自定义全局序列化(jackson),返回值为空,字段消失不见了
自定义全局序列化(jackson),返回值为空,字段消失不见了
基于Spring或SpringBoot框架
- 在后端返回给前端json数据时,会出现字段对应的值为null,返回数据以后该字段也不存在了,在对框架不了解的情况下,初学者不是很好去定位问题出现在那里,下面我就解释一下为什么出现这种情况
Demo
VO:这边定义了不同的类型,以对应不同的类型去进行序列化设置
public class RespVO {
private String str;
private Integer num;
private Long longNun;
private List list;
}
请求返回值,可以查看到当字段为null时也会正常返回字段,如果字段类型为List则会返回空数组
{
"success": true,
"code": 200,
"message": "成功",
"data": {
"str": "",
"num": 1,
"longNun": "",
"list": []
}
}
这都是因为全局序列化设置导致,下面就贴出配置的代码,可以自行根据实际需求进行修改,以达到需求的目的
配置
ps:此处使用的时 jackson序列化
如果是已经上线的项目,谨慎修改全局序列化
@Configuration
public class R3WebMvcConfig {
private final static Logger logger = LoggerFactory.getLogger(R3WebMvcConfig.class);
/**
* 自定义全局 http请求序列化方式
* @return
*/
@Bean
public HttpMessageConverters httpMessageConverters() {
MappingJackson2HttpMessageConverter httpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = httpMessageConverter.getObjectMapper();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
SimpleModule simpleModule = new SimpleModule();
//序列化日期格式
simpleModule.addSerializer(Date.class, new DateSerializer(false, simpleDateFormat));
//Long序列化为String
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
//字符串转String
simpleModule.addDeserializer(Date.class, new JsonDeserializer<Date>() {
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String date = jsonParser.getText();
try {
return simpleDateFormat.parse(date);
} catch (ParseException e) {
logger.error("自定义全局序列化String2Date异常:{}",e.getMessage());
throw new RuntimeException(e);
}
}
});
//反序列化日期格式
objectMapper.registerModule(simpleModule);
//序列化多余字段不报错
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
//序列化地区
objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
//如果值为null时字段key还是否输出:ALWAYS(总是输出),NON_NULL(为null的不输出)
objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator gen, SerializerProvider serializerProvider) throws IOException {
String fieldName = gen.getOutputContext().getCurrentName();
try {
//反射获取字段类型
Field field = gen.getCurrentValue().getClass().getDeclaredField(fieldName);
if (Objects.equals(field.getType(), String.class)) {
//字符串型空值""
gen.writeString("");
return;
} else if (Objects.equals(field.getType(), List.class)) {
//列表型空值返回[]
gen.writeStartArray();
gen.writeEndArray();
return;
} else if (Objects.equals(field.getType(), Map.class)) {
//map型空值返回{}
gen.writeStartObject();
gen.writeEndObject();
return;
}
} catch (NoSuchFieldException e) {
}
//默认返回""
gen.writeString("");
}
});
return new HttpMessageConverters(httpMessageConverter);
}
}
基本原理就是这样,代码注释已经很详细,如有不理解或需求帮助请留言。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix