启用将空对象的Jackson反序列化为空 [英] Enable Jackson Deserialization of Empty Objects to Null

查看:713
本文介绍了启用将空对象的Jackson反序列化为空的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I was asked to change our jackson mapping configuration so that each empty object we deserialize (from JSON) is going to be deserialized as null.

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

The problem is that I'm struggling to do it, but without any luck. Here is a sample of our ObjectMapper configuration (and example):

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;

我考虑过添加以下内容:

I thought about something like adding:

mapper.configure(
    DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);

但它仅适用于字符串。

我恐怕使用a自定义反序列化器对我没有帮助,因为我正在编写一个通用的(对于所有对象)映射器。因此,我可能需要委托人或后期处理反序列化方法。

I'm afraid that using a custom deserializer will not help me, because I'm writing a generic (for all objects) mapper. So I probably need something like a delegator or a post process deserialization method.

因此对于 {} 我希望在Java中转换为 null (而不是空字符串或 Object 实例)。

So for json like "" or {} I expect to be converted to null in java (and not to empty string or Object instance).

推荐答案

什么是空对象?具有空值字段的对象?没有字段的对象?您可以创建一个自定义来检查节点并反序列化所需的方式。我认为以通用方式使用它没有问题。

What is a empty object for you? A object with null value fields? A object with no fields? You can create a custom to check the nodes and deserialize how you want. I see no problem to use it in a generic way.

我做了一个小例子:

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> {

    private final ObjectMapper defaultMapper;

    public DeserializerExample(Class<T> clazz) {
        super(clazz);
        defaultMapper = new ObjectMapper();
    }

    @Override
    public T deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
        System.out.println("Deserializing...");

        JsonNode node = jp.getCodec().readTree(jp);

        for (JsonNode jsonNode : node) {
            if (!jsonNode.isNull()) {
                return defaultMapper.treeToValue(node, (Class<T>) getValueClass());
            }
        }

        return null;
    }

    public static void main(String[] args) throws IOException {

        ObjectMapper mapper = new ObjectMapper();
        SimpleModule module = new SimpleModule();
        module.addDeserializer(Person.class, new DeserializerExample(Person.class));
        mapper.registerModule(module);

        Person person = mapper.readValue("{\"id\":1, \"name\":\"Joseph\"}", Person.class);

        Person nullPerson = mapper.readValue("{\"id\":null, \"name\":null}", Person.class);

        System.out.println("Is null: " + Objects.isNull(person));
        System.out.println("Is null: " + Objects.isNull(nullPerson));
    }

}

这篇关于启用将空对象的Jackson反序列化为空的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