启用 Jackson 将空对象反序列化为 Null

我被要求更改我们的 jackson 映射配置,以便我们反序列化(来自 JSON)的每个空对象都将被反序列化为 null。


问题是我正在努力去做,但没有任何运气。这是我们的配置示例ObjectMapper(和示例):


ObjectMapper mapper = new ObjectMapper();

mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, true);

mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

JavaTimeModule javaTimeModule = new JavaTimeModule();

javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));

javaTimeModule.addDeserializer(Instant.class, InstantDeserializer.INSTANT);

mapper.registerModule(javaTimeModule);

mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

warmupMapper(mapper);


return mapper;

我想过要添加:


mapper.configure(

    DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);

但它只适用于字符串。


恐怕使用自定义解串器对我没有帮助,因为我正在编写一个通用(针对所有对象)映射器。所以我可能需要像委托人或后处理反序列化方法这样的东西。


所以对于 json 之类的""或者{}我希望在 java 中转换为null(而不是空字符串或Object实例)。


大话西游666
浏览 497回答 4
4回答

素胚勾勒不出你

什么是你的空对象?具有空值字段的对象?没有字段的对象?您可以创建一个自定义来检查节点并反序列化您想要的方式。我认为以通用方式使用它没有问题。我做了一个小例子:import com.fasterxml.jackson.core.JsonParser;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.DeserializationContext;import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.ObjectMapper;import com.fasterxml.jackson.databind.deser.std.StdDeserializer;import com.fasterxml.jackson.databind.module.SimpleModule;import java.io.IOException;import java.util.Objects;public class DeserializerExample<T> extends StdDeserializer<T> {&nbsp; &nbsp; private final ObjectMapper defaultMapper;&nbsp; &nbsp; public DeserializerExample(Class<T> clazz) {&nbsp; &nbsp; &nbsp; &nbsp; super(clazz);&nbsp; &nbsp; &nbsp; &nbsp; defaultMapper = new ObjectMapper();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public T deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Deserializing...");&nbsp; &nbsp; &nbsp; &nbsp; JsonNode node = jp.getCodec().readTree(jp);&nbsp; &nbsp; &nbsp; &nbsp; for (JsonNode jsonNode : node) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!jsonNode.isNull()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return defaultMapper.treeToValue(node, (Class<T>) getValueClass());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp; }&nbsp; &nbsp; public static void main(String[] args) throws IOException {&nbsp; &nbsp; &nbsp; &nbsp; ObjectMapper mapper = new ObjectMapper();&nbsp; &nbsp; &nbsp; &nbsp; SimpleModule module = new SimpleModule();&nbsp; &nbsp; &nbsp; &nbsp; module.addDeserializer(Person.class, new DeserializerExample(Person.class));&nbsp; &nbsp; &nbsp; &nbsp; mapper.registerModule(module);&nbsp; &nbsp; &nbsp; &nbsp; Person person = mapper.readValue("{\"id\":1, \"name\":\"Joseph\"}", Person.class);&nbsp; &nbsp; &nbsp; &nbsp; Person nullPerson = mapper.readValue("{\"id\":null, \"name\":null}", Person.class);&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Is null: " + Objects.isNull(person));&nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Is null: " + Objects.isNull(nullPerson));&nbsp; &nbsp; }}

噜噜哒

唯一的方法是使用自定义解串器:class CustomDeserializer extends JsonDeserializer<String> {@Overridepublic String deserialize(JsonParser jsonParser, DeserializationContext context) throws IOException, JsonProcessingException {    JsonNode node = jsonParser.readValueAsTree();    if (node.asText().isEmpty()) {        return null;    }    return node.toString();}}然后做:class EventBean {public Long eventId;public String title;@JsonDeserialize(using = CustomDeserializer.class)public String location;}

一只萌萌小番薯

我有同样的问题。我有一个City班级,有时我会收到'city':{}网络服务请求。因此,标准序列化程序创建一个全空字段的新城市。我以这种方式创建了一个自定义反序列化器public class CityJsonDeSerializer extends StdDeserializer<City> {@Overridepublic City deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; JsonNode node = jp.getCodec().readTree(jp);&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; if(node.isNull() || node.asText().isEmpty()|| node.size()==0)&nbsp; &nbsp; &nbsp; &nbsp; return null;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; City city = new City();&nbsp; &nbsp; ... // set all fields&nbsp; &nbsp; return city;}}if 检查条件:'city' : null'city' : '''city' : '{}'如果为真,反序列化器返回null.

慕斯709654

另一种方法是使用 a com.fasterxml.jackson.databind.util.Converter<IN,OUT>,它本质上是一个用于反序列化的后处理器。假设我们有一个类:public class Person {&nbsp; &nbsp; public String id;&nbsp; &nbsp; public String name;}现在假设我们想要将一个空的 JSON 对象{}反序列化为null, 而不是Person具有和null值的。我们可以创建以下内容:idnameConverterpublic PersonConverter implements Converter<Person,Person> {&nbsp; &nbsp; @Override&nbsp; &nbsp; public Person convert(Person p) {&nbsp; &nbsp; &nbsp; &nbsp; return isEmpty(p) ? null : value;&nbsp; &nbsp; }&nbsp; &nbsp; private static boolean isEmpty(Person p) {&nbsp; &nbsp; &nbsp; &nbsp; if(p == null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if(Optional.ofNullable(p.id).orElse("").isEmpty() &&&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Optional.ofNullable(p.name).orElse("").isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public JavaType getInputType(TypeFactory typeFactory) {&nbsp; &nbsp; &nbsp; &nbsp; return typeFactory.constructType(Person.class);&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public JavaType getOutputType(TypeFactory typeFactory) {&nbsp; &nbsp; &nbsp; &nbsp; return typeFactory.constructType(Person.class);&nbsp; &nbsp; }}请注意,我们必须处理空白String情况,因为这是(违反直觉)分配给 JSON 中未给出的属性的默认值,而不是null.给定转换器,然后我们可以注释我们的原始Person类:@JsonDeserialize(converter=PersonConverter.class)public class Person {&nbsp; &nbsp; public String id;&nbsp; &nbsp; public String name;}这种方法的好处是您根本不必考虑或关心反序列化;您只是在反序列化后决定如何处理反序列化的对象。您还可以使用 a 进行许多其他转换Converter。但这对于使“空”值无效很有效。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java