Call SOAP Webservice Using CXF
Get the WSDL from an example SOAP service.
Store the WSDL file named calculator.wsdl in your codebase in the folder src/main/resources/wsdls.
Add a dependency on CXF framework to the pom.xml.
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.pricefx.integration</groupId> <version>1.0.0-SNAPSHOT</version> <artifactId>im-example-soap-cxf</artifactId> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring.boot>1.5.4.RELEASE</spring.boot> <pricefx-im-version>1.1.14</pricefx-im-version> </properties> <dependencyManagement> <dependencies> <!-- PFX Integration Manager --> <dependency> <groupId>net.pricefx.integration</groupId> <artifactId>integration-manager</artifactId> <version>${pricefx-im-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- PFX Integration Manager --> <dependency> <groupId>net.pricefx.integration</groupId> <artifactId>integration-manager-starter</artifactId> </dependency> <!-- Apache CXF Framework --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cxf</artifactId> </dependency> </dependencies> <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>1.5.4.RELEASE</version> <configuration> <mainClass>net.pricefx.integration.app.Application</mainClass> <executable>true</executable> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
Modify pom.xml to generate JAXB beans during Maven build using the Maven plugin and run
mvn package
. It will generate classes to the target folder of the project.pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.pricefx.integration</groupId> <version>1.0.0-SNAPSHOT</version> <artifactId>im-example-soap-cxf</artifactId> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring.boot>1.5.4.RELEASE</spring.boot> <pricefx-im-version>1.1.14</pricefx-im-version> </properties> <dependencyManagement> <dependencies> <!-- PFX Integration Manager --> <dependency> <groupId>net.pricefx.integration</groupId> <artifactId>integration-manager</artifactId> <version>${pricefx-im-version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <!-- PFX Integration Manager --> <dependency> <groupId>net.pricefx.integration</groupId> <artifactId>integration-manager-starter</artifactId> </dependency> <!-- Apache CXF Framework --> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-cxf</artifactId> </dependency> </dependencies> <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>1.5.4.RELEASE</version> <configuration> <mainClass>net.pricefx.integration.app.Application</mainClass> <executable>true</executable> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <encoding>UTF-8</encoding> </configuration> </plugin> <!-- Generates JAXB beans from WSDL --> <plugin> <groupId>org.apache.cxf</groupId> <artifactId>cxf-codegen-plugin</artifactId> <version>3.2.4</version> <executions> <execution> <id>generate-sources</id> <phase>generate-sources</phase> <configuration> <wsdlOptions> <wsdlOption> <wsdl>src/main/resources/wsdls/PricingService.svc.xml</wsdl> </wsdlOption> </wsdlOptions> </configuration> <goals> <goal>wsdl2java</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
Add the route file to the camel-context.xml.
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <import resource="refs/routes/cxfRoutes.xml"/> <camelContext xmlns="http://camel.apache.org/schema/spring" useMDCLogging="true"> <contextScan/> <routeContextRef ref="cxfRoutes"/> </camelContext> </beans>
Create the route file cxfRoutes.xml in src/main/resources/refs/routes containing JAXB factory.
cxfRoutes.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <!-- JAXB bean factory for autowiring --> <bean id="objectFactory" class="org.tempuri.ObjectFactory"/> <routeContext id="cxfRoutes" xmlns="http://camel.apache.org/schema/spring"> <!-- a transaction with data from webservice --> <route id="callSOAP"> <from uri="timer:foo?repeatCount=1"/> </route> </routeContext> </beans>
Implement a service class for creating the request and setting parameters.
GetPriceService.java
package net.pricefx.integration.example.cxf; import org.apache.camel.Exchange; import org.datacontract.schemas._2004._07.pricing_service.GetPriceRequestDto; import org.datacontract.schemas._2004._07.pricing_service.GetPriceResponseDto; import org.datacontract.schemas._2004._07.pricing_service.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; /** * Service for WSDL data objects */ public class GetPriceService { @Autowired public ObjectFactory getPriceObjectFactory; /** * set GetPrice Distance * @param getPriceRequestDto * @param distance */ public void setDistance(GetPriceRequestDto getPriceRequestDto, String distance) { getPriceRequestDto.setDistance(Double.valueOf(distance).intValue()); } public void setVehicleSize(GetPriceRequestDto getPriceRequestDto, String vehicleSize) { getPriceRequestDto.setVehicleSize(getPriceObjectFactory.createGetPriceRequestDtoVehicleSize(vehicleSize)); } public void setVin(GetPriceRequestDto getPriceRequestDto, String VIN) { getPriceRequestDto.setVin(getPriceObjectFactory.createGetPriceRequestDtoVin(VIN)); } public void setPricingCustomerId(GetPriceRequestDto getPriceRequestDto, String pricingCustomerId) { getPriceRequestDto.setPricingCustomerId(Integer.parseInt(pricingCustomerId)); } public void setDropOffZip(GetPriceRequestDto getPriceRequestDto, String dropoffZip) { getPriceRequestDto.setDropOffZip(getPriceObjectFactory.createGetPriceRequestDtoDropOffZip(dropoffZip)); } public void setPickUpZip(GetPriceRequestDto getPriceRequestDto, String pickupZip) { getPriceRequestDto.setPickUpZip(getPriceObjectFactory.createGetPriceRequestDtoPickUpZip(pickupZip)); } public void setIsOperable(GetPriceRequestDto getPriceRequestDto, String isOperable) { getPriceRequestDto.setIsOperable(Boolean.parseBoolean(isOperable)); } public void setRepoFlag(GetPriceRequestDto getPriceRequestDto, String repoFlag) { getPriceRequestDto.setRepoFlag(Boolean.parseBoolean(repoFlag)); } public GetPriceRequestDto createGetPriceRequest(Exchange exchange) { GetPriceRequestDto request = getPriceObjectFactory.createGetPriceRequestDto(); // Distance request.setDistance(((Double) exchange.getIn().getHeader("Distance")).intValue()); // VehicleSize request.setVehicleSize(getPriceObjectFactory.createGetPriceRequestDtoVehicleSize((String) exchange.getIn().getHeader("VehicleSize"))); // VIN request.setVin(getPriceObjectFactory.createGetPriceRequestDtoVin((String) exchange.getIn().getHeader("VIN"))); // PricingCustomerId request.setPricingCustomerId(Integer.parseInt((String) exchange.getIn().getHeader("PricingCustomerId"))); // DropffZip request.setDropOffZip(getPriceObjectFactory.createGetPriceRequestDtoDropOffZip((String) exchange.getIn().getHeader("DropoffZip5digit"))); // PickupZip request.setPickUpZip(getPriceObjectFactory.createGetPriceRequestDtoPickUpZip((String) exchange.getIn().getHeader("PickupZip5digit"))); // IsOperable request.setIsOperable(Boolean.parseBoolean((String) exchange.getIn().getHeader("IsInOperable"))); // repoFlag - not in PFX request.setRepoFlag(false); return request; } public String getPrice(GetPriceResponseDto getPriceResponseDto) { // FIXME: formatting the number return getPriceResponseDto.getPrice().toString(); } }
Call the service to create the request and set parameters.
cxfRoutes.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd"> <!-- JAXB bean factory for autowiring --> <bean id="objectFactory" class="org.tempuri.ObjectFactory"/> <routeContext id="cxfRoutes" xmlns="http://camel.apache.org/schema/spring"> <!-- a transaction with data from webservice --> <route id="callSOAP"> <from uri="timer:foo?repeatCount=1"/> <!-- create a request data object (JAXB bean) --> <bean ref="getPriceObjectFactory" method="createGetPriceRequestDto()"/> <!-- set parameters --> <bean ref="getPriceService" method="setDistance(${body},16)"/> <bean ref="getPriceService" method="setVehicleSize(${body},'Small')"/> <bean ref="getPriceService" method="setVin(${body},'ZARFAECN3H7546585')"/> <bean ref="getPriceService" method="setPricingCustomerId(${body},130)"/> <bean ref="getPriceService" method="setDropOffZip(${body},'92504')"/> <bean ref="getPriceService" method="setPickUpZip(${body},'91761')"/> <bean ref="getPriceService" method="setIsOperable(${body},'False')"/> <bean ref="getPriceService" method="setRepoFlag(${body},'false')"/> </route> </routeContext> </beans>
Define and call the CXF endpoint. Set the method.
cxfRoutes.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd"> <!-- JAXB bean factory for autowiring --> <bean id="objectFactory" class="org.tempuri.ObjectFactory"/> <!-- WSDL bean service --> <bean id="getPriceService" class="net.pricefx.integration.example.cxf.GetPriceService"/> <bean id="getPriceObjectFactory" class="org.datacontract.schemas._2004._07.pricing_service.ObjectFactory"/> <!-- CXF endpoint --> <cxf:cxfEndpoint id="getPriceEndPoint" wsdlURL="classpath:wsdls/PricingService.svc.xml" serviceClass="org.tempuri.IPricingService" address="http://ws1.1dispatch.com/PricingEngine/PricingService.svc" /> <routeContext id="cxfRoutes" xmlns="http://camel.apache.org/schema/spring"> <!-- a transaction with data from webservice --> <route id="callSOAP"> <from uri="timer:foo?repeatCount=1"/> <!-- create a request data object (JAXB bean) --> <bean ref="getPriceObjectFactory" method="createGetPriceRequestDto()"/> <!-- set parameters --> <bean ref="getPriceService" method="setDistance(${body},16)"/> <bean ref="getPriceService" method="setVehicleSize(${body},'Small')"/> <bean ref="getPriceService" method="setVin(${body},'ZARFAECN3H7546585')"/> <bean ref="getPriceService" method="setPricingCustomerId(${body},130)"/> <bean ref="getPriceService" method="setDropOffZip(${body},'92504')"/> <bean ref="getPriceService" method="setPickUpZip(${body},'91761')"/> <bean ref="getPriceService" method="setIsOperable(${body},'False')"/> <bean ref="getPriceService" method="setRepoFlag(${body},'false')"/> <!-- set the method --> <setHeader headerName="operationName"> <constant>GetPrice</constant> </setHeader> <to uri="cxf:bean:getPriceEndPoint"/> </route> </routeContext> </beans>
Check the result for a failure and log the result.
cxfRoutes.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd"> <!-- JAXB bean factory for autowiring --> <bean id="objectFactory" class="org.tempuri.ObjectFactory"/> <!-- WSDL bean service --> <bean id="getPriceService" class="net.pricefx.integration.example.cxf.GetPriceService"/> <bean id="getPriceObjectFactory" class="org.datacontract.schemas._2004._07.pricing_service.ObjectFactory"/> <!-- CXF endpoint --> <cxf:cxfEndpoint id="getPriceEndPoint" wsdlURL="classpath:wsdls/PricingService.svc.xml" serviceClass="org.tempuri.IPricingService" address="http://ws1.1dispatch.com/PricingEngine/PricingService.svc" /> <routeContext id="cxfRoutes" xmlns="http://camel.apache.org/schema/spring"> <!-- a transaction with data from webservice --> <route id="callSOAP"> <from uri="timer:foo?repeatCount=1"/> <!-- create a request data object (JAXB bean) --> <bean ref="getPriceObjectFactory" method="createGetPriceRequestDto()"/> <!-- set parameters --> <bean ref="getPriceService" method="setDistance(${body},16)"/> <bean ref="getPriceService" method="setVehicleSize(${body},'Small')"/> <bean ref="getPriceService" method="setVin(${body},'ZARFAECN3H7546585')"/> <bean ref="getPriceService" method="setPricingCustomerId(${body},130)"/> <bean ref="getPriceService" method="setDropOffZip(${body},'92504')"/> <bean ref="getPriceService" method="setPickUpZip(${body},'91761')"/> <bean ref="getPriceService" method="setIsOperable(${body},'False')"/> <bean ref="getPriceService" method="setRepoFlag(${body},'false')"/> <!-- set the method --> <setHeader headerName="operationName"> <constant>GetPrice</constant> </setHeader> <to uri="cxf:bean:getPriceEndPoint"/> <choice> <when> <simple>${body[0].isSuccess()}</simple> <log message="price ${body[0].getPrice()}" /> </when> <otherwise> <log message="failed: ${body[0].getMessage().getValue()}" loggingLevel="WARN"/> </otherwise> </choice> </route> </routeContext> </beans>
IntegrationManager version 6.0.0