October 31, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Real World REST Using Jersey, AJAX and JSON

  • October 9, 2009
  • By Bob Reselman
  • Send Email »
  • More Articles »

Introduction

REST, Representational State Transfer, is a powerful, lightweight architecture that allows you to work with data in a comprehensive manner via HTTP. Yet, as powerful as REST is, getting it to work with your code can be a bit of a chore without some help. When it comes to coding in Java, Jersey provides the help that you need. Jersey is an open source project that simplifies the work required to adapt your Java code to REST.

In this article I'll give you a lightning fast overview of REST, and explain the basic operational concepts behind Jersey. Then I'll show you how to work with Jersey to make some real world Java code RESTful. Finally I'll show you how to access your RESTful code using browser based JavaScript, AJAX and JSON. As an added topic, I'll show you to inject a Base64 encoded image file onto a web page at run time.

All the code that I use in this article is available for download so that you follow along as you like.

Understanding the Article's Project Code

I am going to teach you the ins and outs of creating a basic Jersey application using a demonstration project. This demo project is named, CardDealer. CardDealer is a web application that renders a random playing card from a server side shoe of playing cards. You display a random playing card by clicking a "Get Card" button on the project's main web page, as shown in Figure 1 below.

CardDealer Web App
Figure 1: The CardDealer Web App uses AJAX to call a REST Service
(click to view)

Although this interaction may seem simple, there is a lot of technology going on underneath the hood. Jersey and AJAX play a key role in the interaction.

Stuff You Need To Know

The intention of this article is to get you up and running on REST using Jersey as quickly as possible. I've use the Maven Framework to organize and build the various Java modules that make up the project. Also, I've used Spring to do runtime injection of property values on a Java helper class that is part of the CardDealer project. And, as mentioned above, I've used AJAX to facilitate communication between the client side browser and the server side CardDealer REST code.

Thus, in order to get full benefit from reading this article, it’s helpful to have a basic understanding of the following technologies:

  • Maven, to define a project's dependencies, build the sample project and run unit tests
  • Spring, to do runtime property injection
  • AJAX, to make a XmlHttpRequest back to a web server
  • JSON, to encapsulate information into a client-side JavaScript object

Yet, if you find yourself needing to brush up on the technologies listed above, don’t fret! This article has a lot of information that you’ll find useful at a conceptual level.

What is REST?

REST is an acronym for Representational State Transfer. REST offers an elegant way to manipulate the HTTP protocol in order to exchange data between computers. The key is the HTTP Request. In the very old days of the Web one thought of using HTTP Requests mostly to get a file from a Web Server.

For example, I'd make an HTML web page that had my profile information on it, store that page as a file, myProfile.html in a directory, BobInfo. Then, others interested in that file would call the URL, http://www.myExampleWebSite.com/BobInfo/myProfile.html. The web server at the other end of the URL would fetch the file and send the file bytes back to the calling computer, either to a browser or some sort of computer based consuming intelligence that can interpret the HTML. Of course, over time things got a lot more complex. Data driven web pages required that web pages be made up on the fly. So, in that more modern world, myProfile.html might not contain HTML that represented my profile information as a hard coded web page. Instead the web server might be configured to interpret HTML files, or more typically, JSP, ASPX or PHP files, as code that contains HTML interspersed with server-side data-driven programming logic to dynamically construct a web page on the fly. Then, the notion of dynamically constructing a page of HTML text gets abandoned altogether. Why not have the web server intelligence create some XML and return that? Why not accept XML as part of an HTTP Request? Why not return a more complex XML structure such as a SOAP message. In the World Wide Web all things are possible. Thus, over time HTTP Requests and HTTP Responses became more complex and unwieldy. And, so it goes... Until REST.

In a REST world things get simpler and a lot more interesting. First and foremost,in REST a URL (or as some purist RESTafarians prefer, a URI) identifies a "thing". You can think of a "thing" as a noun.

For example, a URL, www.CoolCars.com/salesman/reselman/bob can refer to a salesman named Bob Reselman, while another URL, www.CoolCars.com/lenders/contact/reselman/bob can refer to a lender contact named, Bob Reselman. The important thing to understand is that the URL defines a "thing" and that the structure of that definition is defined by the domain being called. (Later on in this article I’ll show you how to use WADL, Web Application Description Language, to determine how to call things in a given REST domain.)

