#jersey #deserialization #converters #genson
Вопрос:
У меня есть иерархия классов, которая чем-то похожа на приведенную ниже, с пользовательской Converter
Это FieldValueConverter#deserialize
НЕ называется по-моему JerseyTest
. Вместо этого он использует преобразователь GensonJsonConverter по умолчанию, который жалуется, что не может найти соответствующий конструктор. ( Caused by: com.owlike.genson.JsonBindingException: No constructor has been found for type class com.searchdata.actions.api.FieldValue
)
Как мне заставить его использоваться?
Регистрация
Конвертер для FieldValue
s (см. Ниже), который я регистрирую в таком джерси Application
, как этот:
Genson genson = new GensonBuilder()
.withBundle(new JAXBBundle())
.withConverter(new FieldValueConverter(), FieldValue.class)
.setSkipNull(true)
.create();
register(new GensonJaxRSFeature().use(genson));
Преобразователь значения поля
public class FieldValueConverter implements Converter<FieldValue> {
private static final Logger LOG = LoggerFactory.getLogger(FieldValueConverter.class);
public void serialize(FieldValue fieldValue, ObjectWriter writer, Context ctx) throws Exception {
LOG.info("Serializing fieldValue:{}", fieldValue);
writer.beginObject();
writer.writeString("type", fieldValue.getType().name())
.writeString("value", fieldValue.getValue().toString())
.writeString("field", fieldValue.getField());
writer.endObject();
LOG.info("..Done!", fieldValue);
}
/* You don't have to worry for the object being null here, if it is null Genson will
handle it for you. */
public FieldValue deserialize(ObjectReader reader, Context ctx) throws Exception {
LOG.info("Deserializing fieldValue...");
reader.beginObject();
String stringValue=null;
FieldType type= FieldType.STRING;
String fieldKey= null;
while (reader.hasNext()) {
reader.next();
if ("type".equals(reader.name())) {
type = FieldType.valueOf(reader.valueAsString());
} else if ("field".equals(reader.name())) {
fieldKey = reader.valueAsString();
} else if ("value".equals(reader.name())) {
stringValue = reader.valueAsString();
} else {
reader.skipValue();
}
}
Предмет
public class Item
{
@Schema(name = "id", description = "The id of an item")
private String id;
@Schema(name = "values", description = "The fields with values for this action")
private List<FieldValue> values;
}
Значение поля
@Schema(name = "FieldValue")
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class FieldValue {
@Schema(name = "field", description = "The technical name of the field")
private String field;
@Schema(name = "type", description = "The type of the field")
private FieldType type;
@Schema(name = "value", description = "The value of a field", oneOf = {Integer.class, String.class, Date.class, Double.class})
private Serializable value;
public FieldValue(final String field, final String string) {
setField(field);
setValue(string);
setType(FieldType.STRING);
}
public FieldValue(final String field, final Long number) {
setField(field);
setValue(number);
setType(FieldType.LONG);
}
Комментарии:
1. Вы проверяли, подбирается ли вообще ваш пользовательский экземпляр Genson? Вот как выполняется интеграция jax-rs/джерси github.com/owlike/genson/tree/master/genson/src/main/java/com/…
2.Привет @eugen, похоже
JerseyTest
, что при использовании метода не удается подобрать экземплярtarget()
Genson. Если яregister
позвонюGensonCustomResolver
послеtarget()
звонка, это сработает. Имеет ли это смысл?