WELCOME Abdennour : Software engineer

May 18, 2012

6. JAX-RS : Develop REST Web Services With Java : Part1


-Java API for RESTful Web Services (JAX-RS), is a set if APIs to developer REST service. 
-JAX-RS is part of the Java EE6, and make developers to develop REST web application easily.

1. JAX-RS Generalities 
2.Java, REST and Jersey:
3.HelloWorld JAX-RS Web Service :
4.Utility of @Produces :
5.RestFul & JAXB :











1.JAX-RS Generalities : 


  * JAX-RS =Java API for RESTful Web Services.
  * based on: POJO classes & Annotations specific to JAX-RS.
  *No XML configuration, except for Servlets JAX-RS
     (this Servlets establish a bridge between HTTP Requests & Java Classes Annotated.)
  *No possibility to develop Web Service from WADL (extended Web Services , we may from WSDL)
  *The WADL description file is automatically generated by JAX-RS
                              (example: http://host/context/application.wadl)

 *JAX-RS Described by the JSR 311 .
*JAX-RS specification does not describe the client layer,

 *Since version 1.1, JAX-RS has been integrated in the specification of Java  EE6. (Server side only).

implementations of JAX-RS:
****
A/JERSEY #: This is the RI (Reference Implementation) provided by Oracle
         with Maven:     # groupId: com.sun.jersey
                                 # ArtifactId: jersey-server
                                   # Version: 1.12
          -If you want to depend on Jersey snapshot versions the following repository needs to be added to the pom:

<repository>
    <id>snapshot-repository.java.net</id>
    <name>Java.net Snapshot Repository for Maven</name>
    <url>https://maven.java.net/content/repositories/snapshots/</url>
    <layout>default</layout>
</repository>
Non-maven develop

B/CXF: provided by Apache => merger of XFire and Celtix
C/ Resteasy: provided by JBoss
D/ Restlet:
****
Description of JAX-RS: 




2.Java, REST and Jersey:


* Via your "web.xml" :
  >>you will register a servlet provided by Jersey and also
  >> define the path under which your REST web application will be available.

* The base URL of this servlet is:

    
http://your_domain:port/display-name/url-pattern/path_from_rest_class
   


Utility of Jersy Servlet(This Servlet) : 
  >> Select the Correct Class according to icoming HTTP Request .


The most important annotations in JAX-RS : 


AnnotationDescription
@PATH(your_path)Sets the path to base URL + /your_path. The base URL is based on your application name, the servlet and the URL pattern from the web.xml" configuration file.
@POSTIndicates that the following method will answer to a HTTP POST request
@GETIndicates that the following method will answer to a HTTP GET request
@PUTIndicates that the following method will answer to a HTTP PUT request
@DELETEIndicates that the following method will answer to a HTTP DELETE request
@Produces( MediaType.TEXT_PLAIN [, more-types ] )@Produces defines which MIME type is delivered by a method annotated with
@GET. In the example text ("text/plain" ) is produced. Other examples would be "application/xml" or "application/json".
@Consumes( type [, more-types ] )@Consumes defines which MIME type is consumed by this method.
@PathParamUsed to inject values from the URL into a method parameter. This way you inject for example the ID of a resource into the method to get the correct object.

 =>The complete path to a resource is therefore based on :
       1) the base URL. 
       2) the @PATh annotation in your class.
    
http://your_domain:port/display-name/url-pattern/path_from_rest_class
   
if @Path(/xxxx) then path_from_rest_class =xxxx

3.HelloWorld JAX-RS WS with Jersy
   1/Required Installation : 
  i.with Maven:

declares “jersey-server” in Maven pom.xml.
File : pom.xml
<project ...>
 
 <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.8</version>
  </dependency>
 
 </dependencies>
 
</project>


ii.without Maven :

http://dl.dropbox.com/u/55765722/delivred/abdennour/java/jersy/lib1.12/jersy_lib1.12.zip
download the file from above URL .and Add Server part to your hello project .
   2/HelloWorld Service : 
Struture of Project :



















Structure of Jersy Project in General : 


Simple REST service with Jersey.
package slm.abdennour.jaxrs.jersy;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;
@Path("/hello")
public class HelloWorldService {
@GET
@Path("/{param}")
public Response getMsg(@PathParam("param") String msg) { 
       String output = "Jersey say : Esselemou 3leikom " + msg;
      return Response.status(200).entity(output).build();
}
}

  3/Required Configuration (web.xml) : 

In web.xml, register “com.sun.jersey.spi.container.servlet.ServletContainer“, and puts your Jersey service folder under “init-param“, “com.sun.jersey.config.property.packages“.
File : web.xml
<web-app id="WebApp_ID" version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
 <display-name>Restful Web Application</display-name>
 
 <servlet>
  <servlet-name>jersey-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>slm.abdennour.jaxrs.jersy</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>jersey-serlvet</servlet-name>
  <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>
 
</web-app>

Test : 



4.Utility of @Produces
Example illustrates the operation of the annotation: @ Produces:

Create the following class.

    
package slm.abdennour.jaxrs.jersy;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

