空值的 Spring Boot JSON 序列化
Posted
技术标签:
【中文标题】空值的 Spring Boot JSON 序列化【英文标题】:Spring Boot JSON Serialization of Nulls 【发布时间】:2018-09-15 11:42:07 【问题描述】:如何在 Spring Boot 的默认 JSON 响应中强制将 null 对象序列化为空字符串?
我希望它显示为:
myProperty: "",
但是默认出来的是:
myProperty: null,
我不希望 myProperty 被排除在此列表之外,因此我对更改 JsonInclude.Include.NON_NULL
不感兴趣
这是我尝试过的:
在我的主要WebMvcConfigurerAdapter
类中:
@Autowired
private NullAsEmptyStringSerializer nullSerializer;
@Bean
public Jackson2ObjectMapperBuilderCustomizer addCustomSerialization()
return jacksonObjectMapperBuilder ->
DefaultSerializerProvider serializerProvider = new DefaultSerializerProvider.Impl();
serializerProvider.setNullValueSerializer(nullSerializer);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializerProvider(serializerProvider);
jacksonObjectMapperBuilder.configure(objectMapper);
;
然后是我的nullSerializer
对象类:
@Component
public class NullAsEmptyStringSerializer extends JsonSerializer<Object>
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
jsonGenerator.writeString("\"\"");
问题是我的自定义类上从未调用过serialize()
方法。
【问题讨论】:
myProperty:
不是有效的 JSON;你不可能强迫杰克逊产生无效的 JSON。您必须将输出作为字符串进行后处理。考虑创建无效的 JSON 是否是正确的方法。
@Bohemian 编辑让您开心。 :-)
【参考方案1】:
通过Jackson2ObjectMapperBuilderCustomizer
这个配置的问题在于以下几行:
ObjectMapper objectMapper = new ObjectMapper();
jacksonObjectMapperBuilder.configure(objectMapper);
事实上,这没有任何效果,因为构建器总是使用自己的 ObjectMapper
实例,在内部创建。如果我们检查构建器的源代码:
public <T extends ObjectMapper> T build()
ObjectMapper mapper;
// conditional instantiation of mapper
configure(mapper);
return (T) mapper;
我们之前的ObjectMapper
实例被忽略了。
很遗憾,无法通过Jackson2ObjectMapperBuilder
设置SerializerProvider
s。 API 中可能尚未实现此功能。
但是对于这个问题,至少有两种可能的解决方案。
首先,根据official Spring docs,您始终可以创建自己的ObjectMapper
bean,并标记为@Primary
,并按照您的意愿进行完全配置,例如:
@Bean
@Primary
public ObjectMapper objectMapper()
DefaultSerializerProvider serializerProvider = new DefaultSerializerProvider.Impl();
serializerProvider.setNullValueSerializer(nullSerializer);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setSerializerProvider(serializerProvider);
return objectMapper;
这将正确启用nullSerializer
,但缺点是Spring 对ObjectMapper
实例的自动配置将丢失,这可能不是您一直想要的。
第二种解决方案通过引导ObjectMapper
的默认实例并在其上设置所需的属性。这可以通过实现InitializingBean
接口以非常简单的方式实现:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ObjectMapperConfig implements InitializingBean
@Autowired
private NullAsEmptyStringSerializer nullSerializer;
@Autowired
private ObjectMapper objectMapper;
// will be called by Spring after all the beans are created
// and the proper `objectMapper` instance is available here.
@Override
public void afterPropertiesSet() throws Exception
DefaultSerializerProvider serializerProvider = new DefaultSerializerProvider.Impl();
serializerProvider.setNullValueSerializer(nullSerializer);
objectMapper.setSerializerProvider(serializerProvider);
最后一点,上面的NullAsEmptyStringSerializer
有个小问题。
jsonGenerator.writeString("\"\"");
将输出"myProperty":"\"\""
。这应该改为
jsonGenerator.writeString("");
【讨论】:
以上是关于空值的 Spring Boot JSON 序列化的主要内容,如果未能解决你的问题,请参考以下文章
Newtonsoft.Json高级用法 1.忽略某些属性 2.默认值的处理 3.空值的处理 4.支持非公共成员 5.日期处理 6.自定义序列化的
使用 Spring boot 解析具有无效键值的 JSON 对象