英文:
How can I get the JAXB to generate empty tags for non-string elements?
问题
我正在尝试使用JAXB编组程序将Java对象映射到XML,以创建供应商SOAP服务的SOAP请求。我有一些元素,即使它们是空的或null的,也需要出现在请求中。我在pom.xml中使用jaxws-maven-plugin
插件与wsimport
目标来从WSDL文件生成源代码。
以下是生成源代码的Java类Currency的简化版本。
// 生成的代码
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "currency", propOrder = {
"crossCurrency",
"amount"
})
public class Currency {
@XmlElement(required = true)
protected Boolean crossCurrency;
@XmlElement(required = true)
protected BigDecimal amount;
}
然后我将字段设置为null,因为它们不存在。
requestInputRq.setCurrency(new Currency());
requestInputRa.setOtherField("Some value");
这将生成<typ:Currency />
,但我希望它生成如下所示:
<typ:Currency>
<typ:crossCurrency/>
<typ:amount/>
</typ:Currency>
希望这些信息能对您有所帮助。
英文:
Edit: I have re-formatted the question to hopefully make my intentions clearer.
I'm trying to map the java objects to XML using JAXB marshaller to create a soap request for a vendor SOAP service.
I have few elements which need to present in the request even if they are empty or null.
I use jaxws-maven-plugin
plugin with wsimport
goal in my pom.xml to generate sources from the WSDL files.
<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>
</plugin>
I've read and understood from here [ https://stackoverflow.com/questions/11215485/jax-ws-to-remove-empty-tags-from-request-xml ] that for the elements with xs:string
type, an empty tag can be generated by setting an empty string ""
as it's value. But it can't be done on the elements with types such as xs:dateTime, xs:boolean, xs:integer
which will produce XMLGregorianCalendar, BigInteger, Boolean
objects respectively. If I set their value as null, the elements will not be generated in marshaling process. Like others have pointed out, it can be achieved by adding nillable=true
to the @XmlElement
but that will require changing to the generated source which will be overwritten on the next build unless I remove the plugin from maven after the first build.
My current workaround is I changed the types of those particular elements that need to present in the request to xs:string
in the WSDL files and passed the empty string to their corresponding java object fields.
My question is, is it possible to make changes in the WSDL side that will trigger jaxws:wsimport to add nillable=true
in the generated @XmlElement
fields? The reason I prefer to change the WSDL files instead of generated sources is that
- I already have some changes in WSDL files so that all of the changes can be in one place, easier to document.
- I would like to avoid changing the generated sources so that I can keep them out of Git repo and also prevent being overwritten on each build.
Following is the simplified version of the code.
First I have this generated java class for the complexType Currency.
// 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;
}
And I set the fields as null because they don't exist.
requestInputRq.setCurrency(new Currency());
requestInputRa.setOtherField("Some value");
That will generate <typ:Currency /> but I need it to be generated like below.
<typ:Currency>
<typ:crossCurrency/>
<typ:amount/>
</typ:Currency>
答案1
得分: 1
请使用@XmlElement
的nillable
属性,并将其值设置为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" ... />
英文:
use the nillable
attribute with @XmlElement
and set it value to 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;
}
output
<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
add the nillable
attribute and set it value to true
in every requested element as following example,
<xsd:element name="Currency" nillable="true" ... />
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论