为什么JAX-WS从Holder转换为多个返回类型到单个部分响应?

时间:2013-09-19 18:37:47

标签: java web-services wsdl glassfish-3

我有一个来自现有服务的WSDL,我正在开发一个客户端和一个模拟器(在上线之前测试接口的两面)。我正在使用glassfish JAXWS库来生成代码,并使用glassfish 3.1.2.2作为服务器。我们正在运行Java 1.6。

在原始WSDL中,多个返回类型被定义为多个部分,并且自动生成的代码创建Holder条目以保存它们。也就是说,WSDL中的示例返回消息如下所示:

 <message name="returnTypeMessage">
    <part name="outDoc" element="tns:myResponseType"/>
    <part name="XMLAttach" element="xsd:string"/>
 </message>
 ...
<operation name="...">
  <wsdlsoap:operation soapAction="" soapActionRequired="false"/>
  <input ... />
  <output name="...response">
    <mime:multipartRelated>
      <mime:part>
        <wsdlsoap:body parts="outDoc" use="literal" />
      </mime:part>
      <mime:part>
        <mime:content part="XMLAttach" type="text/xml" />
      </mime:part>
    </mime:multipartRelated>
  </output>
</operation>

并且端口界面中生成的签名如下所示:

@WebMethod
public void methodName(@WebParam(name="...") inParameter,
  @WebParam(name="myResponseType", partName="outDoc") Holder<myResponseType> outDoc,
  @WebParam(name="moreData", partName="moreData") Holder<String> moreData);

到目前为止,这么好。现在,当我从这个接口创建一个服务端点类并将其部署到GlassFish 3.1.2.x,然后我转到WSDL时,WSDL会显示:

 <message name="returnTypeMessage">
    <part name="parameters" element="tns:someNewResponseType" />
 </message>
...
<operation name="...">
  <soap:operation soapAction=""/>
  <input>
    <soap:body use="literal"/>
  </input>
  <output>
    <soap:body use="literal"/>
  </output>
</operation>

,端口签名如下:

@WebMethod
@WebResult(name="someNewResponseType", partName="parameters")
public someNewResponseType methodName(...);

所以它将它从自己的Holder中的多个返回类型转换为包含多个元素的单个返回参数(类)。

真正的问题是,然后使用以前的签名尝试针对此部署的服务运行客户端失败,并显示“IllegalStateException:读者必须处于START_ELEMENT事件,而不是8事件”。

我发现这种行为很麻烦,并且非常希望能够很好地解释为什么我可以从WSDL生成端口,部署它的实现,然后广播一个与该初始生成的客户端不兼容的WSDL端口定义。

1 个答案:

答案 0 :(得分:0)

这结果是一个不太理想的WSDL(我无法改变)和参数格式化的组合。解决方案有两个要求。

首先,在生成的端口文件中,将SOAPBinding从SOAPBinding.ParameterStyle.BARE更改为WRAPPED:

@SOAPBinding(parameterStyle=SOAPBinding.ParameterStyle.WRAPPED)

在使用wsimport生成代码后,我使用ant替换任务完成了这项工作。 enableWrapperStyle的wsimport自定义选项无法正常工作(我相信,因为有一点需要注意,如果它无法完全标记包裹wsdl它将恢复为裸露)。

其次,在服务实现类中,在@WebService注释中,必须添加endpointInterface =“...”属性。没有它,它会在通话期间失败。我还补充道:

@WebService(..., endpointInterface="...")
@BindingType(value=SOAPBinding.SOAP12HTTP_BINDING)

鉴于这三个项目(WRAPPED,endpointInterface,BindingType),它随后用于从WSDL生成的服务和客户端。任何其他组合都会导致某种错误(现在似乎与其他问题有关,但最终会出现红色鲱鱼)。

请注意,生成的WSDL仍然不正确,但客户端工作正常,这最重要。