You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 01:56:15