jax-ws/wsimport generates WebMethod with void return - same Request/ResponseWrapper

Nicholas Albion picture Nicholas Albion · Apr 16, 2012 · Viewed 10.9k times · Source

I'm working with a client's WSDL file that uses the same element definition for the input and output messages, but I'm having trouble getting JAX-WS/JAXB to unmarshal the response.

<wsdl:message name="invokeServiceRequest">
    <wsdl:part element="impl:requests" name="multiRequestWrapper"/>
</wsdl:message>
<wsdl:message name="invokeServiceResponse">
    <wsdl:part element="impl:requests" name="result"/>
</wsdl:message>
<wsdl:portType name="GCGatewayPortType">
    <wsdl:operation name="requests">
        <wsdl:input message="impl:invokeServiceRequest" name="invokeServiceRequest"/>
        <wsdl:output message="impl:invokeServiceResponse" name="invokeServiceResponse"/>
    </wsdl:operation>
</wsdl:portType>

For some reason, the code generated by wsimport has a void return, and the INOUT params don't seem to be updated when the response is received.

/**
 * This class was generated by the JAX-WS RI.
 * JAX-WS RI 2.1.7-b01-
 * Generated source version: 2.1
 */
...
@WebMethod
@RequestWrapper(localName = "requests", targetNamespace = "http://cg.test.com/", className = "com.test.cg.RequestsType")
@ResponseWrapper(localName = "requests", targetNamespace = "http://cg.test.com/", className = "com.test.cg.RequestsType")
public void requests(
    @WebParam(name = "paramOne", targetNamespace = "http://cg.test.com/", mode = WebParam.Mode.INOUT)
    Holder<String> paramOne,
    @WebParam(name = "paramTwo", targetNamespace = "http://cg.test.com/", mode = WebParam.Mode.INOUT)
    Holder<String> paramTwo,
    @WebParam(name = "requestList", targetNamespace = "http://cg.test.com/", mode = WebParam.Mode.INOUT)
    Holder<List<RequestType>> requestList);

When I call port.request( paramOne, paramTwo, requestList ), I can see that the SOAP request is sent to the server, which responds with a valid SOAP response:

<soapenv:Envelope ...>
    <soapenv:Header />
    <soapenv:Body>
        <requests ...>
            <paramOne>1</paramOne>
            <paramTwo>2</paramTwo>
            <requestList>
                <!-- various elements that JAXB has generated code for -->

However, when I run my app in debug mode, I can see each RequestType instance in the debugger variables view, but because RequestsType has an <xsd:choice> with RequestData or ResponseData, the latter is null and the RequestData is as I provided.

I've successfully used JAX-WS on other projects, but in those cases it generated code with a @WebResult and non-void return type named after the WebResult. In this project, I think I'm not getting the WebResult because JAX-WS has decided that the request and response types are the same and it can reuse the same object - but how do I get it to update that object with data from the response?

Answer

Isaac picture Isaac · Oct 3, 2014

You can solve this by instructing JAX-WS to disable wrapping. This is done through a JAX-WS bindings file.

<jaxws:bindings xmlns:jaxws="http://java.sun.com/xml/ns/jaxws">
    <jaxws:enableWrapperStyle>false</jaxws:enableWrapperStyle>
</jaxws:bindings>