Saturday, October 5, 2013

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 AnswersApache 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:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 4.0.0
 com.mytutorial
 simpleWeb
 war
 1.0-SNAPSHOT
 simpleWeb Maven Webapp
 http://maven.apache.org
 
 
 
  2.2.3
 
 
 
  
   junit
   junit
   3.8.1
   test
  
 
  
  
  
   org.apache.cxf
   cxf-rt-frontend-jaxrs
   ${cxf.version}
  
   
 
 
 
  simpleWeb
 

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

?
1
2
3
4
5
6
7
8
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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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".

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

?
1
2
3
4
"1.0" encoding="UTF-8" standalone="yes"?>
  John


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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 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">
 
 "classpath:META-INF/cxf/cxf.xml" />
 "classpath:META-INF/cxf/cxf-extension-jaxrs-binding.xml" />
 "classpath:META-INF/cxf/cxf-servlet.xml" />
 
 
 "helloUserWebService" class="com.mytutorial.webservice.HelloUserWebServiceImpl" />
 
 "userRestfulWebService" address="/userservices/">
  
   <ref bean="helloUserWebService" />
  
  
   "xml" value="application/xml" />
  
 
 


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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 id="WebApp_ID" version="2.5">
 
 CXF Web Service Application
 
 
  contextConfigLocation
  classpath:com/mytutorial/webservice/cxf.xml
 
 
  class>org.springframework.web.context.ContextLoaderListenerclass>
 
 
  CXFServlet
  class>org.apache.cxf.transport.servlet.CXFServletclass>
 
 
  CXFServlet
  /*
 
 


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 likeApache HttpClient to make an HTTP call.



No comments: