I've made good progress on getting this to work, mostly by adding annotations 
to my service interface. Everything is working as far as calling the service 
from my test. I did have to change from ClientProxyFactoryBean to 
JaxWsProxyFactoryBean and set the binding to match the 
@BindingType(SOAPBinding.SOAP12HTTP_BINDING) in my service.

                JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
                factory.setBindingId("http://schemas.xmlsoap.org/wsdl/soap12/";);

Now I'm having issues getting the response wrapped in a soap envelop. 

Here's what I'm doing to try and marshal the response.

        SoapJaxbDataFormat soap = new 
SoapJaxbDataFormat("com.company.app.model",
                        new ServiceInterfaceStrategy(FooService.class, false));

        ....

                                .process(new Processor() {
                                        public void process(Exchange exchange) 
throws Exception {
                                                // get the value from the input
                                                List<HashMap> data = 
(ArrayList<HashMap>) exchange.getIn().getBody();
                                                // todo: handle value is empty
                                                FooResponse response = new 
FooResponse();
                                                
response.setGpi(String.valueOf(data.get(0).get("value")));
                                                
exchange.getOut().setBody(response);
                                        }
                                })
                                .marshal(soap);

The error I'm getting is:

java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object;
        at 
org.apache.camel.component.cxf.DefaultCxfBinding.populateCxfResponseFromExchange(DefaultCxfBinding.java:353)
        at 
org.apache.camel.component.cxf.CxfConsumer$1.setResponseBack(CxfConsumer.java:210)
        at 
org.apache.camel.component.cxf.CxfConsumer$1.asyncInvoke(CxfConsumer.java:109)
        at 
org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:74)

Do I have to register a type converter or something to help put the response 
body in a SOAP envelop?

Thanks,

Matt

On May 23, 2014, at 9:04 AM, Matt Raible <m...@raibledesigns.com> wrote:

> Hey all,
> 
> I have a route that produces a CXF Endpoint. 
> 
> public class FooRoute extends RouteBuilder {
> 
>       private String uri = "cxf:/foo?serviceClass=" + 
> FooService.class.getName();
> 
>       @Override
>       public void configure() throws Exception {
>               from(uri)
>                               .to("log:input")
>                                               // send the request to the 
> route to handle the operation
>                                               // the name of the operation is 
> in that header
>                               
> .recipientList(simple("direct:${header.operationName}"));
>               from("direct:findById")
>                               .process(new Processor() {
>                                       public void process(Exchange exchange) 
> throws Exception {
>                                               // get the id from the input
>                                               String id = 
> exchange.getIn().getBody(FooRequest.class).getId();
>                                               exchange.getOut().setBody(id);
>                                       }
>                               })
>                               .to("sql:select value from table where id = 
> #?dataSource=ds")
>                               .to("log:output")
>                               .process(new Processor() {
>                                       public void process(Exchange exchange) 
> throws Exception {
>                                               // get the value from the input
>                                               List<HashMap> data = 
> (ArrayList<HashMap>) exchange.getIn().getBody();
>                                               // todo: handle value is empty
>                                               FooResponse response = new 
> FooResponse();
>                                               
> response.setGpi(String.valueOf(data.get(0).get("value")));
>                                               
> exchange.getOut().setBody(response);
>                                       }
>                               }).end();
>       }
> }
> 
> This is easy to talk to thanks to CXF's ClientFactoryBean, allowing me to 
> call methods directly on the interface.
> 
>       protected static FooService createCXFClient() {
>               // we use CXF to create a client for us as its easier than 
> JAXWS and works
>               ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
>               factory.setServiceClass(FooService.class);
>               factory.setAddress(URL);
>               return (FooService) factory.create();
>       }
> 
> One of the things I'd like to do is make this new service 
> backwards-compatible with the old one. In other words, I should be able to 
> change the endpoint URL in the existing client and everything works the same. 
> The existing client uses the javax.xml.soap API to talk to the service. Below 
> is a test I wrote that shows how it works. Is it possible to modify my 
> route/endpoint so this WS call will work?
> 
> SOAPConnection connection = 
> SOAPConnectionFactory.newInstance().createConnection();
> SOAPMessage message = MessageFactory.newInstance("SOAP 1.2 
> Protocol").createMessage();
> SOAPPart soapPart = message.getSOAPPart();
> SOAPEnvelope envelope = soapPart.getEnvelope();
> envelope.addNamespaceDeclaration("soap", 
> "http://www.w3.org/2003/05/soap-envelope";);
> envelope.addNamespaceDeclaration("ax22", "http://common.app.company.com/xsd";);
> SOAPBody body = envelope.getBody();
> body.addNamespaceDeclaration("m", "http://ws.app.company.com";);
> 
> ByteArrayOutputStream request = new ByteArrayOutputStream();
> message.writeTo(request);
> 
> SOAPElement bodyChildOne = body.addChildElement("CompanyFooRequest", "m");
> SOAPElement bodyChildTwo = bodyChildOne.addChildElement("args0", "m");
> bodyChildTwo.addChildElement("ID", "ax22").addTextNode("123456");
> SOAPMessage reply = connection.call(message, 
> "http://localhost:7800/axis2/services/CompanyFooService_2_0";);
> if (reply != null) {
>       Iterator itr = reply.getSOAPBody().getChildElements();
>       Map resultMap = TestUtils.getResults(itr); // TestUtils loops through 
> SOAPElements to create a map
>       assertEquals("6610012", resultMap.get("value"));
> }
> 
> Thanks,
> 
> Matt
> 

Reply via email to