【问题标题】:How can I get the JAXB to generate empty tags for non-string elements? [duplicate]如何让 JAXB 为非字符串元素生成空标签? [复制]
【发布时间】:2020-08-25 09:34:35
【问题描述】:

编辑:我已重新格式化问题以希望使我的意图更清晰。

我正在尝试使用 JAXB 编组器将 java 对象映射到 XML,以便为供应商 SOAP 服务创建一个肥皂请求。 我几乎没有需要在请求中显示的元素,即使它们为空或为空。 我在 pom.xml 中使用 jaxws-maven-plugin 插件和 wsimport 目标从 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>

我从这里 [https://stackoverflow.com/questions/11215485/jax-ws-to-remove-empty-tags-from-request-xml] 阅读并理解了 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 文件而不是生成的源的原因是

  1. 我已经对 WSDL 文件进行了一些更改,因此所有更改都可以集中在一个地方,更易于记录。
  2. 我希望避免更改生成的源代码,以便将它们排除在 Git 存储库之外,并防止在每次构建时被覆盖。

以下是简化版的代码。

首先我为 complexType Currency 生成了这个 java 类。

// 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>

【问题讨论】:

  • 将 crossCurrency 和 amount 设置为空。
  • @FedericoklezCulloca new Currency() 已经将它们初始化为 null 不是吗?我刚刚尝试将它们设置为 null 以确保,但仍未生成标签。
  • 这能回答你的问题吗? Represent null value as empty element in xml jaxb
  • @Lakshan 是的,但我想尽可能避免更改生成的源文件,因为它们将在下一次导入时被覆盖。我当前的解决方法是将 WSDL 中那些必填字段的类型更改为 xs:string 并传递空字符串以触发空标签。这种方法花费了我很多数字格式验证,但如果我不想弄乱生成的源,这似乎是唯一的方法。

标签: java soap jaxb wsimport jaxws-maven-plugin


【解决方案1】:

将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" ... />

【讨论】:

  • 嗨 Lakshan,感谢您的回答。在我的情况下,源代码是从 wsdl 生成的,所以我想尽可能避免对生成的源进行更改。您知道是否有办法改为更改 WSDL,以便在生成源时将 nillable 添加到 @XmlElement?
  • @MinNaingOo 请参考上面修改后的答案
  • @MinNaingOo 如果它适合你,请接受答案:)
  • 最后一部分正是我要找的。谢谢@Lakshan!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
相关资源
最近更新 更多