【问题标题】:Does JAXB support xsd:restriction?JAXB 是否支持 xsd:restriction?
【发布时间】:2026-01-19 19:50:02
【问题描述】:
<xs:element name="age">
  <xs:simpleType>
    <xs:restriction base="xs:integer">
      <xs:minInclusive value="0"/>
      <xs:maxInclusive value="120"/>
    </xs:restriction>
  </xs:simpleType>
</xs:element>

所以我希望它像这样转换为 Java 代码:

public void setAge(int age){
    if(age < 0 || age > 120){
         //throw some exception
    }
     //setting the age as it is a valid value
}

在 JAXB 中可以吗?

见过一些 WebService 客户端存根生成器这样做可能是axis2 webservice,但不确定。

【问题讨论】:

    标签: java web-services jakarta-ee jaxb xsd-validation


    【解决方案1】:

    在 JAXB 中执行此验证的建议方法是在编组器上打开模式验证。解组器:

    SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
    Schema schema = schemaFactory.newSchema(...);
    
    ValidationEventHandler valHandler = new ValidationEventHandler() {
      public boolean handleEvent(ValidationEvent event) {
          ...
      }
    };
    
    marshaller.setSchema(schema);
    marshaller.setEventHandler(valHandler);
    

    【讨论】:

    • 我知道,但如果架构包含 xsd:restriction 则生成的代码不会反映这些约束
    • 好的,在 JAXB 标准和 RI 中没有这样的机制。我猜它们没有被使用,因为并非所有模式约束都可以立即验证(例如“minOccurs=2”)。
    • 但正如我在问题中提到的,已经看到一些轴工具生成利用 xs:restriction 的类。
    • 以前有验证插件,但是很久没激活了。也许 krasa-jaxb-tools 接近您正在寻找的东西。它生成验证注释。我不得不承认我没有将它用于实际项目。
    【解决方案2】:

    JAXB (JSR-222) 规范不包括在域模型中生成快速失败逻辑。现在的一种常见做法是以注释(或 XML)的形式表达验证规则并对其进行验证。 Bean Validation (JSR-303) 对此进行了标准化,可用于任何 Java EE 6 实现。

    XJC 扩展

    我自己没有尝试过以下扩展,但它似乎会在 XML 模式的域模型表示验证规则上生成 Bean Validation (JSR-303) 注释。由于 XJC 具有很强的可扩展性,因此可能还有其他可用的插件。

    【讨论】:

    • 谢谢,还有一件事。 JAXB Facets 有一个 [java.net/jira/browse/JAXB-917]JIRA,这不包含在 JAXB 的 JSR 中。正确的?这是其他标准的某种标准实现吗?
    • @NarendraPathai - 这是我第一次听说 JAXB Facets。这目前不是 JSR 的一部分,并且被提议作为对 JAXB 参考实现的增强。我在 JIRA 问题上发表了评论,询问它与 Bean Validation (JSR-303) 的兼容性。 JSR-303 兼容方法可能会在 JAXB 规范的未来版本中得到支持。
    • 谢谢布莱斯。我关注你的博客,很想听听 JAXB 中的一些实现。
    • @BlaiseDoughan - 这是什么状态?
    【解决方案3】:

    你可以试试JAXB-Facets。快速sn-p:

    class MyClass {
    
        @MinOccurs(1) @MaxOccurs(10)
        @Facets(minInclusive=-100, maxInclusive=100)
        public List<Integer> value;
    
        @Facets(pattern="[a-z][a-z0-9]{0,4}")
        public String name;
    
    }
    

    【讨论】: