5

In a Java project I created a webservice client using jax-ws and a wsdl. The request is valid xml but missing a prefix which is needed in this specific soap call. Currently I solve this by manually adding xmlns={@javax.xml.bind.annotation.XmlNs(prefix="gen", namespaceURI="http://schemas...")}) to the package-info.java class but feel this is not the best solution because the package-info is automatically created and my solution will be overwritten if for any reason the sources are generated again.

I suspect there is something missing in my wsdl.

Here's the wsdl:

<?xml version="1.0" encoding="UTF-8"?>
    <wsdl:definitions xmlns:tns="http://xmlns.example.com/1308658932768" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:ns0="http://schemas.triennium.com/Servicepunt/gen" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="Untitled" targetNamespace="http://xmlns.example.com/1308658932768">
        <wsdl:types>
        <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
     xmlns="http://schemas.triennium.com/Servicepunt/gen"
     targetNamespace="http://schemas.triennium.com/Servicepunt/gen"
     elementFormDefault="qualified"
     attributeFormDefault="unqualified">
            <xs:element name="CallInfo">
                <xs:complexType>
                    ...
                </xs:complexType>
            </xs:element>
            <xs:element name="ResponseStatus">
                <xs:complexType>
                    ...
                </xs:complexType>
            </xs:element>
            <xs:element name="Credentials">
                <xs:complexType>
                    ...
                </xs:complexType>
            </xs:element>
            <xs:element name="AuthenticateAannemerRequest">
                <xs:complexType>
                    ...
                </xs:complexType>
            </xs:element>
            <xs:element name="AuthenticateAannemerResponse">
                <xs:complexType>
                    ...
                </xs:complexType>
            </xs:element>
        </xs:schema>
    </wsdl:types>
    <wsdl:service name="WSDL_Generator.2.0.2">
        <wsdl:port name="AuthenticateAannemer.2.0.2" binding="tns:AuthenticateAannemer.2.0.2Binding">
            <soap:address location="http://10.11.2.12:2592"/>
        </wsdl:port>
    </wsdl:service>
    <wsdl:portType name="AuthenticateAannemer">
        <wsdl:operation name="AuthenticateAannemer">
            <wsdl:input message="tns:AuthenticateAannemerRequest"/>
            <wsdl:output message="tns:AuthenticateAannemerResponse"/>
        </wsdl:operation>
    </wsdl:portType>
    <wsdl:binding name="AuthenticateAannemer.2.0.2Binding" type="tns:AuthenticateAannemer">
        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
        <wsdl:operation name="AuthenticateAannemer">
            <soap:operation style="document" soapAction="/AuthenticateAannemer.2.0.2/AuthenticateAannemer"/>
            <wsdl:input>
                <soap:body use="literal" parts="input"/>
            </wsdl:input>
            <wsdl:output>
                <soap:body use="literal" parts="output"/>
            </wsdl:output>
        </wsdl:operation>
    </wsdl:binding>
    <wsdl:message name="AuthenticateAannemerRequest">
        <wsdl:part name="input" element="ns0:AuthenticateAannemerRequest"/>
    </wsdl:message>
    <wsdl:message name="AuthenticateAannemerResponse">
        <wsdl:part name="output" element="ns0:AuthenticateAannemerResponse"/>
    </wsdl:message>
</wsdl:definitions>

Here's the request without the prefix:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <AuthenticateAannemerRequest   xmlns="http://schemas.triennium.com/Servicepunt/gen">
            <CallInfo>
                <Customer>...</Customer>
                <Module>...</Module>
                <Version>...</Version>
            </CallInfo>
            <Credentials>
                <Username>...</Username>
                <Password>...</Password>
            </Credentials>
        </AuthenticateAannemerRequest>
    </S:Body>
</S:Envelope>

Here's the request as I want it to be:

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
    <S:Body>
        <gen:AuthenticateAannemerRequest xmlns:gen="http://schemas.triennium.com/Servicepunt/gen">
            <gen:CallInfo>
                <gen:Customer>...</Customer>
                <gen:Module>...</Module>
                <gen:Version>...</Version>
            </gen:CallInfo>
            <gen:Credentials>
                <gen:Username>...</Username>
                <gen:Password>...</Password>
            </gen:Credentials>
        </gen:AuthenticateAannemerRequest>
    </S:Body>
</S:Envelope>

edit: added prefix to namespacedeclaration in the second example, Which was there to start with, but was lost somehow while c/p the code.

Berend
  • 128
  • 1
  • 8
  • 5
    For a XML parser or soap implementation both requests should be identical. The prefix has no meaning in XML, important are the namespace and the local part of the name. In your second example, the prefix `gen` is not actually bound to any namespace, which should be invalid. If you meant to use `xmlns:gen` intead of just `xmlns` then both requests should get handled identically. – Jörn Horstmann Nov 22 '12 at 13:29

3 Answers3

0
@XmlRootElement(namespace = "http://schemas.triennium.com/Servicepunt/gen")
public class AuthenticateAannemerRequest implements Serializable {

    private CallInfo callInfo;
    private Credentials credentials;

    public AuthenticateAannemerRequest() {
    }

    @XmlElement(namespace = "http://schemas.triennium.com/Servicepunt/gen")
    public CallInfo getCallInfo() {
        return callInfo;
    }

    public void setCallInfo(CallInfo callInfo) {
        this.callInfo = callInfo;
    }

    @XmlElement(namespace = "http://schemas.triennium.com/Servicepunt/gen")
    public Credentials getCredentials() {
        return credentials;
    }

    public void setCredentials(Credentials credentials) {
        this.credentials = credentials;
    }
}
abg
  • 2,002
  • 7
  • 39
  • 63
0

You will need to manually compile the package-info.java into class file.

0

If you generate your classes from schema, you may add a JAXB bindings file.

Look at this answer for a template of that file that specifies a prefix for the schema default namespace.

Then specify the additional bindings file when using the genration tool.

EDIT

One example file you would use would be:

<?xml version="1.0"?>
<jxb:bindings version="1.0"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix"
              xsi:schemaLocation="http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd
              http://jaxb2-commons.dev.java.net/namespace-prefix http://java.net/projects/jaxb2-commons/sources/svn/content/namespace-prefix/trunk/src/main/resources/prefix-namespace-schema.xsd">

    <jxb:bindings>
        <jxb:schemaBindings>
            <jxb:package name="your-package-name-here" />
        </jxb:schemaBindings>
        <jxb:bindings>
            <namespace:prefix name="http://schemas.triennium.com/Servicepunt/gen" />
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

Remember to use the jaxb-commons plugin when generating classes.

Community
  • 1
  • 1
Valentino
  • 138
  • 1
  • 6