我知道这样不对,但是虚度年华好过瘾啊!
代码放在https://gitee.com/siumu/blog_code.git
问题复现
Springboot使用Jackson来序列化数据,但是它默认返回的空值都是null,不管是String、Object、List、Map
都是返回一个null,这样就有些不太友好了。
举个例子来说,我们先定义一个类,写一个接口让它返回空值
@Data
@Accessors(chain = true)
public class NullValue {
private String strNull;
private List<String> listNull;
private Map<String,Object> mapNull;
private Double doubleNull;
private User user;
}
我们想让它返回下面这样的值
{
"strNull": "",
"listNull": [],
"mapNull": {},
"doubleNull": null,
"user": {}
}
但是Jackson默认只会序列化成这样的:
{
"strNull": null,
"listNull": null,
"mapNull": null,
"doubleNull": null,
"user": null
}
解决办法
我们知道,Jackson序列化主要靠ObjectMapper
类来给对象序列化,这个类里面就有一个专门处理空值的对象,我们只需要把它替换成我们自己的就可以。所以我们就先创建一个序列化空值的类:
/**
* 空值序列化
*/
public class NullValueSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
String fieldName = gen.getOutputContext().getCurrentName();
//反射获取字段
Field field = ReflectUtil.getField(gen.getCurrentValue().getClass(), fieldName);
if (ObjectUtil.isNotNull(field)){
// 数字类型Integer、Double、Long等返回null
if (Number.class.isAssignableFrom(field.getType())){
gen.writeNull();
return;
}
//String类型返回""
if (Objects.equals(field.getType(), String.class)) {
gen.writeString("");
return;
}
//List类型返回[]
if (Objects.equals(field.getType(), List.class)) {
gen.writeStartArray();
gen.writeEndArray();
return;
}
//其他Object默认返回{}
gen.writeStartObject();
gen.writeEndObject();
}
}
}
然后我们在配置类里将ObjectMapper创建出来,并替换原本的空值处理对象
@Bean
@Primary
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.getSerializerProvider().setNullValueSerializer(new NullValueSerializer());
return objectMapper;
}
这样一来,它就能按照我们的想法来序列化空值了。
代码放在https://gitee.com/siumu/blog_code.git