解决一个JSON反序列化问题的办法(空字符串变为空集合)
作者:小万是个程序员
1.问题场景
当我后端实体中定义如下:
private List<String> projectTypeId;
如果前端传projectTypeId 是 null 或者 [] 都是没问题的。当前端传"" 则会报错。 报错如下:
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot coerce empty String ("") to element of `java.util.ArrayList<java.lang.String>` (but could if coercion was enabled using `CoercionConfig`)
at [Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 8, column: 22] (through reference chain: com.safesoft.web.landProject.vo.LandProjectQueryVO["projectTypeId"])
意思是无法将空字符串强转为集合
2.解决办法(前端)
前端把“” 变为null或者[]即可
(但是我所在这个项目,原先定义的是 private String projectTypeId; 前端传"" 也没毛病,但是后期更改需求,需要变成集合。但是前端每个人写的语法不一样,上个前端人员如果是null则传的"" 。因此造成这个bug)
3.解决办法(后端)
3.1 编写一个自定义 JSON 反序列化器 EmptyStringListDeserializer
package com.safesoft.common.config; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 自定义 JSON 反序列化器,用于处理空字符串在 List 中的情况。 * 该反序列化器设计用于与 Java 类中的 `@JsonDeserialize` 注解一起使用,该注解放在 List<String> 字段上。 * @author Kevin.Wan * @date 2023/12/15 **/ public class EmptyStringListDeserializer extends JsonDeserializer<List<String>> { /** * 反序列化 JSON 数组,处理空字符串并将其转换为空列表。 * * @param p JSON 解析器。 * @param ctxt 反序列化上下文。 * @return 包含反序列化字符串的 List<String>。 * @throws IOException 如果在反序列化过程中发生 I/O 错误。 */ @Override public List<String> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 读取整个 JSON 节点 JsonNode node = p.readValueAsTree(); // 检查节点是否为 null、缺失或不是数组 if (node == null || node.isNull() || node.isMissingNode() || !node.isArray()) { // 对于 null、缺失或非数组情况,返回空列表 return new ArrayList<>(); } else { // 处理数组中的每个元素 List<String> values = new ArrayList<>(); for (JsonNode element : node) { // 检查元素是否为文本节点 if (element.isTextual()) { // 将文本值添加到列表中 values.add(element.textValue()); } } // 返回反序列化字符串的列表 return values; } } }
3.2 然后在可能存在空字符串转换集合的实体上 添加注解
/** * 项目类型id */ @JsonDeserialize(using = EmptyStringListDeserializer.class) private List<String> projectTypeId;
@JsonDeserialize
是在反序列化时,所以就是对参数进行封装,故到的是 setXxxx() 方法,所以需要将注解添加到对应的 set 方法上,若使用了 Lombok 需要自己定义相应的 set 方法。
需要使用 using 属性指定处理参数的类,该类需要继承 JsonDeserializer 类,并重写 deserialize()。
自己见解:
@JsonDeserialize是String提供的反序列化注解,其中 using可以自定义一个反序列化,EmptyStringListDeserializer则是我们自定义处理空字符串转换为空集合的反序列化器
总结
到此这篇关于解决一个JSON反序列化问题的文章就介绍到这了,更多相关JSON反序列化问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!