一、引言
最近在做项目中遇到一个神奇的问题,在测试返回银行三级数据的时候有的项目中返回的数据中把null值的数据返回了,而有的时候就不存在null值数据,如下所示:
存在null值情况
不含null值情况
但是我们可以看一下返回的VO的数据结果如下:
import lombok.Data;
import java.util.List;
/*
* @description 银行
* @author 罗添煦
* @create 2024-08-30 下午12:38
*/
@Data
public class BankEntity {
private String bankName;
private String bankCode;
private List<BankEntity> children;
}
二、jackson
因为上面的问题出现带着好奇心的我,就去搜索了大量的资料,发现在springboot中默认支持的序列化器是jackson,可能你没有听说过jackson这个序列化器,但是你应该在项目中使用过alibaba的序列化工具fastjson。
1、默认情况下,ObjectMapper 在序列化对象时,将实体所有的字段一 一序列化,无论这些字段是否有值,是否为 null。
2、如果实体的某个字段没有提供 getter 方法,则该字段不会被序列化。
3、Spring Boot Web 组件默认使用 Jackson 进行对象的序列化与反序列化,即页面传入的参数,会自动反序列化为后台对象,后台传给前端的对象,也会序列化后输出。所以需要注意返回给页面的对象默认不能使用 Jackson 以外的 Json 库序列化,比如返回一个 Gson 的 JsonObject 给前端,则会报错,因为显然 Jackson 序列化时会失败。
4、Jackson 提供三种不同的方法来操作 JSON:
1)流式API - 使用 Stream(流) 的方式对 Json 的每一个组成部分进行最细粒度的控制,JsonParser 读取数据,JsonGenerator 写入数据。
2)树模型 - 将 JSON 文件在内存里以树的形式表示,通过 JsonNode 处理单个Json节点,类似于 XML 的 DOM 解析器。(常用)
3)databind 模块 - ObjectMapper 读/写 JSON 是 POJO 序列化与反序列化 Json 最方便的方式。(常用)
但是这个地方我们就不过多的去介绍使用Jackson我们还是来看一下是如何解决响应数据中不含null值这个问题的。
三、配置jackson
处理方法1、返回json中的null字段-不显示
配置文件添加 spring.jackson.default-property-inclusion=non_null 配置
处理方法2、返回json中的null字段-转为空字符串
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.IOException;
/**
* 处理 jackson 返回的null值
* 返回json中的null值转为空字符串
*/
@Configuration
public class JacksonConfig {
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString("");
}
});
return objectMapper;
}
}
但是这种方式只是把返回null的数据返回成为了空字符串,和我们需要的看不到参数还是有差距的。
jackson其他配置,我们可以配置Jackson返回时间的类型。
我们可以看一下springboot默认帮我们配置的时间类型的返回数据是什么格式。
在不指定任何特殊配置的情况下,返回的 date 类型的字段会自动转成 UTC 格式字符串,形如 "2024-09-02T01:51:24.091+00:00"
。
但是我们想要变成yyyy-MM-dd HH:mm:ss这种格式的话我们就可以在字段上添加注解
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
经过配置以后返回数据如下所示: