0

The problem I'm having is with Apache CXF putting the namespace inside the element instead of soap envelope.

I used codegen maven plugin to generate the client code from WSDL.

Here are the namespaces in the WSDL:

              xmlns:http="http://schemas.xmlsoap.org/wsdl/http/"
              xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
              xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
              xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
              xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xs="http://www.w3.org/2001/XMLSchema"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

When I fire a SOAP request I can see in logs that the following message has been sent:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
    <ns1:userRegistrationRequest xmlns:ns1="http://some.com/namespace1">
        <InputParameter xmlns:ns2="http://some.com/namespace1">
            <ns2:Message>
                <ns2:Value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:nil="true"/>
                <ns2:HashTable>
                    <ns2:Item key="action">
                        <ns2:Value>some_action</ns2:Value>
                    </ns2:Item>
                </ns2:HashTable>
            </ns2:Message>
        </InputParameter>
    </ns1:userRegistrationRequest>
</soap:Body>

The problem is that the Value element was null in my code when I constructed the message, but here it appears with XSI namespace.

What I was expecting to get is something like this (Value element should not be present and XSI should be in the envelope element):

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
    <ns1:userRegistrationRequest xmlns:ns1="http://some.com/namespace1">
        <InputParameter xmlns:ns2="http://some.com/namespace1">
            <ns2:Message>
                <ns2:HashTable>
                    <ns2:Item key="action">
                        <ns2:Value>some_action</ns2:Value>
                    </ns2:Item>
                </ns2:HashTable>
            </ns2:Message>
        </InputParameter>
    </ns1:userRegistrationRequest>
</soap:Body>

Does anyone have an idea how to prevent the CXF from generating that empty Value element and put the namespace inside the soap envelope element?

Milan
  • 1,780
  • 1
  • 16
  • 29

1 Answers1

1

Ok, so to answer my question. There are two aspects of this problem.

First, adding namespaces to the envelope element. It can be done by writting a custom interceptor and registering it in some early phase. Something like this:

import java.util.Map;

import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.phase.Phase;

public class MyInterceptor extends AbstractSoapInterceptor {

    private Map<String, String> nsMap;

    public MyInterceptor(Map<String, String> nsMap) {
        super(Phase.USER_LOGICAL);
        this.nsMap = nsMap;
      }

    public void handleMessage(SoapMessage message) throws Fault {
        message.put("soap.env.ns.map", nsMap); 
        message.put("disable.outputstream.optimization", Boolean.TRUE); 
    }

}

I found the above solution here

Secondly, to remove empty value element an xsd should be changed to that the element has minOccurs="0" and nillable = "false".

Milan
  • 1,780
  • 1
  • 16
  • 29