如何使用JAXB通过Restriction自定义simpleType?注解疑已废弃
实现自定义XML simpleType的解决方案
你提到的@Digits、@Pattern属于Bean Validation(JSR-380)规范,并未被废弃,但要让这些注解映射到XML Schema的simpleType约束,需要结合JAXB扩展或自定义验证逻辑。以下是两种适配你需求的方案:
方案1:Bean Validation注解 + JAXB插件生成Schema
这种方案既能在运行时验证数据,又能生成符合要求的XML Schema定义。
1. 依赖配置
确保项目引入Bean Validation(以Hibernate Validator为例)、JAXB及Schema生成插件:
<!-- Bean Validation --> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>8.0.1.Final</version> </dependency> <!-- JAXB API & 实现 --> <dependency> <groupId>jakarta.xml.bind</groupId> <artifactId>jakarta.xml.bind-api</artifactId> <version>4.0.0</version> </dependency> <dependency> <groupId>org.glassfish.jaxb</groupId> <artifactId>jaxb-runtime</artifactId> <version>4.0.3</version> <scope>runtime</scope> </dependency> <!-- JAXB2注解映射插件 --> <dependency> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-annotate-plugin</artifactId> <version>1.1.0</version> </dependency>
2. Java类定义约束
用Bean Validation注解对应XML Schema的限制规则:
import jakarta.validation.constraints.Digits; import jakarta.validation.constraints.Max; import jakarta.validation.constraints.Min; import jakarta.xml.bind.annotation.XmlType; import java.math.BigDecimal; @XmlType(name = "TypeNote") public class TypeNote { @Min(10) @Max(20) @Digits(integer = 2, fraction = 2) // 整数位2 + 小数位2 = 总位数4,匹配需求 private BigDecimal value; // Getter & Setter public BigDecimal getValue() { return value; } public void setValue(BigDecimal value) { this.value = value; } }
3. 配置Maven插件生成Schema
在pom.xml中配置jaxb2-maven-plugin,让插件将注解转换为XML Schema约束:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <execution> <goals><goal>xjc</goal></goals> </execution> </executions> <configuration> <plugins> <plugin> <groupId>org.jvnet.jaxb2_commons</groupId> <artifactId>jaxb2-annotate-plugin</artifactId> <version>1.1.0</version> <configuration> <annotations> <annotation>jakarta.validation.constraints.Min</annotation> <annotation>jakarta.validation.constraints.Max</annotation> <annotation>jakarta.validation.constraints.Digits</annotation> </annotations> </configuration> </plugin> </plugins> </configuration> </plugin>
运行mvn jaxb2:xjc即可生成包含目标simpleType的XML Schema。
方案2:自定义XmlJavaTypeAdapter实现验证
如果不想依赖Bean Validation,可通过JAXB适配器在XML编/解组时直接验证数据:
1. 编写适配器类
import jakarta.xml.bind.annotation.adapters.XmlAdapter; import java.math.BigDecimal; public class TypeNoteAdapter extends XmlAdapter<BigDecimal, BigDecimal> { private static final BigDecimal MIN = new BigDecimal("10"); private static final BigDecimal MAX = new BigDecimal("20"); private static final int TOTAL_DIGITS = 4; private static final int FRACTION_DIGITS = 2; @Override public BigDecimal unmarshal(BigDecimal value) throws IllegalArgumentException { // 验证范围 if (value.compareTo(MIN) < 0 || value.compareTo(MAX) > 0) { throw new IllegalArgumentException("值必须在10-20之间"); } // 验证位数规则 String numStr = value.stripTrailingZeros().toPlainString(); String[] parts = numStr.split("\\."); int integerLen = parts[0].length(); int fractionLen = parts.length > 1 ? parts[1].length() : 0; if (integerLen + fractionLen > TOTAL_DIGITS || fractionLen > FRACTION_DIGITS) { throw new IllegalArgumentException("总位数不能超过4位,小数位最多2位"); } return value; } @Override public BigDecimal marshal(BigDecimal value) throws IllegalArgumentException { unmarshal(value); // 编组时同样验证 return value; } }
2. 在Java类中使用适配器
import jakarta.xml.bind.annotation.XmlType; import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import java.math.BigDecimal; @XmlType(name = "TypeNote") public class TypeNote { @XmlJavaTypeAdapter(TypeNoteAdapter.class) private BigDecimal value; // Getter & Setter public BigDecimal getValue() { return value; } public void setValue(BigDecimal value) { this.value = value; } }
这样XML数据在编组或解组时会自动触发验证,确保符合你的simpleType规则。
内容的提问来源于stack exchange,提问作者Soufiane-Chajjaoui
相关产品推荐
相关产品推荐

