Spring Cache With CXF Web Service

Spring Cache With CXF Web Service explains step by step details of Creating / Developing Webservices using Apache CXF, Eclipse & Spring Cache

Spring cache is the caching implementation available in spring framework, By using cache we can reduce the response time. we can avail this feature by using spring framework 3.1 or greater.

By using caching technique, we can reduce the method invocation and reduce the response time dramatically, this is because we don't need to query the backend information for each call, but we are caching the information in memory

You can see the below example, which is demonstrate Spring Cache With CXF Web Service

Note

You can also read article about Ehcache With CXF Web Service

Required Libraries

You need to download

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

Following jar must be in classpath (You need to download spring 3.1 or higher separately)

  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. org.springframework.aop-3.1.1.RELEASE.jar
  10. org.springframework.asm-3.1.1.RELEASE.jar
  11. org.springframework.beans-3.1.1.RELEASE.jar
  12. org.springframework.context-3.1.1.RELEASE.jar
  13. org.springframework.core-3.1.1.RELEASE.jar
  14. org.springframework.expression-3.1.1.RELEASE.jar
  15. org.springframework.web-3.1.1.RELEASE.jar
  16. wsdl4j-1.6.2.jar
  17. jaxb-impl-2.2.6.jar
  18. javax.ws.rs-api-2.0-m10.jar
  19. cglib-nodep-2.1_3.jar
  20. jettison-1.3.3.jar (JSON library)

Spring Cache With CXF Web Service

I am creating a sample restful 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 "CXFRestfulTutorial" according to following screenshot

Create CXF Project Spring Cache With CXF Web Service

Create a Student Object

package com.student;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "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 restful service, to be invoked by the client

Here we implement the service interface created on the previous step

Note

Here we are using @Cacheable annotation like below

@Cacheable(value="student", key="#student.name")

value="student" is the cache name specified in cxf.xml

student.name is the property available on Student object, it will be the key

package com.student;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.springframework.cache.annotation.Cacheable;

@Consumes("application/json")
@Produces("application/json")
public class ChangeStudentDetailsImpl{
 
@Cacheable(value="student", key="#student.name")
 
@POST
  @Path
("/changeName")
 
public Student changeName(Student student) {
   
System.out.println("Inside changeName method");
    student.setName
("HELLO " + student.getName());
   
return student;
 
}
}

Create a cxf.xml

You need to add

<cache:annotation-driven />

for working on annotations and also need to specify which cacheManager we are using

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:cache="http://www.springframework.org/schema/cache" xmlns:cxf="http://cxf.apache.org/core"
	xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	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/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
	<import resource="classpath:META-INF/cxf/cxf.xml" />
	<cache:annotation-driven />
	<cxf:bus>
		<cxf:features>
			<cxf:logging />
		</cxf:features>
	</cxf:bus>
	<jaxrs:server address="/rest" id="base">
		<jaxrs:serviceBeans>
			<ref bean="StudentService" />
		</jaxrs:serviceBeans>
	</jaxrs:server>
	<bean class="com.student.ChangeStudentDetailsImpl" id="StudentService" />
	<!-- Spring Cache library setup -->
	<bean class="org.springframework.cache.support.SimpleCacheManager" id="cacheManager">
    <property name="caches">
      <set>
        <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="default" />
        <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="student" />
      </set>
    </property>
  </bean>
</beans>

Change web.xml

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

<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <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 Restful Service

Run Spring Cache With CXF Web Service

Deployed CXF Restful Service

Deploy Spring Cache With CXF Web Service

Now just call "CXF Restful Client" in order to run this restful service

Need to change the code like following on client

URL url = new URL("http://localhost:8080/CXFRestfulTutorial/rest/changeName");

Here I am calling the client twice and showing the result below, From the result you can see that "Inside changeName method" is showing only once, this is because when first request is coming from client response is cached after that Student object is returned from the cache

Output
Aug 29, 2012 3:56:47 AM org.apache.cxf.interceptor.LoggingInInterceptor
INFO: Inbound Message
----------------------------
ID: 2
Address: http://localhost:8080/CXFRestfulTutorial/rest/changeName
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/json
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Length=[26], content-type=[application/json], host=[localhost:8080], user-agent=[Java/1.7.0_03]}
Payload: {"Student":{"name":"Tom"}}
--------------------------------------
Inside changeName method
Aug 29, 2012 3:56:50 AM org.apache.cxf.interceptor.LoggingOutInterceptor
INFO: Outbound Message
---------------------------
ID: 2
Response-Code: 200
Content-Type: application/json
Headers: {Date=[Tue, 28 Aug 2012 22:26:50 GMT]}
Payload: {"Student":{"name":"HELLO Tom"}}
--------------------------------------
Aug 29, 2012 4:05:19 AM org.apache.cxf.interceptor.LoggingInInterceptor
INFO: Inbound Message
----------------------------
ID: 3
Address: http://localhost:8080/CXFRestfulTutorial/rest/changeName
Encoding: ISO-8859-1
Http-Method: POST
Content-Type: application/json
Headers: {Accept=[text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2], connection=[keep-alive], Content-Length=[26], content-type=[application/json], host=[localhost:8080], user-agent=[Java/1.7.0_03]}
Payload: {"Student":{"name":"Tom"}}
--------------------------------------
Aug 29, 2012 4:05:24 AM org.apache.cxf.interceptor.LoggingOutInterceptor
INFO: Outbound Message
---------------------------
ID: 3
Response-Code: 200
Content-Type: application/json
Headers: {Date=[Tue, 28 Aug 2012 22:35:22 GMT]}
Payload: {"Student":{"name":"HELLO Tom"}}
--------------------------------------

 











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