如何强制JAXB为无maxOccurs的元素生成List类型字段?
问题描述
我在WSDL中定义了两个复杂类型,二者仅在maxOccurs="unbounded"配置上存在差异:
<xs:complexType name="TypeGetPaymentDetailsAdditionRequest"> <xs:sequence> <xs:element name="PaymentDetails" type="tns:TypeGetPaymentDetailAdditionRequest"/> </xs:sequence> </xs:complexType> <xs:complexType name="TypeGetPaymentDetailsRequest"> <xs:sequence> <xs:element name="PaymentDetails" type="tns:TypeGetPaymentDetailRequest" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType>
但通过JAXB(版本com.sun.xml.bind:jaxb-xjc:2.1.7)生成的Java类结构不符合预期:
- 带
maxOccurs="unbounded"的TypeGetPaymentDetailsRequest生成了List<>类型字段:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType( name = "TypeGetPaymentDetailsRequest", propOrder = {"paymentDetails"} ) public class TypeGetPaymentDetailsRequest { @XmlElement( name = "PaymentDetails", required = true ) protected List<TypeGetPaymentDetailRequest> paymentDetails; public TypeGetPaymentDetailsRequest() { } public List<TypeGetPaymentDetailRequest> getPaymentDetails() { if (this.paymentDetails == null) { this.paymentDetails = new ArrayList(); } return this.paymentDetails; } }
- 不带
maxOccurs="unbounded"的TypeGetPaymentDetailsAdditionRequest生成了单个对象字段:
@XmlAccessorType(XmlAccessType.FIELD) @XmlType( name = "TypeGetPaymentDetailsAdditionRequest", propOrder = {"paymentDetails"} ) public class TypeGetPaymentDetailsAdditionRequest { @XmlElement( name = "PaymentDetails", required = true ) protected TypeGetPaymentDetailAdditionRequest paymentDetails; public TypeGetPaymentDetailsAdditionRequest() { } public TypeGetPaymentDetailAdditionRequest getPaymentDetails() { return this.paymentDetails; } public void setPaymentDetails(TypeGetPaymentDetailAdditionRequest value) { this.paymentDetails = value; } }
我需要强制让TypeGetPaymentDetailsAdditionRequest类中的paymentDetails字段也生成为List<>类型,该怎么做?
解决方法
针对JAXB 2.1.7版本,有两种可行方案:
方案一:修改WSDL/XSD定义
直接在目标元素上显式添加maxOccurs="unbounded",若需要确保至少有一个元素,可同时保留minOccurs="1":
<xs:complexType name="TypeGetPaymentDetailsAdditionRequest"> <xs:sequence> <xs:element name="PaymentDetails" type="tns:TypeGetPaymentDetailAdditionRequest" maxOccurs="unbounded" minOccurs="1"/> </xs:sequence> </xs:complexType>
这是最直接的方式,符合XML Schema语义,JAXB会自动生成List<>类型字段。
方案二:使用JAXB绑定自定义文件
如果无法修改原始WSDL/XSD,可创建绑定文件(如jaxb-bindings.xml),通过自定义规则强制生成集合类型:
<jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" xmlns:xs="http://www.w3.org/2001/XMLSchema" jaxb:version="2.1"> <jaxb:bindings schemaLocation="your-service.wsdl" node="/xs:schema"> <jaxb:bindings node="//xs:complexType[@name='TypeGetPaymentDetailsAdditionRequest']//xs:element[@name='PaymentDetails']"> <jaxb:property> <jaxb:baseType name="java.util.List"/> </jaxb:property> </jaxb:bindings> </jaxb:bindings> </jaxb:bindings>
调用xjc工具时指定该绑定文件:
xjc -b jaxb-bindings.xml your-service.wsdl
或在Maven等构建工具中配置绑定文件路径,确保生成代码时应用规则。注意需保证节点路径与目标元素完全匹配。
内容的提问来源于stack exchange,提问作者Eljah
相关产品推荐
相关产品推荐

