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>
Can you please provide the code zip file.
ReplyDeletegetting 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'.
ReplyDeleteexception. Am I missing any dependencies here.
Could you please double check if you have specified the schema location of the cxf namespace in the context xml.
Deletehttp://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.
Can you Please share complete project
ReplyDeleteCan you Please share complete project
ReplyDeleteCould you please send me full project?
ReplyDeleteNice article - THANK YOU
ReplyDelete