Spring Boot API中能否仅用枚举实现JSON与XML的反序列化(替代同名实体类)
Spring Boot API中能否仅用枚举实现JSON与XML的反序列化(替代同名实体类)
当然可以!完全不用保留那个同名的CustomerType实体类,只需要调整你的枚举类,给它加上适配XML序列化/反序列化的注解,就能同时处理JSON和XML的转换需求,一步到位~
先给你理清楚核心思路:你的JSON场景已经靠枚举自带的@JsonCreator和@JsonValue处理好了,现在只需要给枚举补上JAXB相关的注解,让它能识别XML里的Customer_Type元素和Val属性,就能替代原来的实体类。
具体修改步骤和最终代码
- 保留并增强JSON处理逻辑:原来的
@JsonCreator(把JSON里的Standard/Premium转成枚举)和@JsonValue(序列化时返回对应字符串)已经完美适配JSON场景,直接保留就行,还可以给forValue方法加个equalsIgnoreCase,兼容大小写输入的小问题。 - 添加XML适配注解:给枚举加上JAXB注解,让它能映射XML的
Customer_Type元素和Val属性,还要加一个小适配器来处理属性和枚举的转换(因为默认JAXB会把枚举当元素内容处理,而我们需要读取属性值)。 - 移除冗余的实体类:修改完枚举后,原来的
CustomerType实体类就可以直接删掉了。
最终修改后的枚举代码如下:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonValue; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlAdapter; @XmlRootElement(name = "Customer_Type") @XmlAccessorType(XmlAccessType.FIELD) @XmlEnum public enum CustomerType { @XmlEnumValue("SC") SC("Standard"), @XmlEnumValue("PC") PC("Premium"); // 这里修正了你代码里的笔误「Permium」→「Premium」 private final String customerType; CustomerType(String customerType) { this.customerType = customerType; } // 处理JSON反序列化:把"Standard"/"Premium"转成枚举 @JsonCreator public static CustomerType forValue(String customerType) { for (CustomerType type : values()) { // 加equalsIgnoreCase兼容大小写错误,不需要的话可以去掉 if (type.customerType.equalsIgnoreCase(customerType)) { return type; } } throw new IllegalArgumentException("无效的客户类型: " + customerType); } // 处理JSON序列化:返回"Standard"/"Premium"字符串 @JsonValue @Override public String toString() { return customerType; } // JAXB适配器:专门处理XML的Val属性和枚举的转换 @XmlJavaTypeAdapter(CustomerTypeAdapter.class) public static class CustomerTypeAdapter extends XmlAdapter<String, CustomerType> { // 把XML里的Val属性值(比如"SC")转成枚举 @Override public CustomerType unmarshal(String val) throws Exception { for (CustomerType type : CustomerType.values()) { if (type.name().equals(val)) { return type; } } throw new IllegalArgumentException("无效的Val属性值: " + val); } // 把枚举转成XML的Val属性值(比如SC→"SC") @Override public String marshal(CustomerType type) throws Exception { return type.name(); } } }
额外注意事项
- 如果你的项目是Spring Boot 3+,JAXB已经从JDK中移除了,需要手动添加依赖:
Maven项目在pom.xml里加:
Gradle项目在<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency>build.gradle里加:implementation 'javax.xml.bind:jaxb-api:2.3.1' - Spring Boot默认会自动配置Jackson(JSON)和JAXB(XML)的消息转换器,所以不用额外配置转换器,直接用就行。
内容来源于stack exchange
相关产品推荐
相关产品推荐

