Thursday, September 18, 2014

JAX-WS overriding Parameter name when generating code


When generating JAX-WS from code, you may at times need to override the default parameter names of the generated code.  Actually, sometimes it's required if you are having parameter name conflicts.  That happened to me recently.  I had a wsdl that defined an input message and output message that both had a header part like this:

<wsdl:message name="Ping">
<wsdl:part name="headerWSSE" element="wsse:Security"/>
<wsdl:part name="headerSYS" element="tnv:SystemInfo_Request"/>
<wsdl:part name="ping" element="tnv:ping"/>
</wsdl:message>
<wsdl:message name="PingResponse">
<wsdl:part name="headerSYS" element="tnv:SystemInfo_Response"/>
<wsdl:part name="pingResponse" element="tnv:pingResponse"/>
</wsdl:message>

Notice that both the Ping and PingResponse message define a part with the name="headerSYS".

The issue here is that when the code generator tries to create the ping() method in Java, it tries to create a method with 5 parameters... 3 for the input message parts and 2 for the output message parts. However, it would try to use the part name "headerSYS" as a parameter name for one of the input and one of the ouput parameters and it would bomb out because of two parameters having the same name in the same method signature.

Therefore, one fairly simple solution is to just create a custom binding file that tells ws-import how to handle these parameter names.  Here's what the custom binding file would look like:




<jaxws:bindings wsdlLocation="TelephoneNumberVerification_1_0_Logical.wsdl"
                 xmlns:xs="http://www.w3.org/2001/XMLSchema"
                 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                 xmlns:jaxws="http://java.sun.com/xml/ns/jaxws"
                 xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                 xmlns:tnv="http://barry.com/schemas/customerRelationship/Telephony">
       <jaxws:bindings node="wsdl:definitions/wsdl:portType[@name='TelephoneNumberVerification']/wsdl:operation[@name='ping']">
         <jaxws:parameter
                 part="wsdl:definitions/wsdl:message[@name='PingResponse']/wsdl:part[@name='headerSYS']"
                 childElementName="tnv:SystemInfo_Response" name="headerSysResponse"/>
     </jaxws:bindings>
     
 </jaxws:bindings>



I've attempted to hi-lite any thing that is custom for my wsdl that someone would have to change if they copied it and used it as a template.

By pointing ws-import to this custom binding, I was able to generate the code successfully and ended up with a method signature like this:



  public void ping(SecurityHeaderType headerWSSE, SystemInfoRequest headerSYS, boolean ping, Holder<SystemInfoResponse> headerSysResponse, Holder<Boolean> pingResponse)




Hope this helps!