JAX London 2014: A retrospective
The REST Way!

Building Web Services in Java

SSangeetha
Building-Web-Services-in-Java

A RESTful approach to the Java EE 6 API.

REST – REpresentational State Transfer is an architectural style for accessing information on the web. This is becoming increasingly popular and an easier way to access services on the web. In the REST architecture style, information that is available on the server side is considered as resources and these resources can be accessed in a uniform way using web – Uniform Resource Identifier (URI) and the web protocol, HTTP. Since HTTP is preferred as the protocol for communication, REST constraints the architecture to client-server architecture which is stateless in nature. Resources on the web are identified by URIs. Web Services that are created and accessed using REST principles are called RESTful Web Services.

RESTful Web Services use the methods of HTTP protocol for the operations they perform. HTTP methods POST, GET, PUT and DELETE can be mapped to operations like Create, Read, Update and Delete (CRUD). RESTful Web Services in Java can be built using JAX-RS – Java API for RESTful Web Services which is introduced as part of Java EE 6 Platform and it fully supports REST principles.

JAX-RS – An Introduction

JAX-RS (JSR311) is a Java programming API that is included as part of the new Java EE 6 Platform. JAX-RS is designed to make it easy for developing applications in Java using REST principles / architecture. JAX-RS follows the goals of Java EE – simplicity and ease of development. JAX-RS API uses annotations which makes development of web services using REST architecture simple and easy. Simple POJOs can be exposed as web resources with the help of annotations, classes and interfaces provided by JAX-RS API. Since this depends heavily on annotations, JAX-RS requires Java version 5 and above. JAX-RS applications are bundled in a WAR file similar to any other web application in Java and deployed on a container that supports Servlet. A Servlet provided by the vendor is used for routing the requests to the appropriate web resource. One of the goals of JAX-RS is to make the web resources deployable across different types of web containers achieving portability.

Developing RESTful Web Services using JAX-RS

RESTful Web Services in Java can be created with the help of JAX-RS with any implementation. The classes and interfaces used for creating RESTful web services using JAX-RS are available in the following packages:

• javax.ws.rs

• javax.ws.rs.core

• javax.ws.rs.ext

Resource Class

JAX-RS allows POJOs to expose the functionality as web services through annotations. According to JAX-RS, a ‘Resource’ is a Java class (POJO) which uses JAX-RS annotations to implement a web resource. Annotation @Path is used on a Java class to identify that as a Resource class.

This class is packaged as part of a WAR file with an entry for the Servlet provided by JAX-RS implementation (Jersey for example). Then the WAR file is deployed in the container (Glassfish for example) that provides support for JSR 311. Then the resource is accessed using the normal URI http://hostname:portnumber/WARfilename/stockquote.

This will result in invocation of this class annotated with @Path annotation with a value matching to the corresponding value of the URI.

Life Cycle of Resource Class

A new instance of the resource class will be created for each request to that resource. The life cycle of the resource starts with the creation of object, the constructor is invoked and then the required dependencies are injected. The appropriate resource method is invoked and once the response is provided, the object is made available for garbage collection.

    

Resource Methods

Resource methods are public methods of a ‘Resource‘ class identified with the request method designator annotation. The specification provides a clear mapping to the HTTP protocol and the URI through well defined classes and interfaces. As discussed earlier, in RESTful web services, the HTTP methods are mapped to the CRUD (Create, Read, Update and Delete) operations they perform. Request method designators are annotations that are used to identify the methods that handle the HTTP requests and JAX-RS defines annotations for HTTP methods like GET, POST, PUT, DELETE and HEAD. JAX-RS also allows creating user defined custom request method designators.

The corresponding request method designators are called depending on the HTTP method request. For example, if the request is from a HTTP GET request, method annotated with @GET annotation is automatically invoked and the response is provided. However for HTTP method requests like HEAD and OPTIONS, some amount of automation support is provided. When a HEAD request comes, the method annotated with @HEAD request method designator is invoked, if there is no such request method designator, then by default @GET is invoked without providing any response. However this will have some impact on the performance. The return value of the methods with request designator annotations are generally void, a Java language type or a response object of the type javax.ws.rs.core.Response.

Resource methods can have a set of parameters. Some of these parameters will have annotations and others will not. The method parameters can be annotated with one of the following annotations:

When the method is invoked, appropriate parameters are mapped depending on the semantics of the request. Parameters that are not annotated are called as Entity Parameters whose values are mapped from the request entity body. The specification does not permit more than one entity parameter per method.

As discussed earlier, the return value of a resource method could be void, a response object or any other Java type. For HTTP requests, to map request entity body to method parameters MessageBodyReader class provided by JAX-RS API is used. Similarly, for HTTP response, to map return value to response entity body, MessageBodyWriter is used. These classes take care of the conversion between the Java types and an entity body. Methods that need to return additional type not part of the standard Java type should return an instance of Response object. Resource methods can also throw any checked or unchecked exceptions.

