Чего я пытаюсь достичь:
для десериализации пустых значений в пустые списки
Примечание : я не могу изменить / аннотировать объекты, потому что они происходят из банки.
У меня есть следующий код:
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
public class MyJsonMapperList extends ObjectMapper{
private static final MyJsonMapperList jsonMapper = new MyJsonMapperList();
public MyJsonMapperList() {
SimpleModule sm = new SimpleModule();
sm.addDeserializer(List.class, new NullToEmptyListDeserializer());
super.registerModule(sm);
// setSerializationInclusion(JsonInclude.Include.NON_NULL);
// disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
private static class NullToEmptyListDeserializer extends JsonDeserializer<List> {
@Override
public List deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forContentNulls(Nulls.AS_EMPTY));
mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY, Nulls.AS_EMPTY));
return mapper.readValue(jsonParser, new TypeReference<List>(){});
}
@Override
public List getNullValue(DeserializationContext ctx) {
return Collections.emptyList();
}
}
public static <T> T fromJson(String json, Class<T> tClass) throws IOException {
if (json == null) { return null; }
return jsonMapper.readerFor(tClass).readValue(json);
}
public static String toJson(Object bean) throws JsonProcessingException {
if (bean == null) { return null; }
return jsonMapper.writer().writeValueAsString(bean);
}
Источник для этого кода от здесь .
Правильно ли я что-то истолковал из кода Kotlin, предоставленного shyiko ?
* Примечание. Я также пытался напрямую использовать setDeserializerModifier , например:
public MyJsonMapperList () {
SimpleModule sm = new SimpleModule();
// sm.addDeserializer(CollectionType.class, new NullToEmptyListDeserializer ());
sm.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyCollectionDeserializer(DeserializationConfig config, CollectionType type, BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
deserializer = new JsonDeserializer<List<?>>() {
@Override
public List<?> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(jsonParser, new TypeReference<List>(){});
}
@Override
public List getNullValue(DeserializationContext ctx) {
return Collections.emptyList();
}
};
return deserializer;
}
});
super.registerModule(sm);
// setSerializationInclusion(JsonInclude.Include.NON_NULL);
// disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
}
Ошибка, которую я получаю:
java.lang.IllegalArgumentException: Cannot handle managed/back reference 'defaultReference': type: value deserializer of type MyJsonMapperList$NullToEmptyListDeserializer does not support them
at com.fasterxml.jackson.databind.JsonDeserializer.findBackReference(JsonDeserializer.java:365)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase._resolveManagedReferenceProperty(BeanDeserializerBase.java:764)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:474)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:293)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:477)
at com.fasterxml.jackson.databind.ObjectReader._prefetchRootDeserializer(ObjectReader.java:1935)
at com.fasterxml.jackson.databind.ObjectReader.<init>(ObjectReader.java:189)
at com.fasterxml.jackson.databind.ObjectMapper._newReader(ObjectMapper.java:658)
at com.fasterxml.jackson.databind.ObjectMapper.readerFor(ObjectMapper.java:3517)
at ...MyJsonMapperList.fromJson(MyJsonMapperList.java:47)
У сущностей нет аннотаций @JsonManagedReference и @JsonBackReference (даже если они были, они не могли их изменить)
Зависимость Джексона:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
Что мне не хватает?
Есть ли другие возможности, которые я пропустил?
Этот ответ звучит многообещающе, но у вас нет доступа к objectMapperBuilder из-за защищенного доступа.