By kswaughs | Tuesday, March 8, 2016

Camel soap web service client

To consume a soap web service, first generate the stubs and data types from existing wsdl document using wsdl2java command. I have a HelloWorld service running on my machine and after running wsdl2java command, below web service client components are generated in the following packages.

com/kswaughs/poc/acct/
    HelloWorldImplService.class [ Web service client class]
    HelloWorld.class [ web service interface ]
    AcctRequest.class [ request data type ]
    AcctResponse.class [ response data type ]
 
wsdl/
    HelloWorld.wsdl [ wsdl document ]

In this below example, I will explain how to configure camel cxf endpoint using above classes and make a web service call using java DSL routing for building a web service request AcctRequest.java, parsing the web service response AcctResponse.java.

Step 1 : Write a service client class to build the web service request and parse web service response.

SoapSvcClient.java
package com.kswaughs.outbound;

import com.kswaughs.poc.acct.AcctRequest;
import com.kswaughs.poc.acct.AcctResponse;
import com.kswaughs.beans.UserResp;

public class SoapSvcClient {
 
    // Build web service request
    public AcctRequest buildSoapReq(String reqId) {
  
        AcctRequest acctReq = new AcctRequest();
  
        acctReq.setCustNumber(reqId);
  
        System.out.println("Soap Request built successfully");
  
        return acctReq;
    }

    // Read web service response and build a pojo response
    public UserResp parseSoapResp(AcctResponse soapResp) {
  
        UserResp resp = new UserResp();
        resp.setId(soapResp.getCustNumber());
        resp.setName(soapResp.getCustName());
        resp.setBalance(String.valueOf(soapResp.getBalance()));
  
        System.out.println("Soap Response parsed successfully");
  
        return resp;
    }
}

Step 2 : Define all your beans and endpoint in camel context.

camel-context.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:cxf="http://camel.apache.org/schema/cxf"
    xmlns:jaxrs="http://cxf.apache.org/jaxrs" 
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://camel.apache.org/schema/cxf
        http://camel.apache.org/schema/cxf/camel-cxf.xsd
        http://cxf.apache.org/jaxrs
        http://cxf.apache.org/schemas/jaxrs.xsd
        http://camel.apache.org/schema/spring
        http://camel.apache.org/schema/spring/camel-spring.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd">


    <bean id="myRouter" class="com.kswaughs.router.MyRouter" />
    <bean id="userSvcClient" class="com.kswaughs.outbound.SoapSvcClient" />

    <!-- Using Java DSL Router -->
    <camelContext id="firstCtx" xmlns="http://camel.apache.org/schema/spring">
    <routeBuilder ref="myRouter" />
    </camelContext>
 
    <cxf:cxfEndpoint id="accountEndpoint" address="http://localhost:3333/wspoc/user"
        wsdlURL="/wsdl/HelloWorld.wsdl"
        serviceClass="com.kswaughs.poc.acct.HelloWorld"
        endpointName="ws:HelloWorldImplPort"
        serviceName="ws:HelloWorldImplService" 
        xmlns:ws="http://acct.poc.kswaughs.com/" 
        loggingFeatureEnabled="true">
        <cxf:properties>
            <entry key="dataFormat" value="POJO"/>
        </cxf:properties>
    </cxf:cxfEndpoint>
</beans>

Step 3 : Define the Router using Java DSL

MyRouter.java
package com.kswaughs.router;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.cxf.common.message.CxfConstants;
import org.springframework.stereotype.Component;

    @Component
    public class MyRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {
  
        from("direct:getUserDetails")
            .bean("userSvcClient", "buildSoapReq")
            .setHeader(CxfConstants.OPERATION_NAME, constant("getAccountInfo"))
            .to("cxf:bean:accountEndpoint")
            .bean("userSvcClient", "parseSoapResp");
   
    }
}

Step 4 : Start the camel context and test your application.

CamelApp.java
package com.kswaughs.app;

import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.kswaughs.beans.UserResp;

public class CamelApp {

    public static void main(String[] args) {

        try {
            ApplicationContext springCtx = new 
                ClassPathXmlApplicationContext("camel-context.xml");

            CamelContext context = springCtx
                .getBean("firstCtx", CamelContext.class);
   
            context.start();
    
            ProducerTemplate producerTemplate = context.createProducerTemplate();
   
            UserResp resp = producerTemplate
                .requestBody("direct:getUserDetails", "12345", UserResp.class);
   
            System.out.println("resp:"+resp);

            context.stop();
  
        } catch (Exception e) {     
            e.printStackTrace();    
        } 
        finally {  }
 
    }

}

Console Output

 
Soap Request built successfully
INFO|03/02/2016 15:26:49 990|Outbound Message
---------------------------
ID: 1
Address: http://localhost:3333/wspoc/user
Encoding: UTF-8
Http-Method: POST
Content-Type: text/xml
Headers: {Accept=[*/*], breadcrumbId=[ID-PC223152-53569-1456912608587-0-1], SOAPAction=[""]}
Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:getAccountInfo xmlns:ns1="http://acct.poc.kswaughs.com/"><arg0><custNumber>12345</custNumber></arg0></ns1:getAccountInfo></soap:Body></soap:Envelope>
--------------------------------------
INFO|03/02/2016 15:26:50 011|Inbound Message
----------------------------
ID: 1
Response-Code: 200
Encoding: UTF-8
Content-Type: text/xml;charset="utf-8"
Headers: {Content-type=[text/xml;charset="utf-8"], Transfer-encoding=[chunked]}
Payload: <?xml version="1.0" encoding="UTF-8"?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:getAccountInfoResponse xmlns:ns2="http://acct.poc.kswaughs.com/"><return><balance>200</balance><custName>kswaughs</custName><custNumber>12345</custNumber></return></ns2:getAccountInfoResponse></S:Body></S:Envelope>
--------------------------------------
Soap Response parsed successfully
resp:UserResp [id=12345, name=kswaughs, balance=200]

Maven dependencies

pom.xml
<properties>
    <camelspring.version>2.16.0</camelspring.version>  
    <spring.version>4.1.6.RELEASE</spring.version>
</properties>

<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-core</artifactId>
    <version>${camelspring.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-cxf</artifactId>
    <version>${camelspring.version}</version>
</dependency>
<dependency>
    <groupId>org.apache.camel</groupId>
    <artifactId>camel-spring</artifactId>
    <version>${camelspring.version}</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
</dependency>

Recommend this on


7 comments:

  1. Can you please provide the code zip file.

    ReplyDelete
  2. getting org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 75 in XML document from class path resource [camel-context.xml] is invalid; nested exception is org.xml.sax.SAXParseException; lineNumber: 75; columnNumber: 38; cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element 'cxf:cxfEndpoint'.

    exception. Am I missing any dependencies here.

    ReplyDelete
    Replies
    1. Could you please double check if you have specified the schema location of the cxf namespace in the context xml.

      http://camel.apache.org/schema/cxf
      http://camel.apache.org/schema/cxf/camel-cxf.xsd

      Make sure you use same spring & camel versions that are used in this example.
      If you still getting error, please paste your context xml file, maven dependencies that are added in the classpath.

      Delete
  3. Can you Please share complete project

    ReplyDelete
  4. Can you Please share complete project

    ReplyDelete
  5. Could you please send me full project?

    ReplyDelete