These are the steps to create a SOAP web service from java classes using Tomcat and CXF:
1) Create a new eclipse project
Create a new maven project in eclipse using the webapp archetype. Set the targeted runtime to a Tomcat server.
Add the following plugins to the pom.xml file:
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>2.1</version> <configuration> <webXml>src/main/webapp/WEB-INF/web.xml</webXml> </configuration> </plugin> </plugins> <finalName>javafirstws</finalName> </build>
Add CXF dependencies to the pom.xml file:
<dependencies> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxws</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>3.0.3</version> </dependency> <!-- Jetty is needed if you're are not using the CXFServlet --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http-jetty</artifactId> <version>3.0.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>3.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>3.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>3.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>3.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-ws-security</artifactId> <version>3.0.2</version> </dependency> <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpclient</artifactId> <version>3.1</version> </dependency> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>1.9</version> </dependency> </dependencies>
2) Create classes for Data Transfer Objects
Create classes for domain objects, request objects, and response objects.
All of these classes should have the XmlType annotation:
import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlType; @XmlType @XmlAccessorType(XmlAccessType.FIELD) public class CreditCardInfo { @XmlElement(required = true) String cardNumber; @XmlElement(required = true) private Date expirtyDate; @XmlElement(required = true) String firstName; @XmlElement(required = true) String lastName; @XmlElement(required = true) String secCode; @XmlElement(required = true) String Address;
The request object is an annotated POJO that encapsulates the request parameters:
@XmlType(name="PaymentProcessorRequest") @XmlAccessorType(XmlAccessType.FIELD) public class PaymentProcessorRequest { @XmlElement(name = "creditCardInfo", required= true) private CreditCardInfo creditCardInfo; @XmlElement(name = "amount", required= true) private Double amount; ...
Similarly, the response object is an annotated POJO that encapsulates the response data:
@XmlType public class PaymentProcessorResponse { private boolean result;
3) Create a processor interface
Create a processor interface that should include a method for each request. The interface should have the @WebService annotation. The mothod return type should have the @WebResult annotation and the method arguments should have the @WebParam annotation. All the types mentioned in this interface should be classes from step 2 that are annotated as @XmlType.
import javax.jws.WebParam; import javax.jws.WebResult; import javax.jws.WebService; import com.trainings.ws.soap.dto.PaymentProcessorRequest; import com.trainings.ws.soap.dto.PaymentProcessorResponse; @WebService(name = "PaymentProcessor") public interface PaymentProcessor { public @WebResult(name = "response") PaymentProcessorResponse processPayment( @WebParam(name = "paymentProcessorRequest") PaymentProcessorRequest paymentProcessorRequest); }
4) Implement the processor interface
There is nothing special in the interface implementation. We could have avoided the interface and annotated this class instead.
public class PaymentProcessorImpl implements PaymentProcessor { public PaymentProcessorResponse processPayment( PaymentProcessorRequest paymentProcessorRequest) { PaymentProcessorResponse paymentProcessorResponse = new PaymentProcessorResponse(); //Business Logic or a call to a Business Logic Class Goes Here. paymentProcessorResponse.setResult(true); return paymentProcessorResponse; } }
5) Add the CXF servlet to the web.xml file
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>cxf</display-name> <servlet> <description>Apache CXF Endpoint</description> <display-name>cxf</display-name> <servlet-name>cxf</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> </web-app>
6) Configure the CXF servlet
Add a cxf-servlet.xml file to the WEB-INF directory with the following configuration:
<?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:jaxws="http://cxf.apache.org/jaxws" xmlns:cxf="http://cxf.apache.org/core" xmlns:soap="http://cxf.apache.org/bindings/soap" xsi:schemaLocation="http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/bindings/soap http://cxf.apache.org/schemas/configuration/soap.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"> <jaxws:server id="paymentService" serviceClass="my.package.ws.soap.PaymentProcessor" address="/paymentProcessor"> <jaxws:serviceBean> <bean class="my.package.ws.soap.PaymentProcessorImpl" /> </jaxws:serviceBean> </jaxws:server> <cxf:bus> <cxf:features> <cxf:logging /> </cxf:features> </cxf:bus> </beans>
7) Deploy and Run
Deploy with Run As > Maven install. Run with Run As > Run on server.