Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 656
Nicholas Albion Avatar asked Apr 16 '12 05:04

Nicholas Albion


2 Answers

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>
like image 187
Isaac Avatar answered Nov 18 '22 02:11

Isaac


I was having exactly the same problem. I experimented with the names I was using for the various types, elements, message names, operations names, and such. I finally found the key, and something you said in your question actually got me close to the answer:

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?

I looked at my wsdl, which was generating similar java code (with void return and a parameter list instead of a single object parameter). But I have different input and output types. What about my wsdl was similar to yours?

The name of the operation was the same as the name of the element defined for the input type. I would suggest that you change your operation name from 'requests' to something like 'processRequests', or leave the operation name alone, and change the name of the element used for the message definitions.

<wsdl:operation name="requests">

becomes

<wsdl:operation name="processRequests">

I'd love to hear if this works for you.

like image 14
ZachOfAllTrades Avatar answered Nov 18 '22 02:11

ZachOfAllTrades