Search code examples
javaweb-servicessoapnamespacesjax-ws

SOAP WS (JAX-WS) with Java implementation : I receive null parameters because of the namespace qualified


I got a SOAP project with JAX-WS and in my WSDL file the attribute elementFormDefault is set to qualified. Because of this, the xml request generated has the namespace (proj:) in front of all the elements :

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:proj="http://my-project.com/Project">
   <soapenv:Header/>
   <soapenv:Body>
      <proj:Consultation>
         <proj:Header>
            <proj:WSVersion>value</proj:WSVersion>
            <proj:TimeRequete>value</proj:TimeRequete>
            <proj:IDRequest>value</proj:IDRequest>
         </proj:Header>
         <proj:Element1>value</proj:Element1>
         <proj:Element2>value</proj:Element2>
         <proj:limit>value</proj:limit>
      </proj:Consultation>
   </soapenv:Body>
</soapenv:Envelope>

The problem is that on the server side, all the elements I retrieve are null. But when I remove the namespace tag from the elements (like when the attribute elementFormDefault is set to unqualified) I can access all my elements and it works perfectly. Like this :

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:proj="http://my-project.com/Project">
   <soapenv:Header/>
   <soapenv:Body>
      <proj:Consultation>
         <Header>
            <WSVersion>value</proj:WSVersion>
            <TimeRequete>value</proj:TimeRequete>
            <IDRequest>value</proj:IDRequest>
         </Header>
         <Element1>value</proj:Element1>
         <Element2>value</proj:Element2>
         <limit>value</proj:limit>
      </proj:Consultation>
   </soapenv:Body>
</soapenv:Envelope>

Unfortunately, I cannot change the elementFormDefault to unqualified : I can't modify the WSDL file... and all the request generated got the namespace tag "proj:" before the element in the xml request.

I searched and I'm kinda sure that this is a namespace problem with some annotations like in the @WebResult, @WebMethod etc. on the server side but I've tried modifying all this, setting the namespaces, deleting them... It doesn't seem to work.

Here is my WSDL File :

<wsdl:definitions
        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
        xmlns:tns="http://my-project.com/Project"
        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
        xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="MyProject"
        targetNamespace="http://my-project.com/Project"
>
    <wsdl:types>
        <xsd:schema elementFormDefault="qualified" targetNamespace="http://my-project.com/Project"  xmlns:tns="http://my-project.com/Project">

            <xsd:element name="DefaultFault">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element minOccurs="1" name="CodeError" type="xsd:string"/>
                        <xsd:element minOccurs="1" name="LibelleError" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>

            <xsd:simpleType name="Element1Type">
                <xsd:restriction base="xsd:string">
                    <xsd:minLength value="1"/>
                    <xsd:maxLength value="1"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType name="Element2Type">
                <xsd:restriction base="xsd:string">
                    <xsd:minLength value="0"/>
                    <xsd:maxLength value="30"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType name="Element3Type">
                <xsd:restriction base="xsd:string">
                    <xsd:minLength value="0"/>
                    <xsd:maxLength value="30"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType name="Element4Type">
                <xsd:restriction base="xsd:string">
                    <xsd:minLength value="0"/>
                    <xsd:maxLength value="20"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType name="Element5Type">
                <xsd:restriction base="xsd:string">
                    <xsd:minLength value="0"/>
                    <xsd:maxLength value="10"/>
                </xsd:restriction>
            </xsd:simpleType>
            <xsd:simpleType name="Element6Type">
                <xsd:restriction base="xsd:string">
                    <xsd:minLength value="0"/>
                    <xsd:maxLength value="50"/>
                </xsd:restriction>
            </xsd:simpleType>

            <xsd:element name="Consultation">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="Header" type="tns:HeaderRequeteType"/>
                        <xsd:element minOccurs="0" name="Element1" type="tns:Element1Type"/>
                        <xsd:element minOccurs="0" name="Element2" type="tns:Element2Type"/>
                        <xsd:element minOccurs="0" name="limit" type="xsd:int"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="ConsultationResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="Header" type="tns:HeaderReponseType"/>
                        <xsd:element name="Element3" type="tns:Element3Type"/>
                        <xsd:element name="offset" type="xsd:int"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>

            <xsd:element name="Update">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="Header" type="tns:HeaderRequeteType"/>
                        <xsd:element minOccurs="0" name="Element4" type="tns:Element4Type"/>
                        <xsd:element minOccurs="0" name="Element5" type="tns:Element5Type"/>
                        <xsd:element name="data" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="UpdateResponse">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="Header" type="tns:HeaderReponseType"/>
                        <xsd:element name="Element6" type="tns:Element6Type"/>
                        <xsd:element name="element" type="xsd:string"/>
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>

            <xsd:complexType name="HeaderRequeteType">
                <xsd:sequence>
                    <xsd:element name="WSVersion" type="xsd:string"/>
                    <xsd:element name="TimeRequete" type="xsd:dateTime"/>
                    <xsd:element name="IDRequest" type="xsd:string"/>
                </xsd:sequence>
            </xsd:complexType>
            <xsd:complexType name="HeaderReponseType">
                <xsd:sequence>
                    <xsd:element name="WSVersion"  type="xsd:string"/>
                    <xsd:element name="TimeReponse" type="xsd:dateTime"/>
                    <xsd:element name="TimeRequete" type="xsd:dateTime"/>
                    <xsd:element name="IDResponse" type="xsd:string"/>
                </xsd:sequence>
            </xsd:complexType>

        </xsd:schema>
    </wsdl:types>

    <wsdl:message name="MyProject_DefaultFaultMessage">
        <wsdl:part name="fault" element="tns:DefaultFault" />
    </wsdl:message>

    <wsdl:message name="MyProject_Consultation_InputMessage">
        <wsdl:part name="request" element="tns:Consultation"/>
    </wsdl:message>
    <wsdl:message name="MyProject_Consultation_OutputMessage">
        <wsdl:part name="response" element="tns:ConsultationResponse"/>
    </wsdl:message>

    <wsdl:message name="MyProject_Update_InputMessage">
        <wsdl:part name="request" element="tns:Update"/>
    </wsdl:message>
    <wsdl:message name="MyProject_Update_OutputMessage">
        <wsdl:part name="response" element="tns:UpdateResponse"/>
    </wsdl:message>

    <wsdl:portType name="MyProject">
        <wsdl:operation name="Consultation">
            <wsdl:input message="tns:MyProject_Consultation_InputMessage"/>
            <wsdl:output message="tns:MyProject_Consultation_OutputMessage"/>
            <wsdl:fault name="defaultFault" message="tns:MyProject_DefaultFaultMessage"/>
        </wsdl:operation>
        <wsdl:operation name="Update">
            <wsdl:input message="tns:MyProject_Update_InputMessage"/>
            <wsdl:output message="tns:MyProject_Update_OutputMessage"/>
            <wsdl:fault name="defaultFault" message="tns:MyProject_DefaultFaultMessage"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="BasicHttpBinding_MyProject" type="tns:MyProject">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="Consultation">
            <soap:operation soapAction="http://my-project.com/Project/Consultation" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
            <wsdl:fault name="defaultFault">
                <soap:fault name="defaultFault" use="literal"/>
            </wsdl:fault>
        </wsdl:operation>
        <wsdl:operation name="Update">
            <soap:operation soapAction="http://my-project.com/Project/Update" style="document"/>
            <wsdl:input>
                <soap:body use="literal"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal"/>
            </wsdl:output>
            <wsdl:fault name="defaultFault">
                <soap:fault name="defaultFault" use="literal"/>
            </wsdl:fault>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:service name="MyProject">
        <wsdl:port name="BasicHttpBinding_MyProject" binding="tns:BasicHttpBinding_MyProject">
            <soap:address location="http://my-project.com/Project"/>
        </wsdl:port>
    </wsdl:service>
