An Example of Using Jersey RESTful Web Services, Java, Ajax, and JavaScript
Introduction
In my previous article I introduced how to use Jersey, the Java API for JAX-RS, to create a RESTful web service and then call the methods of the web service from a web page. I also explained how to configure the application in Eclipse, Maven, and Tomcat.
In this article I'll introduce how to use a RESTful web service to interact with a Java model class to provide the state of an object or collection of objects to the view and how to use Ajax to call the RESTful web service.
Example Application
I created a simple online RSVP application. The web page has a form where you enter your name and a radio button to check if your attending or not attending the party. The page shows who has already RSVP'd and will add your RSVP to the list when you submit the form.
The web page uses Prototype's library of Ajax functions to make requests to the RESTful web service. There are two basic requests the client makes. One is a HTTP get request to get an XML response that contains an rsvp XML node for everyone who has previously RSVP'd. The XML is created automatically by the web service converting a collection of RSVP objects to an XML document.
The other request the client makes is an HTTP post request with a body of a single rsvp XML node. This request will cause the web service to convert the XML to a Java object of class RSVP and then add that RSVP to the collection of RSVP objects.
You can download an archived Eclipse - Maven project here. See the previous article for my Eclipse - Maven - Tomcat development environment and how to import an archived Eclipse project. Also see the previous article for how to run a project on the Tomcat server or in the command window using Maven. You can view a working example here.
Model Class
This simple web application has one model class: RSVP. This class is designed to store a person's name and whether or not he is attending the party. The one item to note for this class is the @XmlRootElement annotation.
@XmlRootElement
public class RSVP {
...
}
The XmlRootElement is a JAXB annotation that will map a class to an XML element. JAXB is the Java Architecture for XML Binding. JAXB is a Java API that can marshal and unmarshall a Java object to XML and XML to a Java object. This simple annotation will allow our RESTful web service to easily convert RSVP objects to XML and XML to RSVP objects.
The RESTful Web Service
The single RESTful web service is class RSVPResource found in the services package. I'm going to cover those annotations that weren't discussed in the first article. Below is the first part of the RSVPResources class.
@Produces("application/xml")
@Path("rsvpservices")
@Singleton
public class RSVPResource {
...
}
The @Singleton annotation means the Jersey runtime will create a single instance of the RSVPResources class for all requests. For this application that is the desired behavior since all requests will share the same collection of RSVPs that are stored in a class instance field.
The getRSVPs method shown below will process HTTP get requests to the RESTful web service.
@GET
public List<RSVP> getRSVPs() {
List<RSVP> rsvps = new ArrayList<RSVP>();
rsvps.addAll(rsvpMap.values());
return rsvps;
} //end method getRSVPs
This method will be called when the URL includes the path services/rsvpservices (note the web.xml defined all RESTful web services to be called via the url-pattern /services/*). Recall from the first article that the @Path annotation used above will determine the path that needs to be in the URL in order to call this web service.
The @Produces annotation at the beginning of the class specifies that all methods will return XML data. Therefore the getRSVPs return value (rsvps), which is a Java List object, will be converted to an XML document containing a root node of RSVPs and a rsvp child node for every RSVP object stored in the rsvps List. The JAXB API will automatically marshal the RSVP objects into the XML document. The client calling this method will receive back an XML document.
The addRSVP method shown below will process HTTP post requests to the RESTful web service.
@POST
@Path("add")
@Produces("text/html")
@Consumes("application/xml")
public String addRSVP(RSVP rsvp) {
int id = rsvpMap.size();
rsvp.setId(id);
rsvpMap.put(id, rsvp);
return "RSVP received. " + rsvp.toString();
}//end method addRSVP
The above method is called using the path services/rsvpservices/add. Notice that the @Consumes annotation states that this web service method can consume XML. So the browser can send an XML rsvp node and JAXB will convert the node into the RSVP object the method parameter requires.
So as described above the RSVPResource RESTful web service provides two services to a user: a way to get all the RSVPs as an XML document and a way to add an RSVP to the collection maintained by the class.
Client Interaction With The RESTful Web Service
When the browser completes loading the HTML client, it calls the JavaScript function getRSVPs(). This JavaScript function makes an Ajax call to the RESTful web service to get an XML response that includes a rsvp node for all RSVPs previously received.
To call the RESTful web service I'm using the Ajax object from the Prototype JavaScript library. Prototype provides a easy-to-use wrapper around using JavaScript's XmlHttpRequest object. You don't have to worry about browser differences as Prototype's Ajax object handles all of that. You can learn more about Prototype's Ajax object here.
The XML response is processed by the client (see JavaScript function getRSVPs) and a div tag in the HTML document is updated with the processed XML.
Add An RSVP
In the HTML client of this application--index.html--the user can enter his or her name and check a radio button to indicated if he/she is attending the party. When the user clicks on the RSVP submit button the following JavaScript function is called.
function addRSVP() {
var name = $('name').getValue();
var attending = $('attending').getValue();
//create XML node
var rsvpXML = "<rsvp><name>" + name + "</name><attending>" + attending + "</attending></rsvp>" ;
//alert("XML: " + rsvpXML);
ajaxAddRSVP(rsvpXML);
}
The JavaScript function takes the form values and creates an rsvp XML node. Note that the child nodes name and attending match the RSVP model objects public setName and setAttending methods. This JavaScript function then calls another function named ajaxAddRSVP, passing it the XML node.
Function ajaxAddRSVP again uses the Prototype Ajax object to make an Ajax call to the web service.
function ajaxAddRSVP( rsvpXML) {
new Ajax.Request('/RSVPApp/services/rsvpservices/add',
{
method:'post',
postBody:rsvpXML,
contentType:'application/XML', ...
}
Note that the HTTP method specified is post and the URL includes the path /services/rsvpservices/add. This will cause the addRSVP method of class RSVPResource to process this request. The postBody attribute above is set to rsvpXML which is storing the rsvp XML node created in function addRSVP. As I noted earlier, the rsvp XML node will be converted automatically into an RSVP object by the web service and JAXB.
The response from the web service's addRSVP method is processed by the browser by displaying it in a JavaScript alert window. The JavaScript then calls function getRSVPs() to get the latest list of RSVPs from the web service and update the div tag displaying those RSVPs.
Summary
The use of JavaScript and Ajax on the client side provides a way for the browser to interact with our RESTful web service. The client can easily send requests to the web service and process the XML responses.
On the back end, our RESTful web service can interact with a Java RSVP model object and a collection of those RSVP objects. Of course, in a production application you need to store the RSVP objects in some type of permanent storage repository. Since the RESTful web service class, RSVPResource, is a standard Java class it can easily communicate with other Java classes that are using common Java APIs for data storage (for example Java Persistence API [JPA]).
References
- Example Application - Archived Eclipse - Maven Project
- Example Application On bpjava.net
- An Introduction to Creating RESTful Web Services Using Jersey and Java, Bruce Phillips Blog
- JAX-RS, the Java API for RESTful web services
- jsr311-api 1.0 API
- Jersey, Sun's Reference Implementation for JAX-RS
- RESTful Web Services Developer's Guide, Sun MicroSystems
- Using JAX-RS (Jersey) to build a JPA/JAXB-backed JSON REST API, java rants blog
- Prototype JavaScript Library
There are no comments for this entry.
[Add Comment]