URI Template

As we know, a root resource class is identified using @Path annotation. The value of the annotation can have a relative URI path template mentioned between the curly braces {,} with a reference to the base URI provided by the deployment context. An URI path template acts as a place holder for relative path URI. URI path template generally is a String with zero or more embedded parameters in it. When the values are applied for the parameters forms a valid URI path.

In the following example, the Stock resource class is identified by the relative URI path stock/abc where abc is the value of the symbol parameter. However ‘{‘ and ‘}’ will not appear in the URI as it is not valid, it is used just for the sake of specifying the URI template. The value of the symbol parameter can be retrieved in the method using @PathParam annotation as the parameter value in part of the URI path. URI template parameters can optionally have a regular expression.

Similarly, the parameter annotation @FormParam will be helpful to get the information from the form elements in the request.

Sub Resources

Apart from the Resource class, methods of a resource class can also be annotated with @Path annotation. When the methods are annotated with @Path annotation, the methods are called as sub resource methods or sub resource locators.

Sub Resource Methods

Methods in a resource class that are annotated with @Path annotation along with the request method designator annotation like @GET, @POST, … are called as Sub Resource Methods. The sub resource methods will be invoked for a URI request that is created by concatenating the URI template of the method with the URI template of the resource class.

In the above example, a GET request from the URI /sayHello/lastname will be handled directly by the hello() sub-resource method in the SayHello resource class.

Sub Resource Locators

Methods in a resource class that are annotated with @Path annotation which are used to dynamically identify the object that will handle the request are called as Sub Resource Locators. The return value for these methods is generally an object of resource class that will handle the request. Sub Resource

Locators are similar to normal resource method but cannot have an entity parameter.

MIME Types supported by JAX-RS for Request and Response

MIME media types are used to identify the HTTP request entities and representations. A resource class can produce or consume any MIME type. Annotations are used to specify the MIME media type for request and response on a resource class or a resource method. Annotation @Produces is used to specify the MIME type for the response (representation that can be produced by a resource and sent back to the client) and @Consumes is used to specify the MIME type for the request (representation that a resource can accept from HTTP request entity or consume the content sent by client). For specifying simple ‘text/plain’ MIME, @Produces (“text/plain”) and @Consumes (“text/plain”) will be used.

If the MIME type is HTML, then “text/html” is used as the value for @Produces and @Consumes annotations.

If the value of the annotation @Produces of a resource method is not supported by the HTTP request (if it is not part of the header – Accept in HTTP request), then the resource method will not be invoked. Similarly if the value of the annotation @Consumes of a resource method does not match with the header – Content-Type in HTTP request, the resource method will not be invoked. If these annotations are not present, then any of the MIME types (*/*) is supported.

    

Providers

JAX-RS has providers that help in mapping between entities and associated Java types. These are called as Entity Providers. The two types of Entity Providers supported by JAX-RS are:

1. MessageBodyReader is a class that is used to map HTTP request entity body to method parameters.

2. MessageBodyWriter is a class that is used to map the return value to the HTTP response entity body. By default, there are some types automatically supported by MessageBodyReader and MessageBodyWriter, they are called as standard types. Following are the standard types:

• byte[] – All Media types (*/*)

• java.lang.String – All Media types (*/*)

• java.io.InputStream – All Media types (*/*)

• java.io.Reader – All Media types (*/*)

• java.io.File – All Media types (*/*)

• javax.activation.DataSource – All Media types (*/*)

• javax.xml.transform.Source – For XML Media types only

(text/xml, application/xml, application/*+xml)

• javax.xml.bind.JAXBElement and application supplied JAXB classes – For XML Media types only (text/xml, application/xml, application/*+xml)

• MultivaluedMap<String, String> – Form Content (application/x-www-form-urlencoded)

• StreamingOutput – All Media types (*/*), only for MessageBodyWriter If the application chooses not to use any of the standard types, a method can return an object of Response which is built using ResponseBuilder class.

JAX-RS allows one to write custom mapping from/to representation and entity body. Such classes which would provide custom mapping are annotated with @Provider and implements the MessageBodyReader or MessageBodyWriter classes. Entity Provider is also a resource class annotated with @Provider annotation and implements the JAX-RS API. @Provider annotation can be used along with @Produces and @Consumes annotations as demonstrated below:

The value of the stock parameter will be mapped from the request entity body using the StProvider class. Similarly when a mapping has to be done from the representation to the response entity body, StockProvider class will be used.

Context

To get a handle to the deployment environment and the individual request, JAX-RS provides different types of Context to resource class as well as providers. Annotation @Context is used to get the Java types related to request or response. The different types of Context provided by JAX-RS are:

UriInfo provides information about the components of a request URI. Information about both static and dynamic request URI is provided. However the information provided is valid per request only. An instance of UriInfo is injected to the field of a class or to the parameter of a method using @Context annotation.

