blogger templates blogger widgets
This is part of a list of blog posts.
To browse the contents go to

JAX-RS: Basics and Sample App


Create a dynamic web project with JAX-RS support. I used RAD with Websphere implementation of JAX-RS.

Define a resource class

You need to define at least one root resource class.

Root resource classes are POJOs that are either annotated with @Path or have at least one method annotated with @Path or a request method designator, such as @GET, @PUT, @POST, or @DELETE.

Annotations Used:

@Path
The @Path annotation’s value is a relative URI path indicating where the Java class will be hosted: for example, /helloworld. You can also embed variables in the URIs to make a URI path template. For example, you could ask for the name of a user and pass it to the application as a variable in the URI: /helloworld/{username}.

@GET
The @GET annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP GET requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@POST
The @POST annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP POST requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@PUT
The @PUT annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP PUT requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@DELETE
The @DELETE annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP DELETE requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@HEAD
The @HEAD annotation is a request method designator and corresponds to the similarly named HTTP method. The Java method annotated with this request method designator will process HTTP HEAD requests. The behavior of a resource is determined by the HTTP method to which the resource is responding.

@PathParam
The @PathParam annotation is a type of parameter that you can extract for use in your resource class. URI path parameters are extracted from the request URI, and the parameter names correspond to the URI path template variable names specified in the @Path class-level annotation.

@QueryParam
The @QueryParam annotation is a type of parameter that you can extract for use in your resource class. Query parameters are extracted from the request URI query parameters.

@Consumes
The @Consumes annotation is used to specify the MIME media types of representations a resource can consume that were sent by the client.

@Produces
The @Produces annotation is used to specify the MIME media types of representations a resource can produce and send back to the client: for example, "text/plain".

@Provider
The @Provider annotation is used for anything that is of interest to the JAX-RS runtime, such as MessageBodyReader and MessageBodyWriter. For HTTP requests, the MessageBodyReader is used to map an HTTP request entity body to method parameters. On the response side, a return value is mapped to an HTTP response entity body by using a MessageBodyWriter. If the application needs to supply additional metadata, such as HTTP headers or a different status code, a method can return a Response that wraps the entity and that can be built using Response.ResponseBuilder.

package com.test;

import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
// The Java class will be hosted at the URI path /hello
// and based on the methods defined it supports GET 
@Path("/hello")
public class HelloResource {
    @GET
    @Produces("text/plain")
    public String helloGet() {
        return "[GET] Hello from JAX-RS on WebSphere Application server";
    }
}

Now this needs to be deployed as a REST application.
This could be done in 2 ways:

1. Application subclass
Define a class that extends javax.ws.rs.core.Application to define the components of a RESTful Web service application deployment and provide additional metadata.

package com.test;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
 
@ApplicationPath("/HelloApp")
public class HelloApplication extends Application {
 /*
  * An "empty" (no methods overriden) implementation of javax.ws.rs.core.Application tells the 
  * runtime environment that the service resources are packaged in the web archive (WAR) 
  * and should be scanned for at deployment. 
  *
/// @Override
// public Set<Class<?>> getClasses() {
//  Set<Class<?>> resources = new java.util.HashSet();
//  resources.add(HelloResource.class);
//  return resources;
// }
}

Within the Application subclass, override the getClasses() and getSingletons() methods, as required, to return the list of RESTful Web service resources. A resource is bound to the Application subclass that returns it.
Note that an error is returned if both methods return the same resource.


2. Servlet

Update the web.xml deployment descriptor to configure the servlet and mappings. The method used depends on whether your Web application is using Servlet 3.0 or earlier.
For Servlets 3.0,
If you are using RAD, then you will probably already have this configuration in web.xml.

<servlet>
 <description>JAX-RS Tools Generated - Do not modify</description>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <servlet-class>com.ibm.websphere.jaxrs.server.IBMRestServlet</servlet-class>
 <load-on-startup>1</load-on-startup>
 <enabled>true</enabled>
 <async-supported>false</async-supported>
</servlet>
<servlet-mapping>
 <servlet-name>JAX-RS Servlet</servlet-name>
 <url-pattern>
 /jaxrs/*</url-pattern>
</servlet-mapping>

For pre-Servlets 3.0 look here

Deploy and test

Your rest urls are defined as,
http://[your_hostname]:[your web_container_port=""]/[context_root_of_web_app]/[mapping_pattern]/[resource_uri]

In our case,
http://localhost:9080/RSServer/HelloApp/hello

Test it using a client. The one used here is Advanced-Rest-Client chrome extension.


The information sent to a resource and then passed back to the client is specified as a MIME media type in the headers of an HTTP request or response.
You can specify which MIME media types of representations a resource can respond to or produce by using the following annotations:
@Consumes = javax.ws.rs.Consumes
@Produces = javax.ws.rs.Produces
Though these are optional for most of the cases it's highly recommended.


JAX-RS Client

Since WAS REST implementation is based on Apache Wink you could use Wink API to write your client.

By default, the Apache Wink client uses the java.net.HttpURLConnection class from the Java runtime environment for issuing requests and processing responses. The Apache Wink client can also use Apache HttpClient 4.0 as the underlying client transport.

To implement an Apache Wink REST client, you must first create an org.apache.wink.client.ClientConfig object that is then used to construct an org.apache.wink.client.RestClient. You can change the configuration settings for the ClientConfig object programmatically, or you can use JVM properties to modify the default ClientConfig object values.

ClientConfig object is used to set readTimeout, connectTimeout and to configure Entity providers. ClientConfig object is not mandatory.

You can also use JAX-RS entity providers to help serialize request entities or deserialize response entities.

I created a web application and called the JAX-RS service from one of it's servlets.

String lsUrl = "http://localhost:9080/RSServer/HelloApp/hello";
RestClient client = new RestClient(); //construct a new RestClient using the default client configuration
Resource resource = client.resource(lsUrl);
ClientResponse result = resource.contentType(MediaType.TEXT_PLAIN).get();
System.out.println(result.getEntity(String.class));
//or if the response entity type is known
String result = resource.contentType(MediaType.TEXT_PLAIN).get(String.class);
System.out.println(result);

More info about Wink clients here


1 comment: