Asynchronous Web Service Using CXF

Asynchronous Web Service Using CXF explains about Creating / Developing JAX-WS Asynchronous Web service with the help of Apache CXF, Spring, Eclipse and deployed in Tomcat

In this example we are showing implementing an Asynchronous SOAP services using CXF Java first approach.

The asynchronous model allows the client thread to continue after making a two-way invocation without being blocked while awaiting a response from the server. Once the response is available, it is delivered to the client application asynchronously

For this there are two alternative approaches:

1) Callback: client application implements the javax.xml.ws.AsyncHandler interface to accept notification of the response availability
2) Polling: client application periodically polls a javax.xml.ws.Response instance to check if the response is available

Reference -> http://cxf.apache.org/docs/developing-a-consumer.html

Required Libraries

You need to download

  1. JDK 6
  2. Eclipse 3.7
  3. CXF-2.7.3
  4. Tomcat 7

Following jar must be in classpath

  1. aopalliance-1.0.jar
  2. commons-logging-1.1.1.jar
  3. cxf-2.7.3.jar
  4. httpasyncclient-4.0-beta3.jar
  5. httpclient-4.2.1.jar
  6. httpcore-4.2.2.jar
  7. httpcore-nio-4.2.2.jar
  8. neethi-3.0.2.jar
  9. spring-aop-3.0.7.RELEASE.jar
  10. spring-asm-3.0.7.RELEASE.jar
  11. spring-beans-3.0.7.RELEASE.jar
  12. spring-context-3.0.7.RELEASE.jar
  13. spring-core-3.0.7.RELEASE.jar
  14. spring-expression-3.0.7.RELEASE.jar
  15. spring-web-3.0.7.RELEASE.jar
  16. wsdl4j-1.6.2.jar
  17. xmlschema-core-2.0.3.jar

CXF Asynchronous Web Service Tutorial

I am creating a sample web service project that pass Student object and return with some changes on that object. The service is using simple POJO (Plain Old Java Object) bean.

Firstly create a Dynamic Web Project (File->New->Dynamic Web Project) named "CXFTutorial" according to following screenshot

Create CXF Project CXF Asynchronous Tutorial

Create a Student Object

package com.student;

public class Student {
 
private String name;
 
public String getName() {
   
return name;
 
}
 
public void setName(String name) {
   
this.name = name;
 
}
}

Create a Service Interface

This service interface will defines which methods of web service, to be invoked by the client

package com.student;

import java.util.concurrent.Future;

import javax.jws.WebService;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;
import javax.xml.ws.ResponseWrapper;

@WebService(name = "ChangeStudentDetails")
public interface ChangeStudentDetails {

   
public Response<Student> changeStudentAsync(String name);

   
   
@ResponseWrapper(localName = "changeStudentResponse", className = "com.student.Student")
   
public Future<?> changeStudentAsync(String requestType,AsyncHandler<Student> asyncHandler);

   
@ResponseWrapper(localName = "changeStudentResponse", className = "com.student.Student")
   
public String changeStudent(String name);
}

Implement the Service Interface

Here we implement the service interface created on the previous step

org.apache.cxf.annotations.UseAsyncMethod is available from 2.6.0. By Using @UseAsyncMethod annotation, if the transport supports asynchronous feature, CXF will call the async version that takes an AsynHandler object and the service can call that handler when the response is ready. If the transport does not support the CXF will use the synchronous method as normal.

package com.student;

import java.util.concurrent.Future;

import javax.jws.WebService;
import javax.xml.ws.AsyncHandler;
import javax.xml.ws.Response;

import org.apache.cxf.annotations.UseAsyncMethod;
import org.apache.cxf.jaxws.ServerAsyncResponse;

@WebService(endpointInterface = "com.student.ChangeStudentDetails")
public class ChangeStudentDetailsImpl implements ChangeStudentDetails {

   
// synchronous method, as before
   
@UseAsyncMethod
   
public String changeStudent(String name) {
       
System.out.println("Executing operation changeStudent synchronously\n");
       
return "How are you " + name;
   
}

   
// async callback Method (new method)
   
public Future<?> changeStudentAsync(final String name, final AsyncHandler<Student> asyncHandler) {
       
System.out.println("Executing operation changeStudentAsync asynchronously\n");
       
final ServerAsyncResponse<Student> asyncResponse = new ServerAsyncResponse<Student>();
       
new Thread() {
           
public void run() {
               
try {
                   
Thread.sleep(10000);
               
} catch (InterruptedException e) {
                   
e.printStackTrace();
               
}
               
Student resp = new Student();
                resp.setName
("How are you " + name);
                asyncResponse.set
(resp);
                System.out.println
("Responding on background thread\n");
                asyncHandler.handleResponse
(asyncResponse);
           
}
        }
.start();

       
return asyncResponse;
   
}

   
// async polling Method (new method)
   
public Response<Student> changeStudentAsync(String requestType) {
       
return null;
   
}
}

Create a cxf.xml

CXF is using Spring internally, Finding classes by spring we need to add service implementation class on "jaxws:endpoint" tag

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

    <jaxws:endpoint id="changeStudent"
        implementor="com.student.ChangeStudentDetailsImpl" address="/ChangeStudent" />

</beans>

Change web.xml

Change the web.xml file to find CXF servlet and cxf.xml

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    id="WebApp_ID" version="3.0">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/cxf.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Publishing CXF Web Service

Run CXF On Tomcat

Note

You can Find all the deployed JAX-WS/JAX-RS services you need to append 'services' at the end of the URL so URL will become following

http://localhost:8080/CXFTutorial/services

Deployed CXF Web Service

CXF Asynchronous WebService Running

Note

you can also need CXF Asynchronous client example in order to run this service





4 Responses to "Asynchronous Web Service Using CXF"
  1. sen 2014-03-16 10:02:54.0
  1. globero 2014-03-17 10:02:54.0
  1. admin 2014-03-18 10:02:54.0
  1. Khaled AFI 2014-03-19 10:02:54.0

Your email address will not be published. Required fields are marked *