Google

Oct 15, 2012

Restful Web Service Tutorial with Apache CXF

Nowadays, it is more common to work with RESTful Web Service than with SOAP based Web service. This is also a very popular job interview question and I have discussed the reasons at Web Services Interview Questions and Answers. Apache CXF is a popular framework for developing both style Web services. This tutorial extends the "simple Web" Java EE tutorial.

Step 1: You need to bring in the relevant CXF framework JAR files. The transitive dependencies will bring in the other dependent Spring jar files, JAXB jar files, and many other jar files listed in the screenshot below.

Modify the pom.xml file as shown below:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.mytutorial</groupId>
 <artifactId>simpleWeb</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>simpleWeb Maven Webapp</name>
 <url>http://maven.apache.org</url>


 <properties>
  <cxf.version>2.2.3</cxf.version>
 </properties>

 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>

 
  <!-- CXF RESTful Web Service JARS -->
  <dependency>
   <groupId>org.apache.cxf</groupId>
   <artifactId>cxf-rt-frontend-jaxrs</artifactId>
   <version>${cxf.version}</version>
  </dependency>
  

 </dependencies>
 <build>
  <finalName>simpleWeb</finalName>
 </build>
</project>


Now, if you right-mouse-click on simpleWeb,  and select "Maven --> Update Depencies", you can see all the transitively dependent jar files in the "Java Perspective" as shown below.



As you can see, it transitively brings in Spring and JAXB jars in addition to other relevant jars.

Step 2: Define the RESTful Web Service interface and implementation classes with relevant annotations

Interface HelloUserWebService.java

package com.mytutorial.webservice;

import com.mytutorial.pojo.User;

public interface HelloUserWebService {
 //parameter that gets passed via the URL
 User greetUser(String userName);
}


Implementation HelloUserWebServiceImpl.java

package com.mytutorial.webservice;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;

import com.mytutorial.pojo.User;

@Path("userservice/1.0")
@Produces("application/xml")
public class HelloUserWebServiceImpl implements HelloUserWebService {

 @GET
 @Path("/user/{userName}")
 public User greetUser(@PathParam("userName") String userName) {
  User user = new User();
  user.setName(userName);
  return user;
 }

}


Note: The path "userservice/1.0" and  "/user/{userName}" will be used in the URL when invoking the web service. For example, http://localhost:8080/userservices/userservice/1.0/user/John. The "1.0" is the web service version number.

Step 3: Define the "User" bean (or POJO -- Plain Old Java Object) class with the relevant annotations to marshall (i.e. convert object to XML) User object to relevant XML. Generally, these objects can be generated from a XSD file and running it through "xjc" compiler supplied with JAXB. This is demonstrated at "RESTful Web Service Overview".

package com.mytutorial.pojo;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name = "user")
public class User {

 private String name;

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }
}


This will marshal the user object to XML like

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user>
  <name>John</name>
</user>





Step 4: Define the web service endpoint via cxf.xml, which internally uses the Spring framework. Define this under sr/main/resources folder under a package com.mytutorial.webservice.

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
 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">

 <import resource="classpath:META-INF/cxf/cxf.xml" />
 <import resource="classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
 <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />


 <bean id="helloUserWebService" class="com.mytutorial.webservice.HelloUserWebServiceImpl" />

 <jaxrs:server id="userRestfulWebService" address="/userservices/">
  <jaxrs:serviceBeans>
   <ref bean="helloUserWebService" />
  </jaxrs:serviceBeans>
  <jaxrs:extensionMappings>
   <entry key="xml" value="application/xml" />
  </jaxrs:extensionMappings>
 </jaxrs:server>

</beans>


Step 5: Define the web.xml with the CXFServlet and tell where to find the cxf.xml file.

<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_2_5.xsd"
 id="WebApp_ID" version="2.5">

 <display-name>CXF Web Service Application</display-name>

 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>classpath:com/mytutorial/webservice/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>
 </servlet>
 <servlet-mapping>
  <servlet-name>CXFServlet</servlet-name>
  <url-pattern>/*</url-pattern>
 </servlet-mapping>

</web-app>


You should now have the relevant artifacts as shown below.




Step 6: Deploy the simpleWeb.war to the Tomcat server from within eclipse or from outside eclipse as described in the simple web JEE tutorial.


Step 7: Open a wen browser like google chrome, and type the following URL -> http://localhost:8080/simpleWeb/. This will list the RESTful services that are available.

 Click on the wadl (i.e. Web Application Description Language) link to get



Step 8: Finally, invoke the web service via the URL --> http://localhost:8080/simpleWeb/userservices/userservice/1.0/user/John to get an output as shown below. The username supplied is "John". If you are accessing it via a Java application, you can use a framework like Apache HttpClient to make an HTTP call.



Labels:

5 Comments:

Anonymous Anonymous said...

I found this site to be a very useful.. thanks arul for ur time..

8:59 PM, August 20, 2013  
Blogger Unknown said...

how to add multiple services in the cxf.xml

9:07 PM, September 26, 2013  
Blogger shorav said...

Is cxf could be used as a replacment for MOM or Activemq. I have a Restful service API developed with JAX-RS and jersey. I have deployed the same in TOMCAT 7. Now I would like to implement Active Mq so that I would keep all request in a queue and process the api. How to do this and integrate with tomcat7. From this article; I would be able to integrate ActiveMq with Tomcat7. but how to call the service.

5:44 PM, November 01, 2013  
Anonymous Anonymous said...

Where is the User.java ?

4:38 AM, February 20, 2014  
Blogger Unknown said...

Step 3

6:18 PM, October 21, 2014  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home