// POJO, no interface no extends
//Sets the path to base URL + /hello
@Path("/hellov2")
public class Hello {

 // This method is called if TEXT_PLAIN is request
 @GET
 @Produces(MediaType.TEXT_PLAIN)
 public String sayPlainTextHello() {
  return "Hello Jersey";
 }

 // This method is called if XML is request
 @GET
 @Produces(MediaType.TEXT_XML)
 public String sayXMLHello() {
  return "<?xml version=\"1.0\"?>" + "<hello> Hello Jersey" + "</hello>";
 }

 // This method is called if HTML is request
 @GET
 @Produces(MediaType.TEXT_HTML)
 public String sayHtmlHello() {
  return "<html> " + "<title>" + "Hello Jersey" + "</title>"
    + "<body><h1>" + "Hello Jersey" + "</body></h1>" + "</html> ";
 }

}
   

  Via the @Produces annotation it defines that it delivers two MIME types, "text" and "HTML" code.
that's means : @Produces defines the  type MIME of Response .


Test your Service : 
under : http://localhost:8080/helloJersyRS2/rest/hellov2
http://localhost:8080/<name_of_project>/rest/hellov2


5.RestFul & JAXB :

5.1. Create project

| /////\\\\\\  Quick Intoduction to JAXB : /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\

|          Java Architecture for XML Binding (JAXB) is a Java standard that defines how Java  |objects are converted from and to XML. It uses a standard set of mappings.
|    => JAXB defines an API for reading and writing Java objects to and from XML |documents.

*JAXB uses annotations to indicate the central elements.
AnnotationDescription
@XmlRootElement(namespace = "namespace")Define the root element for a XML tree
@XmlType(propOrder = { "field2", "field1",.. })Allows to define the order in which the fields are written in the XML file
@XmlElement(name = "neuName")Define the XML element which will be used. Only need to be used if the neuNeu is different then the JavaBeans Name

|/////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ /////\\\\\\ //



Create a new "Dynamic Web Project" "jaxrsJaxb" and copy all jersey jars into the folder "WEB-INF/lib".


Create your domain class.

    
package slm.abdennour.jersey.jaxb.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
// JAX-RS supports an automatic mapping from JAXB annotated class to XML and JSON
// Isn't that cool?
public class Todo {
 private String summary;
 private String description;
 public String getSummary() {
  return summary;
 }
 public void setSummary(String summary) {
  this.summary = summary;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }

 
}

   

Create the following resource class. This class simply return an instance of the Todo class.

    
package slm.abdennour.jersey.jaxb;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import de.vogella.jersey.jaxb.model.Todo;

@Path("/todo")
public class TodoResource {
 // This method is called if XMLis request
 @GET
 @Produces( { MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
 public Todo getXML() {
  Todo todo = new Todo();
  todo.setSummary("This is my first todo");
  todo.setDescription("This is my first todo");
  return todo;
 }
 
 // This can be used to test the integration with the browser
 @GET
 @Produces( { MediaType.TEXT_XML })
 public Todo getHTML() {
  Todo todo = new Todo();
  todo.setSummary("This is my first todo");
  todo.setDescription("This is my first todo");
  return todo;
 }

}

   

Change "web.xml" to the following.

    
<?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>jaxrsJaxb</display-name>
 <servlet>
  <servlet-name>Jersey REST Service</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>slm.abdennour.jersey.jaxb</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 <servlet-mapping>
  <servlet-name>Jersey REST Service</servlet-name>
  <url-pattern>/rest/*</url-pattern>
 </servlet-mapping>
</web-app>
   

Run you web application in Eclipse and validate that you can access your service. Your application should be available under "http://localhost:8080/de.vogella.jersey.jaxb/rest/todo".

5.2. Create a client

Create a new Java "de.vogella.jersey.jaxb.client" and add the jersey jars to the project and the project build path. Create the following test class.

    
package de.vogella.jersey.jaxb.client;


import java.net.URI;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.UriBuilder;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

public class Test {
 public static void main(String[] args) {
  ClientConfig config = new DefaultClientConfig();
  Client client = Client.create(config);
  WebResource service = client.resource(getBaseURI());
  // Get XML
  System.out.println(service.path("rest").path("todo").accept(
    MediaType.TEXT_XML).get(String.class));
  // Get XML for application
  System.out.println(service.path("rest").path("todo").accept(
    MediaType.APPLICATION_JSON).get(String.class));
  // Get JSON for application
  System.out.println(service.path("rest").path("todo").accept(
    MediaType.APPLICATION_XML).get(String.class));
 }

 private static URI getBaseURI() {
  return UriBuilder.fromUri(
    "http://localhost:8080/jaxrsJaxb").build();
 }

}

    

5.3.Result



<?xml version="1.0" encoding="UTF-8" standalone="yes"?><todo><description>This is my first todo</description><summary>This is my first todo</summary></todo>
{"description":"This is my first todo","summary":"This is my first todo"}
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><todo><description>This is my first todo</description><summary>This is my first todo</summary></todo>







Reference : 


1 comment: