Technology Insights
How to Easily Build REST Web-Services With Java, Spring and Apache CXF
By Christophe Levesque / September 25, 2011
As an integration platform for Web applications, AppDirect relies heavily on APIs and Web-Services. That's why when we designed our architecture, we looked for technologies that are open and flexible, while sticking to the golden KISS principle. We found that exposing CRUD (Create, Read, Update and Delete) operations through RESTful Web-Services was a great choice with these requirements. In this article, we're going to show how easy it is to implement this type of Web-Services on a Java stack with the Spring Framework and Apache CXF.
To keep this article short and sweet, we're going to start from the point where you have a working JEE web app running with Spring (3.0.5) configured.
Configure Spring and CXF
First, we need to do a little configuration to integrate CXF in our Spring application. CXF implements JAX-RS (JSR-311), which is what we are going to use. We need to add the CXF dependency to our project. The Maven dependencies are:
<dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-frontend-jaxrs</artifactId> <version>2.4.2</version> </dependency> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-rt-transports-http</artifactId> <version>2.4.2</version> </dependency>
To hook up Spring and CXF we create a Spring XML called applicationContext-cxf.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:jaxrs="http://cxf.apache.org/jaxrs" xmlns:http-conf="http://cxf.apache.org/transports/http/configuration" xsi:schemaLocation=" 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://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd "> <import resource="classpath:META-INF/cxf/cxf.xml" /> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <jaxrs:server id="restContainer" address="/"> <jaxrs:serviceBeans> <!-- This is where we tell which beans CXF should expose as Web-Services --> </jaxrs:serviceBeans> </jaxrs:server> </beans>
Finally, we update our web.xml to define the servlet that will process the requests to our Web-Service and map it to the "/api/" path (for example):
<servlet> <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>/api/*</url-pattern> </servlet-mapping>
Whew! This was the hard part! Luckily this is only done once. We can now focus on creating actual functionality.
Defining the business logic
For the sake of this example, we're going to expose CRUD operations on an entity called "User". We're defining the User object as a simple POJO:
public class User { private String uuid; private String email; private String firstName; private String lastName; <getters and setters> }
The interface to manage that data should look something like that:
public interface public interface UserService { public User create(User user); public User read(String uuid); public void update(String uuid, User user); public void delete(String uuid); }
and the class implementing that logic like:
@Service("userService") // Use Spring IoC to create and manage this bean. public class UserServiceImpl { public User create(User user) { // Some logic... } public User read(String uuid) { // Some logic... } public void update(String uuid, User user) { // Some logic... } public void delete(String uuid) { // Some logic... } }
Nothing fancy here. Just some basic Java code... Now get ready for some magic!
Expose the business logic as a Web-Service
This is where things get interesting. We are going expose the business logic created above as REST Web-Services without writing any extra code, by sprinkling a few Java annotations on the classes we already have. To be as flexible as possible, we want our Web-Services to be able to consume and produce data in XML as well JSON. CXF supports both out of the box, and, in a lot of cases, all you need to do is add the @XmlRootElement annotation on your User class declaration:
@XmlRootElement(name = "user") public class User { // Same code as before... }
With this, instances of the User class can be serialized to / deserialized from:
XML:
<user> <uuid>550e8400-e29b-41d4-a716-446655440000</uuid> <email>christophe.levesque@...com</email> <firstName>Christophe<firstName> <lastName>Levesque</lastName> </user>
or JSON:
{ "uuid": "550e8400-e29b-41d4-a716-446655440000", "email": "christophe.levesque@...com", "firstName": "Christophe", "lastName": "Levesque" }
We can now use the JAX-RS annotations on the interface we created earlier to declare our Web-Services:
@Path("v1") public interface UserService { @POST @Path("users") @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public User create(User user); @GET @Path("users/{uuid}") @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public User read(@PathParam("uuid") String uuid); @PUT @Path("users/{uuid}") @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public void update(@PathParam("uuid") String uuid, User user); @DELETE @Path("users/{uuid}") @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) public void delete(@PathParam("uuid") String uuid); }
These annotations map URL paths and HTTP verbs (GET, POST...) to the methods we created.
Reference: http://cxf.apache.org/docs/jax-rs-basics.html
Last bit of configuration is to add our Spring bean "userService" to the list of CXF service beans in applicationContext-cxf.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans ...> ... <jaxrs:server id="restContainer" address="/"> <jaxrs:serviceBeans> <ref bean="userService" /> </jaxrs:serviceBeans> </jaxrs:server> </beans>
And voila! You have now implemented a set of RESTful Web-Services to manage users. You can create a user by POSTing XML or JSON to http://yourhost/api/v1/users, read info about a user at http://yourhost/api/v1/users/550e8400-e29b-41d4-a716-446655440000, etc. CXF will automatically detect which media type to use from the "Accept" or "Content-Type" header of your HTTP request. More advanced topic notes:
- You can configure CXF to use other (de)serializers than the packages ones (like the excellent Jackson JSON processor) or implement your own
- You can map exceptions thrown by your API to particular HTTP status codes (403, 404, 500...) using beans implementing javax.ws.rs.ext.ExceptionMapper
- You can (and should) configure CXF to secure your APIs (start with http://cxf.apache.org/docs/secure-jax-rs-services.html)
- You can also easily implement clients for RESTful Web-Services using org.apache.cxf.jaxrs.client.JAXRSClientFactory
Related Articles

Technology Insights
10 Ways AppDirect.AI Enhances Advisor Efficiency
Unlock advisor efficiency with AppDirect.AI: Elevate collaboration, tap into specialized capabilities, and craft custom AI bots. Explore the AppDirect AI Marketplace and discover how to create AI that learns from your own data sets.By Ideas @ AppDirect / AppDirect / November 22, 2023

Technology Insights
Is Predictability Overrated? The Case for a ‘Chaos Engineering’ Game Day
From chaos comes order: Check out the surprising benefits of our ‘chaos engineering’ game day. Plus, tips for you applying them to your organization.By Juan Ramollino / AppDirect / April 13, 2023

Technology Insights
6 Ways Quality Drives Product Development at AppDirect
Discover the cross-company culture and processes that ensure AppDirect SaaS products meet the highest quality standards available—including a quality-driven software development lifecycle and continuous development and deployment.By Ideas @ AppDirect / AppDirect / November 30, 2022