Okay, so REST tells us that URL defines a thing. The question that arises is what can we do with that thing? Well, we can get the thing from the domain; we can add the thing to the domain or we can delete the thing from the domain. How? This is where the use of the HTTP METHOD comes into play.

As mentioned above, REST utilizes the HTTP protocol to do very powerful things in a very simple way. One of the features of the HTTP protocol that REST utilizes extensively is the METHOD field. The most commonly known HTTP methods are GET and POST. In the old days, web developers used the GET and POST value as way for passing some query string and form information to a web server for processing. No biggie.

REST however, takes a much more elegant approach to the use of METHOD fields. REST says, "hey, let's use these methods as they were intended to be used, as directives about the intent of a HTTP Request". Thus, in REST, GET actually means to get some data, PUT means to add data (as does POST), and DELETE means to delete data. There are more HTTP Methods you can use in REST. But, for now let's focus on the basic ones.

So, now you have the basics of REST. REST allows you to define a thing via a URL, and then by setting the METHOD field in the HTTP Request, you can get the thing, add the thing or delete the thing. Of course this means that we are dealing with the HTTP protocol at a lower level than has been usual for most bread and butter web developers. But, once you get the hang of working with essential HTTP, life becomes a lot easier and a lot more powerful.

How does Jersey make REST easier?

So where does Jersey fit in to all of this? Jersey takes care of the lower level HTTP processing referenced above. Jersey provides a way to map a RESTful HTTP Request directly to intelligence in your Java code.

For example, let's say that we have a RESTful URL, http://localhost:9090/card-dealer-rest/rest/card-dealer/card that is sent to a Web server using the HTTP METHOD, GET. Before Jersey came along, in order to process the REST statement we'd do some low level work intercepting the HTTP Request coming into the computer, dissect the URL to determine the thing it represents and then do a whole bunch of programming based on the HTTP METHOD field to create an HTTP Response relevant to the RESTful HTTP Request. This is a lot of work! However, when we use Jersey things get a lot easier.

Please take a look the Jersey enhanced code in Listing 1 below.

Listing 1: Using Jersey annotations to bind a URL to a Java class

01: @Path("/card-dealer")
02: public class CardDealerRest {
03: //Some Java code follows......
04: .
05: .
06:     @GET
07:     @Produces(MediaType.APPLICATION_JSON)
08:     @Path("/card")
09:     public Response getCard(@QueryParam("shoeId") String shoeId) throws IOException, InvalidCardDeckException
10:        {
11:         //Some Java code  for the method follows......
12:         .
13:         .
14:         .
15:         return generateResponse(gson.toJson(rc),
16:                 MediaType.APPLICATION_JSON_TYPE);
17:     }
18:     //Some more Java code follows......
19:     .
20      .
21:     //end of class
22: }

Notice the use of the Java annotation, @Path, in line 01 above the declaration for the class, CardDealerRest. @Path is a Jersey annotation that maps a URL segment to a class and then subsequently to methods within the class. In this case of the use of @Path in line 01 above, /card-dealer, is mapped to the class, CardDealerRest. Thus, any HTTP Request that has a URL base of /card-dealer, will, with the help of Jersey, be routed by the web app to an instance Java class, CardDealerRest.

Also notice that line 08 uses @Path to map the subsequent part of the URL, /card, to the method, getCard(). Thus, using Jersey we've taken a RESTful HTTP Request and bound it to a method in a Java class in order to facilitate server-side behavior.

This is pretty much how Jersey works in terms of mapping a URL to code. In your web.xml you define a URL base as an entry point to which the Web server will pass the HTTP Request to the Jersey servlet. Then you use Jersey @Path annotations to define how the remainder of the URL is to be mapped, first to a class, which in Jersey parlance is called a resource class, and then to a method within the class. Figure 2 below illustrates this concept.

CardDealer Web App
Figure 2: The Jersey @Path annotation maps segments of a URL to a Java class and methods for execution
(click to view)

There are additional Jersey annotations that you use to do things such as declare the mime type that your the methods of the resource will accept, bind an HTTP Request METHOD to a particular method in the resource class and define a return mime type that will be set in HTTP Response.

Table 1 below is an excerpt from the Sun documentation that describes the basic Jersey annotations.

Table 1: The Jersey Annotations

Annotation Description
@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, like this, /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 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 which can be built using Response.ResponseBuilder.

You can find a full JavaDoc description of Jersey annoations here.


Tags: Web services



Page 1 of 4



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel