【问题标题】:Why classes generated by wsimport requires JAXBElement<ClassName> parameters?为什么 wsimport 生成的类需要 JAXBElement<ClassName> 参数?
【发布时间】:2012-08-31 07:56:23
【问题描述】:

我有一个来自 Axis2 Web 服务的 WSDL 文件。当我在给定 WSDL 文件的情况下使用 wsimport 生成客户端存根时,生成的类需要 JAXBElement 参数。为什么会这样?

来自生成的类之一的示例方法:

JAXBElement<DataBean> value;

public void setValue(JAXBElement<DataBean> value)
{
    this.value = ((JAXBElement<DataBean>) value);
}

我希望它看起来像这样(没有 JAXBElement):

DataBean value;

public void setValue(DataBean value)
{
    this.value= (DataBean) value;
}

我在网上看到的教程并没有将类设置为JAXBElement。可能是什么问题呢?请注意,服务器是 Axis2 Web 服务,WSDL 文件是由 Axis2 自动生成的。假设是我无法控制服务器。

我怎样才能使wsimport 不会将参数转换为 JAXBElements?

以下是 WSDL 文件的摘录:(我忽略了一些标签,只包含基本标签)

<xs:element name="getData">
    <xs:complexType>
        <xs:sequence>
            <xs:element minOccurs="0" name="getData" nillable="true" type="ax220:getData"/>
        </xs:sequence>
    </xs:complexType>
</xs:element>

<xs:complexType name="getData">
    <xs:sequence>
        <xs:element minOccurs="0" name="value" nillable="true" type="ax219:DataBean"/>
    </xs:sequence>
</xs:complexType>

<wsdl:message name="getDataRequest">
    <wsdl:part name="parameters" element="ns:getData"/>
</wsdl:message>

<wsdl:message name="getDataResponse">
    <wsdl:part name="parameters" element="ns:getDataResponse"/>
</wsdl:message>

<wsdl:operation name="getData">
    <wsdl:input message="ns:getDataRequest" wsaw:Action="urn:getData"/>
    <wsdl:output message="ns:getDataResponse" wsaw:Action="urn:getDataResponse"/>
</wsdl:operation>

<wsdl:operation name="getData">
    <soap:operation soapAction="urn:getData" style="document"/>
    <wsdl:input>
        <soap:body use="literal"/>
    </wsdl:input>
    <wsdl:output>
        <soap:body use="literal"/>
    </wsdl:output>
</wsdl:operation>

<wsdl:operation name="getData">
    <soap12:operation soapAction="urn:getData" style="document"/>
    <wsdl:input>
        <soap12:body use="literal"/>
    </wsdl:input>
    <wsdl:output>
        <soap12:body use="literal"/>
    </wsdl:output>
</wsdl:operation>

<wsdl:operation name="getData">
    <http:operation location="getData"/>
    <wsdl:input>
        <mime:content type="text/xml" part="parameters"/>
    </wsdl:input>
    <wsdl:output>
        <mime:content type="text/xml" part="parameters"/>
    </wsdl:output>
</wsdl:operation>

【问题讨论】:

  • 您能否发布在消息和操作中定义和使用 DataBean 的 WSDL 部分?
  • @joergl:我修改了我的帖子以包含请求的详细信息。

标签: java wsdl jax-ws axis2 wsimport


【解决方案1】:

如本页所述:

http://www.techdevtips.com/java/java-webservice-client-how-to-remove-jaxbelement

使用此代码的数据绑定文件:

<?xml version="1.0" encoding="UTF-8"?>
<jaxb:bindings
  xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" jaxb:version="2.0"
  xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc" jaxb:extensionBindingPrefixes="xjc">
  <jaxb:globalBindings generateElementProperty="false">
    <xjc:simple />
  </jaxb:globalBindings>
</jaxb:bindings>

并通过填充绑定属性(或 -b 标志参数,如果您使用可运行对象)在您的 wsimport ant 任务中使用它

干杯:)

【讨论】:

    【解决方案2】:

    首先:我不认为这是可以做到的。也就是说,我认为您不能告诉 wsimport 以不同的方式生成类。但是,我可以告诉您如何修改 WSDL,从而以不同的方式生成架构,并且仍然可以让您与服务对话。

    我从 WSDL 中获取了类型定义,调整了 complexType 的名称并添加了上面缺少的 DataBean 类型。我将它粘贴到一个模式并使用 xjc(JAXB 模式编译器)编译模式,wsimport 使用它从类型定义生成类。这是架构:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/DataBean"
        xmlns:tns="http://www.example.org/DataBean" elementFormDefault="qualified"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
    
        <xs:element name="getData">
            <xs:complexType>
                <xs:sequence>
                    <xs:element minOccurs="0" name="getDataType" type="tns:getDataType" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    
        <xs:complexType name="getDataType">
            <xs:sequence>
                <xs:element minOccurs="0" name="value" type="tns:DataBean" />
            </xs:sequence>
        </xs:complexType>
    
        <xs:complexType name="DataBean">
            <xs:simpleContent>
                <xs:extension base="xs:int" />
            </xs:simpleContent>
        </xs:complexType>
    </schema>
    

    编译器不需要任何特殊选项,只需执行 xjc 并将其指向架构文件,然后它将编译源文件。

    生成的类不使用JAXBElement 作为方法参数。那就是他们看起来像这样:

    protected DataBean value;
    
    public DataBean getValue() {
        return value;
    }
    

    这是为什么?我从元素定义中删除了nillable="true" 属性,这就成功了。 nillable="true" 声明显式空值在这里是合法的:

    <DataBean></DataBean> 
    

    如果您删除此属性,如果服务实际上在其中写入空值,您的代码将遇到问题。但是在生成了所有 WSDL 之后,也许 Axis2 只是认为 nillable 出于某种原因应该在其中,尽管实现从未真正使用它。如果幸运的话,虽然您修改了 WSDL,但它不会,并且一切都会正常工作。

    我希望这会有所帮助!如果没有,那么至少我今天学到了一些东西;-)

    【讨论】:

    • 嗨!谢谢!会试试这个。 :) 希望它有效。我会及时通知你的。所以基本上,您是说 Axis2 不符合 JAXWS,因此,如果不手动修改 WSDL,wsimport 就无法生成 Axis2 生成的 WSDL?我没听错吗?
    • 嗯,不。 Axis2 至少在很大程度上符合 JAX-WS。我没有详细测试它,但我确信它实现了大多数部分并且未能实现一些;-) 这里的问题是 JAXB 模式生成的一些边缘情况。我应该固定在根(Web 服务,通过更改注释以不生成 nillable=true)。由于您无法做到这一点,因此本地解决方案是您可以获得的最佳解决方案。
    • 感谢您的澄清!我想我在某处读到 Axis2 不是 JAX-WS,所以当我得知我要连接的服务是 JAX-WS 时,我远离它。此外,当我为 Axis2 生成客户端存根时,JAXB 不包含在数据绑定选项列表中。 (我使用的是 Eclipse。)数据绑定选项列表仅包括 ADB、XMLBeans、JIBX 和 None。我应该选择哪个选项来使用 JAXWS 绑定?
    • None of these ;-) Axis2 也支持 JAXB,但没有在其官方文档中列出:axis.apache.org/axis2/java/core/tools/CodegenToolReference.html 太可怜了...嗯,这里有一篇文章解释了如何使用 JAXB使用 Axis2 ibm.com/developerworks/java/library/j-jws8/index.html 简短的回答是您应该使用:-d jaxbri
    • 谢谢! :D 也许,我应该停止以懒惰的方式生成我的客户端存根(你好,IDE)。我会检查你的链接。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2017-11-18
    • 1970-01-01
    • 1970-01-01
    • 2011-02-21
    • 2014-03-19
    • 1970-01-01
    相关资源
    最近更新 更多