如何让JAXB为非字符串元素生成空标签?

huangapple go评论85阅读模式
英文:

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.

&lt;plugin&gt;
&lt;groupId&gt;com.helger.maven&lt;/groupId&gt;
&lt;artifactId&gt;jaxws-maven-plugin&lt;/artifactId&gt;
&lt;version&gt;2.6&lt;/version&gt;
&lt;executions&gt;
	&lt;execution&gt;
		&lt;goals&gt;
			&lt;goal&gt;wsimport&lt;/goal&gt;
		&lt;/goals&gt;
		&lt;configuration&gt;
			&lt;wsdlFiles&gt;
				&lt;wsdlFile&gt;${project.basedir}/src/wsdl/sample/SomeSoapService.wsdl&lt;/wsdlFile&gt;
			&lt;/wsdlFiles&gt;
		&lt;/configuration&gt;
		&lt;id&gt;wsimport-generate-cbs&lt;/id&gt;
		&lt;phase&gt;generate-sources&lt;/phase&gt;
	&lt;/execution&gt;
&lt;/executions&gt;
&lt;dependencies&gt;
	&lt;dependency&gt;
		&lt;groupId&gt;javax.xml&lt;/groupId&gt;
		&lt;artifactId&gt;webservices-api&lt;/artifactId&gt;
		&lt;version&gt;2.0&lt;/version&gt;
	&lt;/dependency&gt;
&lt;/dependencies&gt;
&lt;configuration&gt;
	&lt;sourceDestDir&gt;${project.build.directory}/generated-sources/jaxws-wsimport&lt;/sourceDestDir&gt;
	&lt;xnocompile&gt;true&lt;/xnocompile&gt;
	&lt;xadditionalHeaders&gt;true&lt;/xadditionalHeaders&gt;
	&lt;verbose&gt;true&lt;/verbose&gt;
	&lt;extension&gt;true&lt;/extension&gt;
&lt;/configuration&gt;

</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 &quot;&quot; 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

  1. I already have some changes in WSDL files so that all of the changes can be in one place, easier to document.
  2. 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 = &quot;currency&quot;, propOrder = {
    &quot;crossCurrency&quot;,
    &quot;amount&quot;
})
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(&quot;Some value&quot;);

That will generate <typ:Currency /> but I need it to be generated like below.

&lt;typ:Currency&gt;
    &lt;typ:crossCurrency/&gt;
    &lt;typ:amount/&gt;
&lt;/typ:Currency&gt;

答案1

得分: 1

请使用@XmlElementnillable属性,并将其值设置为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 = &quot;currency&quot;, propOrder = {
    &quot;isoCurrencyCode&quot;,
    &quot;amount&quot;
})
public class Currency {

    @XmlElement(required = true, nillable=true)
    protected Boolean crossCurrency;
    @XmlElement(required = true, nillable=true)
    protected BigDecimal amount;
}

output

&lt;typ:Currency&gt;
    &lt;typ:crossCurrency xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:nil=&quot;true&quot;/&gt;
    &lt;typ:amount xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:nil=&quot;true&quot;/&gt;
&lt;/typ:Currency&gt;

WSDL

add the nillable attribute and set it value to true in every requested element as following example,

&lt;xsd:element name=&quot;Currency&quot; nillable=&quot;true&quot; ... /&gt;

huangapple
  • 本文由 发表于 2020年8月25日 17:34:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63575992.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定