0

I'm facing an issue converting my SOAP request from CXF payload format to required format.

This is what the request looks like:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Header/>
   <soapenv:Body>
      <ObscureSOAPOperation xmlns="<wsdl-namespace-url>">
         <ObjectInfo>
            <value1>value1</value1>
            <value2>value2</value2>
         </ObjectInfo>
      </ObscureSOAPOperation>
   </soapenv:Body>
</soapenv:Envelope>

And this is what my route looks like:

from("properties:soapoperation.service.cxf.endpoint")
            .to("log:info?showAll=true")
            .process(new Processor() {
                @Override
                public void process(Exchange exchange) throws Exception {
                    CxfPayload<?> request = (CxfPayload<?>) exchange.getIn().getBody();
                    Source source = request.getBodySources().get(0);

                    JAXBElement<ObjectInfo> objectInfoElement =
                            jaxbContext.createUnmarshaller().unmarshal(source, ObjectInfo.class);

                    System.out.println("~~~~~~~~~Object Info value1: " + objectInfoElement.getValue().getValue1() + "~~~~~~~~~");
                }
            })

ObjectInfo is WSDL generated class. Incidentally the WSDL is a rpc/literal style wsdl.

The issue is that when the request from exchange is being cast to CxfPayload. It becomes null. The DOMSource looks like:

<ObjectInfo>
    <value1>null</value1>
    <value2>null</value2>
</ObjectInfo>

My SOAP request actually contains couple of more elements after ObjectInfo (the WSDL has multi-part message for the particular SOAP request) which are also null.

Nikhil Vibhav
  • 120
  • 1
  • 4
  • 11
  • I suspect your problem might be related to the fact that CXF does not support RPC style web services. See this : http://stackoverflow.com/questions/14831499/will-apache-cxf-supports-jax-rpc-based-web-servicessoap. – Namphibian Apr 13 '16 at 21:32
  • Ah. I suspected that too. It was worth a try. Meanwhile, I found a workaround, instead of using Source, I'm using XmlConverter to convert the body to String. And then unmarshal it to the required object type. – Nikhil Vibhav Apr 14 '16 at 05:48

2 Answers2

0

I've found a temporary work around to my problem.

Instead of using Source, I'm using XmlConverter to convert the body to String. And then unmarshal it to the required object type.

@Override
public void process(Exchange exchange) throws Exception {
    CxfPayload<SoapHeader> request = exchange.getIn().getBody(CxfPayload.class);

    XmlConverter converter = new XmlConverter();
    String xmlInRequest = converter.toString(request.getBody().get(0).cloneNode(true), exchange);

    xmlInRequest = xmlInRequest.replace(" xmlns=\"<wsdl-namespace-url>\"", "");
    xmlInRequest = xmlInRequest.replace(" xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\"", "");
    xmlInRequest = xmlInRequest.replace(" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", "");
    xmlInRequest = xmlInRequest.replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"", "");
    xmlInRequest = xmlInRequest.replace("<?xml version=\"1.0\" encoding=\"utf-8\"?>", "");

    JAXBContext jaxbContext = JAXBContext.newInstance("com.rmg.globalrates.adapter.models");
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
    StreamSource streamSource = new StreamSource(new StringReader(xmlInRequest));
    ObjectInfo objectInfo  = (ObjectInfo) unmarshaller.unmarshal(streamSource);
    System.out.println("----------------------------ObjectInfo-----------------------" + objectInfo.toString());
}

It seems like RPC is not supported by CXF. RPC, the source of all my woes for the past couple of days.

Nikhil Vibhav
  • 120
  • 1
  • 4
  • 11
  • This acts as workaround solution. Not a complete one. Only proper solution would be to modify the WSDL from RPC style to Document Style – Nikhil Vibhav Apr 15 '16 at 10:19
0

I would try CXF message format and a convertBodyTo=String further.

I like MESSAGE because it gives more visibility and control over responses and faults.

gnanagurus
  • 883
  • 1
  • 12
  • 29
  • Yep. Turns out that WSDL in malformed and I'm not allowed to change it in anyway. So I've exposed a rest endpoint which will accept incoming requests as XML. I think it's the best option right now. – Nikhil Vibhav Apr 15 '16 at 07:56