Monday, January 5, 2015

An Introduction to Java API for RESTful Web Services (JAX-RS)

Environment
  1. Eclipse Luna Service Release 1 (4.4.1)
  2. JDK 1.7.0_71
  3. Apache Maven 3.2.3 
  4. Tomcat 7


Outline
  • Configure a Maven Web Project in Eclipse
  • Create a REST resource
  • Deploy to Tomcat



Creating the Project


If you have a preferred method for creating Dynamic Web Projects in Eclipse, you may find it simpler to skip directly to the POM (below).

1. Select
File > New > Maven Project



2a. Check Create a simple project (skip archetype selection)

2b. Uncheck Use default Workspace location and enter a suitable path for the project


3. Fill out the required information for a new Maven Project
4. Click Finish


Note: Although we'll change this to WAR later, it's important to keep the packaging as a JAR file in the dialog for now.  This will trigger the configuration event for adding a web.xml file down below.

Configuring the Project


1. Right-Click the Project > Properties > Project Facets
Select the option to convert this project to "faceted form":


2a. Ensure that "Dynamic Web Module 3.0" is selected
2b. Ensure that "Java 1.7" is selected


3. Click the link at the bottom of the dialog that says "Further configuration available".
Check the box that says "Generate web.xml deployment descriptor":
4. Click Ok


Edit the POM


Replace (or merge) the generated POM with the file given below, and then update the Eclipse Project:
Right Click on the Project > Maven > Update Project

Run the Maven Clean Package command from the command line:
mvn clean package -e

My POM file looks like this:
 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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<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/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>

 <groupId>com.mycompany.app</groupId>
 <artifactId>mycompany-app</artifactId>
 <version>1.0.0</version>
 <packaging>war</packaging>

 <url />
 <name>mycompany-app</name>
 <inceptionYear>2015</inceptionYear>
 <description>This is my company's app</description>

 <build>
  <plugins>

   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.5.1</version>
    <inherited>true</inherited>
    <configuration>
     <source>1.7</source>
     <target>1.7</target>
    </configuration>
   </plugin>

   <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>
    <configuration>
     <warSourceDirectory>WebContent</warSourceDirectory>
     <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
   </plugin>

   <!-- Required for Maven-to-Tomcat Deployments -->
   <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
    <configuration>
     <url>http://192.168.1.5:8080/manager/text</url>
     <server>TomcatServer</server>
     <path>/test</path>
     <username>tomcat</username>
     <password>tomcat</password>
    </configuration>
   </plugin>

  </plugins>
 </build>

 <repositories>
  <repository>
   <id>maven2-repository.java.net</id>
   <name>Java.net Repository for Maven</name>
   <url>http://download.java.net/maven/2/</url>
   <layout>default</layout>
  </repository>
 </repositories>

 <dependencies>
  <dependency>
   <groupId>com.sun.jersey</groupId>
   <artifactId>jersey-server</artifactId>
   <version>1.9</version>
  </dependency>
  <dependency>
   <groupId>com.owlike</groupId>
   <artifactId>genson</artifactId>
   <version>1.2</version>
  </dependency>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
  </dependency>
 </dependencies>

</project>
 


POM Overview:

  1. Application Packaging
    1. Must be a Web Application Archive (WAR) file
  2. Tomcat Plugin
    1. The configuration for this plugin, and for the Tomcat server, is detailed in this article.
  3. Additional Dependencies
    1. Jersey and the Genson JSON conversion library.
    2. The Javax Servlet package (optional for this tutorial, but usually necessary when additional code is added).


You should now have an error-free Eclipse Workspace:



Configuring the Deployment Description (web.xml)


If you didn't generate a deployment descriptor when you created the project in Eclipse, add it under this path:
mycompany-app\WebContent\WEB-INF\web.xml


My web.xml file looks like this:
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns="http://java.sun.com/xml/ns/javaee"
 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">

 <display-name>RESTful Web App</display-name>

 <servlet>
  <servlet-name>jersey-helloworld-serlvet</servlet-name>
  <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
  <init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>com.mycompany.app</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>

 <servlet-mapping>
  <servlet-name>jersey-helloworld-serlvet</servlet-name>
  <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>

</web-app>  

You might want to consider modifying the values highlighted in red above.

  1. Jersey Package Configuration value
    1. Specifies the package structure containing the REST resources.
  2. URL pattern
    1. This is a resource mapping



Creating the REST Resource


Outline:
  1. Create a User POJO
  2. Create the REST Service
We'll populate the User POJO with values passed into the REST service, and return the User object as JSON.


The User POJO
 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
38
39
40
41
42
43
 package com.mycompany.app;  
   
 public class User {  
   
      private Integer age;  
   
      private String firstname;  
   
      private String lastname;  
   
      public User() {  
      }  
   
      public User(String firstname, String lastname, Integer age) {  
           setFirstname(firstname);  
           setLastname(lastname);  
           setAge(age);  
      }  
   
      public Integer getAge() {  
           return age;  
      }  
   
      public String getFirstname() {  
           return firstname;  
      }  
   
      public String getLastname() {  
           return lastname;  
      }  
   
      public void setAge(Integer age) {  
           this.age = age;  
      }  
   
      public void setFirstname(String firstname) {  
           this.firstname = firstname;  
      }  
   
      public void setLastname(String lastname) {  
           this.lastname = lastname;  
      }  
 }  


The REST Service
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package org.swtk.sandbox.rest;  
   
 import javax.ws.rs.DefaultValue;  
 import javax.ws.rs.GET;  
 import javax.ws.rs.Path;  
 import javax.ws.rs.Produces;  
 import javax.ws.rs.QueryParam;  
 import javax.ws.rs.core.MediaType;  
   
 @Path("/simpleREST")  
 public class SimpleREST {  
   
      @GET  
      @Path("/user")  
      @Produces(MediaType.APPLICATION_JSON)  
      public User responseMsg(  
                @DefaultValue("john") @QueryParam("firstname") String firstname,  
                @DefaultValue("doe") @QueryParam("lastname") String lastname,  
                @DefaultValue("21") @QueryParam("age") Integer age) {  
   
           return new User(firstname, lastname, age);  
      }  
 }  

In order to construct a URL to test this service, we need these three items:

  1. The Tomcat deployment path from the POM file:  /sandbox-rest
  2. The url-pattern from the servlet-mapping in the web.xml file: /rest
  3. The @Path annotation on the REST class:  /simpleREST
  4. The @Path annotation on the GET method in this class:  /user

We assemble these three together and get:
http://localhost:8080/sandbox-rest/rest/simpleREST/user



Deploying the Resource


Assuming both the POM file and Tomcat are configured correctly, this will be as simple as typing:
mvn tomcat7:deploy -e

To undeploy the web-app, simply type:
mvn tomcat7:undeploy -e

Using this URL
http://localhost:8080/sandbox-rest/rest/simpleREST/user

the web-app returns:



References

  1. Deploying a Web Project with Maven
    1. Describes the POM configuration for automated Maven-to-Tomcat deployments.
  2. [JavaCodeGeeks] Jersey Hello World Example
    1. The first section of my post (using Eclipse to create a Maven Web Project) was based on this tutorial.

No comments:

Post a Comment