如何建立两个Enum间映射并验证请求中的类型与值合法性
问题场景与解决方案
现有Java枚举定义
类型枚举 DifferentiatorType
public enum DifferentiatorType { @JsonProperty("differentiatorType") MARKETPLACE_ID("MarketplaceId"); private final String value; // 补充原代码缺失的构造方法 DifferentiatorType(String value) { this.value = value; } public String getValue() { return value; } // 根据字符串值匹配枚举实例的工具方法 public static DifferentiatorType fromValue(String value) { for (DifferentiatorType type : DifferentiatorType.values()) { if (type.value.equals(value)) { return type; } } throw new IllegalArgumentException("无效的DifferentiatorType值: " + value); } }
取值枚举 DifferentiatorValue(当前对应MARKETPLACE_ID类型)
public enum DifferentiatorValue { VALUE_ONE("valueOne"), VALUE_TWO("valueTwo"), VALUE_THREE("valueThree"), VALUE_FOUR("valueFour"); private final String value; // 补充原代码缺失的构造方法 DifferentiatorValue(String value) { this.value = value; } public String getValue() { return value; } // 根据字符串值匹配枚举实例的工具方法 public static DifferentiatorValue fromValue(String value) { for (DifferentiatorValue val : DifferentiatorValue.values()) { if (val.value.equals(value)) { return val; } } throw new IllegalArgumentException("无效的DifferentiatorValue值: " + value); } }
业务需求
包含differentiatorType和differentiatorValue字段的请求负载需按以下规则校验:
- 先校验
differentiatorType是否为DifferentiatorType的合法枚举值 - 再校验该类型对应的
differentiatorValue是否匹配专属的合法取值枚举 - 仅校验通过后,才能执行后续业务流程
- 未来新增
DifferentiatorType枚举项时,必须为其创建对应的专属取值枚举
示例请求负载:
{"referenceId":"B01-2776421-8482453","preferenceType":"CREDITCARD","differentiatorValue":"ABXWY75J","customerId":"A37I50ASYHT","differentiatorType":"MarketplaceId"}
映射与校验实现方案
1. 改造类型枚举,关联对应取值枚举
修改DifferentiatorType,添加字段存储对应取值枚举的Class对象,同时内置取值校验方法:
public enum DifferentiatorType { @JsonProperty("differentiatorType") MARKETPLACE_ID("MarketplaceId", DifferentiatorValue.class); private final String value; private final Class<? extends Enum<?>> valueEnumClass; DifferentiatorType(String value, Class<? extends Enum<?>> valueEnumClass) { this.value = value; this.valueEnumClass = valueEnumClass; } public String getValue() { return value; } // 校验当前类型对应的取值是否合法 public boolean isValidValue(String value) { try { // 针对自定义字符串值的枚举,需调用getValue方法对比 if (valueEnumClass.equals(DifferentiatorValue.class)) { return DifferentiatorValue.fromValue(value) != null; } // 针对普通枚举直接匹配名称 Enum.valueOf(valueEnumClass, value); return true; } catch (IllegalArgumentException e) { return false; } } // 根据字符串值获取类型枚举实例 public static DifferentiatorType fromValue(String value) { for (DifferentiatorType type : DifferentiatorType.values()) { if (type.value.equals(value)) { return type; } } throw new IllegalArgumentException("无效的DifferentiatorType值: " + value); } }
2. 新增类型的扩展方式
当需要新增DifferentiatorType枚举项时,只需两步:
- 创建对应专属取值枚举(比如新增
STORE_ID类型,就创建StoreIdValue枚举) - 在
DifferentiatorType中添加枚举项并关联新的取值枚举:
STORE_ID("StoreId", StoreIdValue.class)
3. 请求校验流程示例
在业务处理类中实现完整校验逻辑:
public class RequestValidator { public void validateDifferentiator(String typeStr, String valueStr) { // 1. 校验类型合法性 DifferentiatorType type = DifferentiatorType.fromValue(typeStr); // 2. 校验对应取值合法性 if (!type.isValidValue(valueStr)) { throw new IllegalArgumentException(String.format("类型[%s]对应的取值[%s]不合法", typeStr, valueStr)); } // 校验通过,执行后续业务流程 } }
4. 示例请求校验结果
示例请求中differentiatorType为MarketplaceId,对应的合法取值是DifferentiatorValue枚举中的valueOne/valueTwo等,但请求中的differentiatorValue是ABXWY75J,不在合法列表中,因此校验会抛出IllegalArgumentException。
内容的提问来源于stack exchange,提问作者koushik
相关产品推荐
相关产品推荐

