Spring中@RequestBody字符串转对象时Enum列表反序列化异常如何解决
解决方案
Spring 默认使用 Jackson 处理 @RequestBody 的 JSON 反序列化,你可以通过 Jackson 官方提供的自定义反序列化器能力实现需求,属于标准规范方案,无侵入性。
步骤1:编写自定义反序列化器
实现针对 List<Enum2> 类型的反序列化逻辑,你已有的字符串拆分转枚举逻辑可以直接放到deserialize方法中:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class Enum2ListDeserializer extends StdDeserializer<List<Enum2>> { public Enum2ListDeserializer() { super(List.class); } @Override public List<Enum2> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 读取前端传入的拼接字符串 String missionStr = p.getValueAsString(); List<Enum2> missionList = new ArrayList<>(); // 拆分字符串逐个转Enum2枚举 for (char c : missionStr.toCharArray()) { missionList.add(Enum2.valueOf(String.valueOf(c))); } return missionList; } }
步骤2:绑定反序列化器
推荐使用字段级绑定,仅对Tracks类的missions字段生效,不会影响其他同类型字段,避免全局污染:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class Tracks { private Enum1 name; // 绑定自定义反序列化器 @JsonDeserialize(using = Enum2ListDeserializer.class) private List<Enum2> missions; // 原有构造方法、getters、setters保持不变 }
可选:全局生效配置
如果项目中所有List<Enum2>类型字段都是以拼接字符串形式传入,可以注册全局反序列化器,不需要单独给字段加注解:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class JacksonConfig { @Bean public ObjectMapper customObjectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(List.class, new Enum2ListDeserializer()); objectMapper.registerModule(module); return objectMapper; } }
注意事项
如果需要处理传入字符串包含非枚举有效值的场景,可以在deserialize方法中增加异常捕获逻辑,抛出业务异常后通过全局异常处理器统一返回错误信息即可。
内容的提问来源于stack exchange,提问作者user3083022
相关产品推荐
相关产品推荐

