如何让 JAXB 为非字符串元素生成空标记?
How can I get the JAXB to generate empty tags for non-string elements?
编辑:我重新格式化了问题,希望能使我的意图更清楚。
我正在尝试使用 JAXB 编组器将 java 对象映射到 XML 以创建供应商 SOAP 服务的 soap 请求。
我几乎没有需要在请求中显示的元素,即使它们为空或 null。
我在我的 pom.xml 中使用带有 wsimport
目标的 jaxws-maven-plugin
插件从 WSDL 文件生成源代码。
<plugin>
<groupId>com.helger.maven</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlFiles>
<wsdlFile>${project.basedir}/src/wsdl/sample/SomeSoapService.wsdl</wsdlFile>
</wsdlFiles>
</configuration>
<id>wsimport-generate-cbs</id>
<phase>generate-sources</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>webservices-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<configuration>
<sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir>
<xnocompile>true</xnocompile>
<xadditionalHeaders>true</xadditionalHeaders>
<verbose>true</verbose>
<extension>true</extension>
</configuration>
我从这里[ ] 了解到,对于 xs:string
类型的元素,可以通过设置空字符串 ""
因为它的价值。但是不能对xs:dateTime, xs:boolean, xs:integer
等类型的元素做,会分别产生XMLGregorianCalendar, BigInteger, Boolean
个对象。如果我将它们的值设置为 null,则不会在编组过程中生成元素。就像其他人指出的那样,可以通过将 nillable=true
添加到 @XmlElement
来实现,但这将需要更改为生成的源,它将在下一个构建中被覆盖,除非我在之后从 Maven 中删除插件首次构建。
我目前的解决方法是,我将需要在请求中显示的那些特定元素的类型更改为 WSDL 文件中的 xs:string
,并将空字符串传递给它们相应的 java 对象字段。
我的问题是,是否可以在 WSDL 端进行更改以触发 jaxws:wsimport 在生成的 @XmlElement
字段中添加 nillable=true
?我更喜欢更改 WSDL 文件而不是生成源的原因是
- 我已经对 WSDL 文件进行了一些更改,因此所有更改都可以放在一个地方,更容易记录。
- 我想避免更改生成的源,这样我就可以将它们排除在 Git 存储库之外,并防止在每次构建时被覆盖。
以下是代码的简化版本。
首先,我为 complexType Currency 生成了 java class。
// Generated
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "currency", propOrder = {
"crossCurrency",
"amount"
})
public class Currency {
@XmlElement(required = true)
protected Boolean crossCurrency;
@XmlElement(required = true)
protected BigDecimal amount;
}
我将字段设置为空,因为它们不存在。
requestInputRq.setCurrency(new Currency());
requestInputRa.setOtherField("Some value");
这将生成 但我需要它像下面那样生成。
<typ:Currency>
<typ:crossCurrency/>
<typ:amount/>
</typ:Currency>
将 nillable
属性与 @XmlElement
一起使用并将其值设置为 true
Currency.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "currency", propOrder = {
"isoCurrencyCode",
"amount"
})
public class Currency {
@XmlElement(required = true, nillable=true)
protected Boolean crossCurrency;
@XmlElement(required = true, nillable=true)
protected BigDecimal amount;
}
输出
<typ:Currency>
<typ:crossCurrency xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<typ:amount xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</typ:Currency>
WSDL
在每个请求的元素中添加 nillable
属性并将其值设置为 true
,如下例,
<xsd:element name="Currency" nillable="true" ... />
编辑:我重新格式化了问题,希望能使我的意图更清楚。
我正在尝试使用 JAXB 编组器将 java 对象映射到 XML 以创建供应商 SOAP 服务的 soap 请求。
我几乎没有需要在请求中显示的元素,即使它们为空或 null。
我在我的 pom.xml 中使用带有 wsimport
目标的 jaxws-maven-plugin
插件从 WSDL 文件生成源代码。
<plugin>
<groupId>com.helger.maven</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<wsdlFiles>
<wsdlFile>${project.basedir}/src/wsdl/sample/SomeSoapService.wsdl</wsdlFile>
</wsdlFiles>
</configuration>
<id>wsimport-generate-cbs</id>
<phase>generate-sources</phase>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>javax.xml</groupId>
<artifactId>webservices-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
<configuration>
<sourceDestDir>${project.build.directory}/generated-sources/jaxws-wsimport</sourceDestDir>
<xnocompile>true</xnocompile>
<xadditionalHeaders>true</xadditionalHeaders>
<verbose>true</verbose>
<extension>true</extension>
</configuration>
我从这里[ ] 了解到,对于 xs:string
类型的元素,可以通过设置空字符串 ""
因为它的价值。但是不能对xs:dateTime, xs:boolean, xs:integer
等类型的元素做,会分别产生XMLGregorianCalendar, BigInteger, Boolean
个对象。如果我将它们的值设置为 null,则不会在编组过程中生成元素。就像其他人指出的那样,可以通过将 nillable=true
添加到 @XmlElement
来实现,但这将需要更改为生成的源,它将在下一个构建中被覆盖,除非我在之后从 Maven 中删除插件首次构建。
我目前的解决方法是,我将需要在请求中显示的那些特定元素的类型更改为 WSDL 文件中的 xs:string
,并将空字符串传递给它们相应的 java 对象字段。
我的问题是,是否可以在 WSDL 端进行更改以触发 jaxws:wsimport 在生成的 @XmlElement
字段中添加 nillable=true
?我更喜欢更改 WSDL 文件而不是生成源的原因是
- 我已经对 WSDL 文件进行了一些更改,因此所有更改都可以放在一个地方,更容易记录。
- 我想避免更改生成的源,这样我就可以将它们排除在 Git 存储库之外,并防止在每次构建时被覆盖。
以下是代码的简化版本。
首先,我为 complexType Currency 生成了 java class。
// Generated
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "currency", propOrder = {
"crossCurrency",
"amount"
})
public class Currency {
@XmlElement(required = true)
protected Boolean crossCurrency;
@XmlElement(required = true)
protected BigDecimal amount;
}
我将字段设置为空,因为它们不存在。
requestInputRq.setCurrency(new Currency());
requestInputRa.setOtherField("Some value");
这将生成
<typ:Currency>
<typ:crossCurrency/>
<typ:amount/>
</typ:Currency>
将 nillable
属性与 @XmlElement
一起使用并将其值设置为 true
Currency.java
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "currency", propOrder = {
"isoCurrencyCode",
"amount"
})
public class Currency {
@XmlElement(required = true, nillable=true)
protected Boolean crossCurrency;
@XmlElement(required = true, nillable=true)
protected BigDecimal amount;
}
输出
<typ:Currency>
<typ:crossCurrency xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
<typ:amount xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
</typ:Currency>
WSDL
在每个请求的元素中添加 nillable
属性并将其值设置为 true
,如下例,
<xsd:element name="Currency" nillable="true" ... />