简体   繁体   English

Jackson:将 null 字符串反序列化为空字符串

[英]Jackson: deserializing null Strings as empty Strings

I have the following class, that is mapped by Jackson (simplified version):我有以下 class,由 Jackson(简化版)映射:

public class POI {
    @JsonProperty("name")
    private String name;
}

In some cases the server returns "name": null and I would like to then set name to empty Java String.在某些情况下,服务器返回"name": null ,然后我想将名称设置为空 Java 字符串。

Is there any Jackson annotation or should I just check for the null inside my getter and return empty string if the property is null ?是否有任何 Jackson 注释或者我应该只检查我的 getter 中的 null 并返回空字符串,如果属性是null

Again, this answer is for the SO users who happen to stumble upon this thread.同样,此答案适用于偶然发现此线程的SO 用户

While the accepted answer stands accepted and valid in all its sense - it did not help me in the case where the decision to set null string values to empty string came only after we made our services available to iOS clients.虽然接受的答案在所有意义上都被接受和有效 - 在我们将服务提供给iOS客户端之后才决定将null字符串值设置为empty字符串的情况下,它对我没有帮助。

So, around 30-40 pojo's(increasing) and initializing them while instantiating the object in question or at the point of declaration was too much.因此,大约 30-40 个 pojo(增加)并在实例化有问题的对象时或在声明点初始化它们太多了。

Here's how we did it.这是我们如何做到的。

public class CustomSerializerProvider extends DefaultSerializerProvider {

    public CustomSerializerProvider() {
        super();
    }

    public CustomSerializerProvider(CustomSerializerProvider provider, SerializationConfig config,
            SerializerFactory jsf) {
        super(provider, config, jsf);
    }

    @Override
    public CustomSerializerProvider createInstance(SerializationConfig config, SerializerFactory jsf) {
        return new CustomSerializerProvider(this, config, jsf);
    }

    @Override
    public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException {
        if (property.getType().getRawClass().equals(String.class))
            return Serializers.EMPTY_STRING_SERIALIZER_INSTANCE;
        else
            return super.findNullValueSerializer(property);
    }
}

And, the serializer而且,序列化器

public class Serializers extends JsonSerializer<Object> {
    public static final JsonSerializer<Object> EMPTY_STRING_SERIALIZER_INSTANCE = new EmptyStringSerializer();

    public Serializers() {}

    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException, JsonProcessingException {
        jsonGenerator.writeString("");
    }

    private static class EmptyStringSerializer extends JsonSerializer<Object> {
        public EmptyStringSerializer() {}

        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
                throws IOException, JsonProcessingException {
            jsonGenerator.writeString("");
        }
    }
}

And, then set the serializer in the ObjectMapper.然后,在 ObjectMapper 中设置序列化器。 ( Jackson 2.7.4 ) 杰克逊 2.7.4

ObjectMapper nullMapper = new ObjectMapper();
nullMapper.setSerializerProvider(new CustomSerializerProvider());

Hoping, this will save someone some time.希望,这会节省一些时间。

Jackson 2.9 actually offers a new mechanism not yet mentioned: use of @JsonSetter for properties, and its equivalent "Config Overrides" for types like String.class . Jackson 2.9 实际上提供了一种尚未提及的新机制:对属性使用@JsonSetterString.class类型使用等效的“配置覆盖”。 Longer explanation included in更长的解释包含在

https://medium.com/@cowtowncoder/jackson-2-9-features-b2a19029e9ff https://medium.com/@cowtowncoder/jackson-2-9-features-b2a19029e9ff

but gist is that you can either mark field (or setter) like so:但要点是您可以像这样标记字段(或设置器):

@JsonSetter(nulls=Nulls.AS_EMPTY) public String stringValue;

or configure mapper to do the same for all String value properties:或配置映射器对所有String值属性执行相同的操作:

mapper.configOverride(String.class)
 .setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));

both of which would convert incoming null into empty value, which for Strings is "".这两者都将进入转换null为空值,这对于字符串是“”。

This also works for Collection s and Map s as expected.这也按预期适用于Collection s 和Map s。

A simple solution using no Jackson specialities: Write a Getter for name which returns an empty String instead of null as Jackson uses those to serialize.一个不使用 Jackson 专长的简单解决方案:为 name 编写一个 Getter,它返回一个空字符串而不是 null,因为 Jackson 使用它们进行序列化。

public String getName() {
  return name != null ? name : "";
}

Another way would be to write a custom deserializer.另一种方法是编写自定义解串器。 Look here: http://wiki.fasterxml.com/JacksonHowToCustomSerializers看这里: http : //wiki.fasterxml.com/JacksonHowToCustomSerializers

You can either set it in the default constructor, or on declaration:您可以在默认构造函数中或在声明中设置它:

public class POI {
    @JsonProperty("name")
    private String name; 

    public POI() {
        name = "";
    }
}

OR

public class POI {
    @JsonProperty("name")
    private String name = "";
} 

In case you are looking for a global solution for spring boot, you can configure the ObjectMapper如果您正在寻找 spring 引导的全局解决方案,您可以配置ObjectMapper

@Configuration
public class JacksonConfiguration {

    @Bean
    public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder mapperBuilder) {
        DefaultSerializerProvider sp = new DefaultSerializerProvider.Impl();
        sp.setNullValueSerializer(new JsonSerializer<Object>() {
            public void serialize(Object value, JsonGenerator jgen,
                                  SerializerProvider provider)
                    throws IOException, JsonProcessingException
            {
                jgen.writeString("");
            }
        });
        ObjectMapper mapper = mapperBuilder.build();
        mapper.setSerializerProvider(sp);
        return mapper;
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM