Sunday, July 28, 2013

Java's REST Jersey 2.x examples

Jersey updated to 2.0 (JAX-RS 2.0), but most of the examples on the internet are for Jersey 1.x.  There are a few changes, none are that big, but here are some examples of serving and requesting (client) Jersey 2.0.

First, grab the Jersey jars from here: http://jersey.java.net/download.html - I got the Jersey JAX-RS 2.1 RI bundle  which contains what I needed.  Next, as I'm working in Eclipse, I created a Dynamic Web Project (right click in package explorer area -> Other Project -> Web -> Dynamic Web Project) and called it DynamicWebP. 

Extract the jars from the bundle and copy them into the project's WebContent/WEB-INF/lib directory. Also, add them to the project build path (right click on the project -> build path -> add external libraries).  For these examples, only javax.ws.rs-api-2.0.jar and jersey-container-servlet-core.jar are needed on the build path, but it's easier to add them all.  For deployment, all/nearly all are needed so it's easier to add them from the start to the WEB-INF/lib directory.  (If you have problems with some of the jars added to build path, but not to WEB-INF/lib, because you didn't copy them, then go to project properties, deployment, add and add the jars needed for deployment.)

Server
Now, add a class to the project - here I've put it in a package I called example.jersey and named the class Hello. This class is a simple servlet to greet a request. Note the @Path to specify the path off the root in web.xml (shown next), the @GET for the HTTP verb that a method will respond to, and the @Produces for the media type to produce (there's also @Consumes for the media type to expect in the request).

 package example.jersey;  
 import javax.ws.rs.*;  
 import javax.ws.rs.core.MediaType;  
 @Path("/hello")  
 public class Hello {  
      @GET  
      @Produces(MediaType.TEXT_PLAIN)     // nature of MIME type  
      public String simpleStringResponse() {  
           return "hello from the text response of Hello";  
      }  
      @GET  
      @Produces(MediaType.TEXT_HTML) // nature of MIME type  
      public String simpleHTMLResponse() {  
           return "<html> <title> Simple RESTful Hello</title> "  
                     + "<body><h2>Hello from the html response of class Hello :)</h2></body></html>";  
      }  
 }  

Here is the web.xml to update (in WEB-INF).  One noticeable change from Jersey 1.x to 2.0 is the classes to be referenced in servlet-class and param-name:
     org.glassfish.jersey.servlet.ServletContainer 
and 
   jersey.config.server.provider.packages
respectively.
As expected, note the url-pattern path (relates to the url needed to find the resource) and param-value (relates to the class package) as that will be important to checking the result.

 <?xml version="1.0" encoding="UTF-8"?>  
 <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>SomeAppDisplayName</display-name>  
  <welcome-file-list>  
   <welcome-file>index.html</welcome-file>  
  </welcome-file-list>  
  <servlet>  
  <servlet-name>HelloServlet</servlet-name>  
    <servlet-class>  
     org.glassfish.jersey.servlet.ServletContainer  
   </servlet-class>  
   <init-param>  
     <param-name>jersey.config.server.provider.packages</param-name>  
     <param-value>example.jersey</param-value>  
   </init-param>  
   <load-on-startup>1</load-on-startup>  
 </servlet>  
 <servlet-mapping>  
   <servlet-name>HelloServlet</servlet-name>  
   <url-pattern>/jersey_test/*</url-pattern>  
 </servlet-mapping>  
 </web-app>  
With that configured, right click on the project (assuming in Eclipse still) and click Run As -> Run on Server to launch the app on a configured server (tomcat).  Then go to the url: http://localhost:8080/DynamicWebP/jersey_test/hello - if you use a browser (instead of curl), the response should be:

      Hello from the html response of class Hello :)

Client
Now, add a REST Jersey client by using the same project and the following JerseyClient class in the package client.jersey.

 package client.jersey;  
 import javax.ws.rs.client.*;  
 import org.glassfish.jersey.client.filter.CsrfProtectionFilter;  
 public class JerseyClient {  
       public static void main(String[] args) {  
            Client restClient = ClientBuilder.newClient();  
            //restClient.register(new CsrfProtectionFilter()); //register a filter, here a predefined one  
            WebTarget target = restClient.target("http://jersey.java.net//");  
           // target.register(new CsrfProtectionFilter());//or register on a target  
            WebTarget resourceTarget = target.path("download.html"); //change the URI without affecting a root URI  
            String responseString = resourceTarget.request("text/plain").get(String.class);  
            System.out.println("Here is the response: "+responseString);  
       }  
 }  

Note the separation of higher web targets (urls) from lower ones - you can set filters and paths at various levels.  The commented out code is just to illustrate the setting of filters at two levels.
(More info and examples on the simple setup of a client are here: https://jersey.java.net/documentation/latest/user-guide.html#client.)

To run the example, right click on the JerseyClient.java file in Eclipse and Run As -> Java Application to invoke the main(...) in the class.  Your console output should be the html text from the Jersey download page.

That's it - client and server side. We could make it more exciting by using query parameters and doing a recursive call to each class (you'd need to make some changes) until a value is reached like a predetermined limit (or something crashes :)

No comments:

Post a Comment