• In the above example, Context is used to inject an object of type UriInfo as the method parameter whose methods provide access to request URI information.

• Headers: HttpHeaders provide information about request header. Generally the information is provided in the form of a map. An instance of HttpHeader is injected to the field of a class or to the parameter of a method using @Context annotation. The methods of HttpHeaders provide access to request information.

 

Request: Request interface is provided for content negotiation and evaluating certain preconditions. An instance of request is injected to the field of a class or to the parameter of a method using @Context annotation.

Security: SecurityContext provides information about the security context of the request. With SecurityContext, information about the user, group, and roles can be retrieved from the request and it also helps in identifying the authentication scheme used and whether the request is using https or not. An instance of SecurityContext is injected to the field of a class or to the parameter of a method using @Context annotation.

All the above contexts mentioned are available to all containers where JAX-RS root resource class or a provider is deployed. Apart from these standard ones, @Context annotation can be used to specify container specific resources too. For example, in Servlet Container based environment, @Context can be used to inject dependencies of type HttpServletRequest, HttpServletResponse, ServletConfig and ServletContext.

Frameworks supporting JAX-RS

There are several open source frameworks supporting JAX-RS specification. All of them provide good support for standard server-side JAX-RS APIs and proprietary client APIs. Each one has its own merits and demerits and are used appropriately. Some of them are discussed here:

  • Jersey: JAX-RS applications can be developed in Java using Jersey – an open source production quality reference implementation of JAX-RS from Sun/Oracle. Jersey implements all the APIs and provides annotations for easy and quick creation of web services in Java using REST style. Apart from the defined set of annotations and features defined by JAX-RS, Jersey provides a lot of additional features with its own APIs like Jersey Client API. Jersey is available separately for download as well as coming bundled with NetBeans 6.5 along with Glassfish V3 Prelude. Jersey is built completely using Maven. Jersey provides a good integration with frameworks like Spring MVC.
  • RESTEasy is a JBoss framework for developing RESTful web services which is fully complaint with the JAX-RS specification. RESTEasy has been designed to run in any Servlet Container, but it is preferred with JBoss Application Server because of its tight integration. An important benefit of RESTEasy is apart from providing complete support for JAX-RS server side APIs; it comes with a powerful RESTEasy JAX-RS Client framework which allows mapping of HTTP requests to remote servers and interface proxies. It provides a good integration with other frameworks like Google Guice, Spring and Spring MVC. It is highly preferred when there is a need for integration with JBoss SEAM.
  • Apache CXF is an open source services framework which helps in building web services in Java using both JAX-WS and JAX-RS standards. It supports a variety of protocols ranging from SOAP, REST HTTP and CORBA to transports like JMS, JBI etc. Apache CXF provides a good integration with Spring and JAX-WS services and usage of Maven makes the integration easier. The benefit of Apache CXF is that it provides a pluggable architecture which supports both XML and non XML bindings with any transport.
  • Apache Wink is an open source simple yet powerful framework for building RESTful web services in Java. This framework has been exclusively designed for REST support, unlike Apache CXF which supports both SOAP based and REST based web services. Apache Wink comes with two modules:
  • a) Wink Server – is JAX-RS complaint server side API. Apart from the standard implementation it provides additional facilities for RESTful web services.
  • b) Wink Client – is Java based client framework which helps in consuming RESTful web services. This is extended from HttpURLConnection class available in java.net package.
  • Restlet is a leading (most preferred and matured) open source RESTful web framework for Java which is not JAX-RS complaint. Its simplicity and scalability helps to blend server side web applications, web clients and web services into a uniform web application. There are extensions available to integrate with JAX-RS. The benefit of Restlet comes from its unique Java API available for applications built using different platforms like Java SE, Java EE, Google App Engine, Android and Google Web Toolkit.

Conclusion

JAX-RS provides a good support for building RESTful web services in Java. It is simple and provides an easy approach for exposing POJO as a service and supports different types of representations. JCP has already started working on the next version of JAX-RS – JAX-RS 2.0 where the focus is going to be more on the need for a standardized Client API. Discussions are in place to introduce support for hypermedia, integrate matured open source client frameworks from Apache and introduce architecture – MVC compatible with JAX-RS programming model – JAX-RS MVC. All these makes JAXRS a more promising technology/standard for RESTful Web services in Java.

Acknowledgements

The author would like to sincerely thank Mr. Subrahmanya SV, VP – ECOM Research group for all his encouragements, support and constant motivation. Special thanks to Mr. Nitin KL for quickly reviewing this from the technology perspective.

Author
SSangeetha
S Sangeetha is a Senior Technical Architect at the E-Commerce Research Labs at Infosys technologies. She has over 12 years of experience in architecture, design and development of enterprise Java applications. She is also involved in enhancing the technical skills of Architects at Infosys. She has co-authored a book on
Comments
comments powered by Disqus