[英]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 实际上提供了一种尚未提及的新机制:对属性使用@JsonSetter
对String.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.