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.