Javax.jws.WebParam.name vs javax.jws.WebParam.partName in JAX-WS and WSDL

javajax-wssoapweb serviceswsdl

I was digging in WSDL and JAX-WS, thats where I came across this.
When I write service interface in JAX-WS as follows:

@WebService
@SOAPBinding(style = Style.RPC)
public interface HelloWorld {
    @WebMethod
    @WebResult(name="helloworldstring")
    String getHelloWorldAsString(**@WebParam(name="myname")** String name);
}

The generated WSDL has message for request declared as follows:

<message name="getHelloWorldAsString">
    <part **name="myname"** type="xsd:string"></part>
</message>

When I generate client stub from wsimport utility, the generated service class gets both name and partName as "myname".

If I dont specify @WebParam at all in my service, the WSDL gets part name as arg0 while the service stub generated using wsimport gets both name and partName as arg0 in its @webParam declaration.

If I specify both name and partName in @WebParam in my service class as follows:

@WebService
@SOAPBinding(style = Style.RPC)
public interface HelloWorld {
    @WebMethod
    @WebResult(name="helloworldstring")
    String getHelloWorldAsString(**@WebParam(name="myname", partName="mypartname")**  String name);
}

The generated WSDL gets part name as mypartname. Also service stubs generated using wsimport gets mypartname for both name and partName of @WebParam declaration, completely ignoring name="myname" declared in my webservice.

So I dont understand the significance of these two properties of @WebParam. What should be reflected in WSDL if I specify different values in these two properties.

This link describes them as follows:

  • name: Specifies the name of the parameter as it appears in the generated WSDL document. For RPC bindings, this is the name of the wsdl:part representing the parameter. For document bindings, this is the local name of the XML element representing the parameter. Per the JAX-WS specification, the default is argN, where N is replaced with the zero-based argument index (i.e., arg0, arg1, etc.).
  • partName: Specifies the value of the name attribute of the wsdl:part element for the parameter. This property is used for document style SOAP bindings.

But still am not getting much understanding from it. Will like to know what difference it makes if I specify different name and partName.

Note: Am doing this all with RPC style SOAP binding not Document style.

Best Answer

Let's take a look what specification says about it (JSR-000224 Java API for XML-Based Web Services 2.2 Rev a 3.6.1):

The javax.jws.WebParam annotation (see 7.11.4) MAY be used to specify the name of the wsdl:part or XML Schema element declaration corresponding to a Java parameter. If both the name and partName elements are used in the javax.jws.WebParam annotation then the partName MUST be used for the wsdl:part name attribute and the name element from the annotation will be ignored.

So behaviour that you observe is correct according to specification. Two different attributes makes sense in case of Document style because there you have both part name and name of the element in <wsdl:types>. I was wondering whether it is possible to use element attribute of part in RPC service, like this:

<wsdl:part name="myname" element="tns:mynameelement" />

Short test shows that wsimport fails with error:

Invalid wsdl:operation "getHelloWorldAsString": its a rpc-literal operation, message part must refer to a schema type declaration

WSDL specification does not disallow that but WS-I Basic Profile does:

A wsdl:message in a DESCRIPTION MAY contain wsdl:parts that use the elements attribute provided those wsdl:parts are not referred to by a soapbind:body in an rpc-literal binding.

Conclusion: it does not make any difference if you specify different name and partName. Those two fields are there because same annotation is used for document binding style, where they make more sense.