我有一个类,由Jackson映射(简化版本):
public class POI {
@JsonProperty("name")
private String name;
}
在某些情况下,服务器会返回"name": null
,我想将名称设置为空的Java字符串。是否有任何Jackson注释可以使用,或者我应该在getter中检查null并返回空字符串,如果属性是
null
?@JsonSetter
注解来设置属性,以及类型如String.class
的“配置覆盖”等价物。
更长的解释在此:https://medium.com/@cowtowncoder/jackson-2-9-features-b2a19029e9ff
简而言之,您可以像这样标记字段(或setter):@JsonSetter(nulls=Nulls.AS_EMPTY) public String stringValue;
或者配置映射器以对所有String
值属性执行相同的操作:
mapper.configOverride(String.class)
.setSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
两者都会将传入的null
转换为空值,对于字符串而言是 ""。
这同样适用于Collection
和Map
。
@JsonSetter(nulls = Nulls.AS_EMPTY)
对我很有用。在这两种情况下,它都被映射为空字符串。正是我所需要的,谢谢! - AbstractVoidNulls.SKIP
- 可以在字段本身上或通过配置映射器来实现,如此答案所述。 - Yaniv Nahoum@JsonCreator
)的情况,其中必须提供一些值。因此,您是正确的,这是解决限制的一种方法。 - StaxMan再次说明,本回答是为那些偶然发现这个帖子的SO用户准备的。
虽然已接受的答案在所有方面都是被认可和有效的,但它在我这种情况下并没有帮助我,那就是在我们将服务提供给客户端之后才决定将null
字符串值设置为空字符串。
因此,在实例化相关对象时或者在声明时初始化大约30-40个pojo(增加)是太多了。
以下是我们的解决方法。
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);
}
}
而且,序列化程序
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("");
}
}
}
然后在ObjectMapper中设置序列化器。(Jackson 2.7.4)
ObjectMapper nullMapper = new ObjectMapper();
nullMapper.setSerializerProvider(new CustomSerializerProvider());
希望这可以节省其他人的时间。
stackoverflow
-> SO
- Tirath一个不使用Jackson特性的简单解决方案:为名称编写一个Getter方法,该方法返回一个空字符串而不是null,因为Jackson使用null进行序列化。
public String getName() {
return name != null ? name : "";
}
还有一种方法是编写自定义反序列化器。请看这里:http://wiki.fasterxml.com/JacksonHowToCustomSerializers
您可以在默认构造函数中设置它,也可以在声明时设置:
public class POI {
@JsonProperty("name")
private String name;
public POI() {
name = "";
}
}
或者
public class POI {
@JsonProperty("name")
private String name = "";
}
如果您正在寻找一个适用于Spring Boot的全局解决方案,您可以配置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;
}
}