Можно ли использовать Джексона для десериализации класса значений (final, без сеттеров), который имеет только конструктор all args и Builder? Я не могу использовать JsonDeserialize
и JsonPOJOBuilder
, так как пытаюсь десериализовать модель, определенную в клиентской библиотеке, поэтому я не могу добавлять аннотации. Могу ли я указать застройщику использовать другой способ?
Джексон - десериализация с помощью Builder без аннотации
Ответы (2)
Вы можете попробовать использовать MixIn.
Я создал один образец для вашего варианта использования:
Исходный класс:
final class Sample {
final int id;
Sample(int id) {
this.id = id;
}
}
MixIn (укажите конструктор без аргументов с такими же аргументами):
@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
abstract class SampleMixin {
@JsonCreator
public SampleMixin(@JsonProperty("id") int id) {
}
}
Десерилизация:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Sample.class, SampleMixin.class);
Sample sample = mapper.readValue(json, Sample.class);
@JsonDeserialize(builder = ...)
на MixIn, и это сработало! Таким образом, мне не нужно наносить на карту все поля. Спасибо!
- person gta0004; 24.10.2017
Вы можете. Строитель должен соответствовать определенным требованиям. Например, его методы для полей должны иметь определенный префикс, например, «с» или «набор».
Вот класс DTO и его построитель без каких-либо аннотаций Джексона:
public class DtoBuilderWithFinalFieldsWithoutJackson {
public final String stringValue;
private DtoBuilderWithFinalFieldsWithoutJackson(final String stringValue){
this.stringValue = stringValue;
}
public static Builder builder(){
return new Builder();
}
public static class Builder {
private String stringValue;
public Builder withStringValue(String stringValue) {
this.stringValue = stringValue;
return this;
}
public DtoBuilderWithFinalFieldsWithoutJackson build() {
return new DtoBuilderWithFinalFieldsWithoutJackson(stringValue);
}
}
}
Без каких-либо дополнительных усилий с помощью настраиваемого объекта по умолчанию вы можете сериализовать этот объект dto. Вы несете ответственность за создание экземпляра. Джексону нужен только доступ к полям. В нашем случае это публичное поле.
Если для десериализации используется DTO, вам необходимо настроить собственный объект:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
@Override
public Class<?> findPOJOBuilder(AnnotatedClass ac) {
//set analogue of: @JsonDeserialize(builder = DtoBuilderWithFinalFieldsWithoutJackson.Builder.class)
if (DtoBuilderWithFinalFieldsWithoutJackson.class.equals(ac.getRawType())) {
return DtoBuilderWithFinalFieldsWithoutJackson.Builder.class;
} else {
return super.findPOJOBuilder(ac);
}
}
@Override
public JsonPOJOBuilder.Value findPOJOBuilderConfig(AnnotatedClass ac) {
if (DtoBuilderWithFinalFieldsWithoutJackson.class.equals(ac.getRawType())) {
//both build and with - are default in this case:
//set analogue of @JsonPOJOBuilder(buildMethodName = "build", withPrefix = "with")
return new JsonPOJOBuilder.Value("build", "with");
} else {
return super.findPOJOBuilderConfig(ac);
}
}
});
и используйте этот настроенный CustomObject в своих реализациях. Вот тест и полный пример можно найти здесь: DtoBuilderWithFinalFieldsWithoutJackson test
JsonDeserializer
- person rkosegi   schedule 24.10.2017