Spring Boot:如何根据枚举自定义值完成反序列化?
问题描述
我定义了如下枚举类:
public enum BusinessType { C_CORP("C-Corporation"), S_CORP("S-Corporation"), // 更多类型 public final String name; BusinessType(String name) { this.name = name; } }
前端提交的是枚举的name属性字符串(比如C-Corporation),但Spring Boot会尝试用这个字符串查找枚举常量,抛出错误:
No enum constant ai.interval.common.model.enums.BusinessType.C-Corporation
我的接收视图包含如下属性方法:
BusinessType getBusinessType();
请问如何让Spring Boot根据提交的值正确反序列化并匹配对应的枚举?
解决方案
方法一:自定义Spring Converter(适配URL参数/表单提交)
创建一个实现Converter<String, BusinessType>的类,手动实现字符串到枚举的转换逻辑,Spring会自动识别并使用这个转换器处理参数绑定:
import org.springframework.core.convert.converter.Converter; import org.springframework.stereotype.Component; @Component public class BusinessTypeConverter implements Converter<String, BusinessType> { @Override public BusinessType convert(String source) { for (BusinessType type : BusinessType.values()) { if (type.name.equals(source)) { return type; } } throw new IllegalArgumentException("无效的商业类型: " + source); } }
方法二:Jackson自定义反序列化器(适配JSON请求体)
如果前端通过JSON请求体提交数据,需要自定义Jackson的反序列化器:
- 编写反序列化器类:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; public class BusinessTypeDeserializer extends JsonDeserializer<BusinessType> { @Override public BusinessType deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String value = p.getText(); for (BusinessType type : BusinessType.values()) { if (type.name.equals(value)) { return type; } } throw new IllegalArgumentException("无效的商业类型: " + value); } }
- 在枚举类上添加注解指定该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = BusinessTypeDeserializer.class) public enum BusinessType { C_CORP("C-Corporation"), S_CORP("S-Corporation"), // 更多类型 public final String name; BusinessType(String name) { this.name = name; } }
方法三:枚举内添加静态查找方法(通用兼容)
在枚举类中新增一个静态方法,用来根据传入的字符串匹配枚举实例,结合@JsonCreator注解可以同时适配JSON和参数绑定场景:
import com.fasterxml.jackson.annotation.JsonCreator; public enum BusinessType { C_CORP("C-Corporation"), S_CORP("S-Corporation"), // 更多类型 public final String name; BusinessType(String name) { this.name = name; } @JsonCreator public static BusinessType fromName(String name) { for (BusinessType type : BusinessType.values()) { if (type.name.equals(name)) { return type; } } throw new IllegalArgumentException("无效的商业类型: " + name); } }
- 对于JSON请求,
@JsonCreator会让Jackson自动调用这个静态方法完成反序列化。 - 对于URL/表单参数,也可以在自定义Converter里直接调用
BusinessType.fromName(source)来完成转换。
内容的提问来源于stack exchange,提问作者Mankind1023
相关产品推荐
相关产品推荐

