Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JAX-WS: why nested elements are in "" namespace?

Having a toy service as below

@WebService(targetNamespace="http://www.example.org/stock")
@SOAPBinding(style=Style.RPC,parameterStyle=ParameterStyle.WRAPPED)
public class GetStockPrice {
    @WebMethod(operationName="GetStockPrice",action="urn:GetStockPrice")
    @WebResult(partName="Price")
    public Double getPrice(
            @WebParam(name="StockName")
            String stock
        ) {
        return null;
    }
}

JAX-WS-generated client creates a SOAP message where StockName parameter has no namespace:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
  <S:Body>
    <ns2:GetStockPrice xmlns:ns2="http://www.example.org/stock">
      <StockName>IBM</StockName>
    </ns2:GetStockPrice>
  </S:Body>
</S:Envelope>

I would expect and wish StockName to be generated as

  <ns2:StockName>IBM</ns2:StockName>

i.e. in the target namespace, not in the anonymous one (ns2 is not default, as far as I can see from the message).

I wonder how to make JAX-WS to add the target namespace to the nested elements of the message?

An attempt to specify the namespace to WebParam annotation changed nothing as this param is ignored when RPC is used.

Or... Does it mean that parameters in RPC-style are always anonymous?

UPDATE

Silly me. Partially solved. What I had to do is

  • style=Document, to enable target namespaces for elements
  • param style=Wrapped, to enable top level element
  • specify target namespace for WebParam (why service one is not used? documentation says service namespace should be used)

That is:

@WebService(targetNamespace="http://www.example.org/stock")
@SOAPBinding(style=Style.DOCUMENT,parameterStyle=ParameterStyle.WRAPPED)
public class GetStockPrice {
    @WebMethod(operationName="GetStockPrice",action="urn:GetStockPrice")
    @WebResult(partName="Price")
    public Double getPrice(
            @WebParam(name="StockName",targetNamespace="http://www.example.org/stock")
            String stock
        ) {
        return null;
    }
}

Still, client still expects return value without any namespace, even if I try to declare provide one. This is confusing.

like image 627
Vladimir Dyuzhev Avatar asked Apr 26 '11 16:04

Vladimir Dyuzhev


People also ask

What's the point of XML namespaces?

An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.

What is the namespace in XML Schema?

Figure 1: Elements and attributes in XML Schema namespace are used to write an XML Schema document, which generates elements and attributes as defined by user and puts them in {target namespace}. This {target namespace} is then used to validate the XML instance.

What is a target namespace?

The targetNamespace declares a namespace for other xml and xsd documents to refer to this schema. The target prefix in this case refers to the same namespace and you would use it within this schema definition to reference other elements, attributes, types, etc. also defined in this same schema definition.


2 Answers

This behavior is proper per the WSI-Basic Profile. If you look at:

http://www.ws-i.org/profiles/basicprofile-1.1.html#Part_Accessors

section 4.7.20, assertion R2735 specifically states that for RPC/Literal, the part accessor elements must be put in elements with no namspace.

like image 112
Daniel Kulp Avatar answered Oct 22 '22 12:10

Daniel Kulp


I too have the same problem . i developed webservice clientusing JAX-WS, with SOAP UI simulation.My webservice client is working fine. but when i test with real server (axis web service). I got null values.

SOUP UI simulation response like this

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.aml.infrasofttech.biz" xmlns:dat="http://dataobject.aml.infrasofttech.biz">
   <soapenv:Header/>
   <soapenv:Body>
      <web:getCIPMatchResponse>
         <!--1 or more repetitions:-->
         <web:getCIPMatchReturn>
            <dat:countries>?</dat:countries>
            <dat:dob>?</dat:dob>
            <dat:fullName>?</dat:fullName>
            <dat:isError>?</dat:isError>
            <dat:listName>?</dat:listName>
            <dat:passport>?</dat:passport>
            <dat:percentage>?</dat:percentage>
            <dat:sdnId>?</dat:sdnId>
            <dat:sdnName>?</dat:sdnName>
         </web:getCIPMatchReturn>
      </web:getCIPMatchResponse>
   </soapenv:Body>
</soapenv:Envelope>

But in the server it response with out namespace like this..

        <countries>?</countries>
        <dob>?</dob>
        <fullName>?</fullName>
        <isError>?</isError>
        <listName>?</listName>
        <passport>?</passport>
        <percentage>?</percentage>
        <sdnId>?</sdnId>
        <sdnName>?</sdnName>

The JAX-WS generated code looks like this.

  @XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "SdnBean", namespace = "http://dataobject.aml.infrasofttech.biz", propOrder = {
    "countries",
    "dob",
    "fullName",
    "isError",
    "listName",
    "passport",
    "percentage",
    "sdnId",
    "sdnName"
})
public class SdnBean {

Then i have change the client jax-ws code @XmlType as shown below

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "countries",
    "dob",
    "fullName",
    "isError",
    "listName",
    "passport",
    "percentage",
    "sdnId",
    "sdnName"
})
public class SdnBean {

Now this will bind the soap response without namespace.

like image 29
Vidhya - Vidhyadharan Avatar answered Oct 22 '22 12:10

Vidhya - Vidhyadharan