</wsdl:definitions>

The Java implementation :

package web.service.server.myproject;


@WebService(name = "myProject", targetNamespace = "http://my-project.com/Project")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class MyProjectServiceImpl implements MyProjectService {

    @Override
    @WebMethod(operationName = "Consultation", action = "http://my-project.com/Project/Consultation")
    @WebResult(name = "ConsultationResponse", targetNamespace = "http://my-project.com/Project", partName = "response")
    public ConsultationResponse consultation(Consultation request)
        throws MyProjectDefaultMessage {

            // some code...

        }

    @Override
    @WebMethod(operationName = "Update", action = "http://my-project.com/Project/Update")
    @WebResult(name = "UpdateResponse", targetNamespace = "http://my-project.com/Project", partName = "response")
    public UpdateResponse update(Update request)
        throws MyProjectDefaultMessage {

            // some code ...

        }
}

And some elements :

package web.service.server.myproject.types;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "header",
    "element1",
    "element2",
    "limit"
})
@XmlRootElement(name = "Consultation")
public class Consultation {

    @XmlElement(name = "Header", required = true)
    protected HeaderRequeteType header;
    @XmlElement(name = "Element1")
    protected String element1;
    @XmlElement(name = "Element2")
    protected String element2;
    protected Integer limit;

    // getters and setters

}

and

package web.service.server.myproject.types;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "EnteteRequeteType", propOrder = {
    "VersionWS",
    "timeRequete",
    "idRequest",
})

public class HeaderRequeteType {

    @XmlElement(name = "WVersionS", required = true)
    protected String versionWS;
    @XmlElement(name = "TimeRequete", required = true)
    @XmlSchemaType(name = "dateTime")
    protected XMLGregorianCalendar timeRequete;
    @XmlElement(name = "IDRequest", required = true)
    protected String idRequest;

    // getters and setters

}

I also tried adding in the @XmlType the namespace but it didn't seem to work

Note :

  • I've change the names etc. from the WSDL and the java code so it would be easier to analyse. I also reduced them a lot. If there is some little mistyping mistakes, this is not the problem.
  • On the server side, it seems that it recognizes the request as a 'Consultation' or an 'Update' object, but everything inside is null (Header, Element1, Element2 ...)
  • If you need more infos, feel free to ask

If someone can help me I would be very grateful, this problem is actually driving me insane. Thanks !


Solution

  • I finally managed to resolve the problem.

    I added a

    package-info.java

    class in my package with all the types of my web service.

    @javax.xml.bind.annotation.XmlSchema(namespace = "http://my-project.com/Project", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
    package web.service.server.myproject.types;
    

    If I understand correctly, this put a package level annotation so my elements are all linked to my namespace.

    I hope this will help next people with the same problem :)