Exercise 3: Consuming RESTful Web Services using Jersey
Client API (15 minutes)
In this exercise we will see how to consume a RESTful
web service using the Jersey Client API. We will see how
easily we can send requests to a service and get back
a response.
We will create a Java Swing
Application, which will consume the jerseyservice
we created in the previous exercise. Using this application we will be able
to list the system properties, and update/add/delete a particular property.
In the previous exercise we have seen how
to create a RESTful Web Service using maven. To show how you can use Jersey
without Maven, in this exercise we will download the required Jersey jars
manually and use them in an ant-based project.
Steps to Follow
In order to save some time, the lab provides a pre-built skeleton application,
which already contains all of the UI components. The only thing we will be adding
during this lab is the business logic. We will start by opening this pre-built project
and walking through its structure a bit.
- From the NetBeans IDE, open
jerseyclient project located in
<lab_root>/restwebservice/exercises/exercise3.
- What got opened is a simple ant-based project implementing a Swing UI.

The com.mycompany.jerseyclient package has three classes:
MainWindow - Implements the main window of the application
containing a list box for listing all the properties and buttons to perform
operations on the properties.

EditPropWindow - Implements a dialog window used to
display/gather user input for a particular property.

DataProvider - A simple class containing methods that
should perform the actual operations of retrieving, updating and deleting
the properties - the UI components delegate to these methods - so this
class is the only one we will need to touch.
All these classes are reasonably documented, so you can browse through their
code to find out more.
- Let's run the application to get a better idea of how it looks like by
right-clicking on "jerseyclient" in the Projects tab and clicking on Run.
- The main window will appear. To get list of all properties, the main window
calls
DataProvider.getPropertyNames() method, which currently always
returns hard-coded values - property1, property2 and property3. The same call
is made when you click on Refresh button.
- Click on New button - the
EditPropWindow dialog will appear.
You can enter some name and value. Upon clicking OK, a call to
DataProvider.setPropertyValue() is made passing the property name
and value you entered. Currently this method does nothing. The application also
does a refresh (by calling DataProvider.getPropertyNames()
to update the list box content).
- Select a property from the list and click on Edit button. The same dialog
will appear but this time the property name field is read-only. To get the
current value of the selected property, the application calls
DataProvider.getPropertyValue() passing the property name.
This method currently always returns "dummy". Once user changes the value
in the dialog and clicks OK, the application calls
DataProvider.setPropertyValue() and does a refresh.
- Select a property from the list and click Delete. Application asks if you
are sure - after clicking OK it calls
DataProvider.deleteProperty()
(which currently does nothing) and does a refresh.
- Exit the application by closing the main window.
Before we start properly implementing methods of the DataProvider class,
we need to make sure we have the required Jersey jar files on the classpath.
Every release of Jersey provides a snapshot of
the dependencies page
showing which libraries you need to depend on when using certain features of Jersey.
For developers not using maven, it provides links for downloading the JAR files directly.
We will use the Jersey Client API. To unmarshall the data from XML we will
use JAXB (similarly to using it in jerseyservice for
marshalling to XML/JSON). As a result, we will need the following jar files for this exercise:
- jersey-bundle-*.jar - core Jersey classes
- jsr311-api-*.jar - JAX-RS API
- jaxb-api-2.1.jar - (needed for JDK5 only) JAXB API
- jaxb-impl-2.1.10.jar - (needed for JDK5 only) implementation of JAXB API
- activation-*.jar - (needed for JDK5 only) JAXB dependency
- stax-api-*.jar - (needed for JDK5 only) JAXB dependency
- wstx-asl-*.jar - (needed for JDK5 only) JAXB dependency
For your convenience, the needed files can be found in lib
directory under the root of jerseyclient project.
Let's add them to the classpath of our project:
- Right-click on the Libraries node under the
jerseyclient project
and choose "Add JAR/Folder..."

- In the Add JAR/Folder dialog browse to <lab_root>/restwebservice/exercises/exercise3/jerseyclient/lib
directory, select all jars in it and click OK.

NOTE: As mentioned above, only jersey-bundle and jsr311-api jars
are needed when running on JDK6. Please add all jars as suggested in case you are
not sure which version of JDK you are running on.
Now we can finally get to the main topic of this exercise. We will use the
Jersey Client API to properly implement methods of the DataProvider
class.
- Open the
DataProvider class for editing by double-clicking on it
in the Projects tab.
- Jersey Client API defines
WebResource class that makes it
easy to invoke operations on web resources (such as PropertiesResource
we developed in the previous exercise). Let's declare a static variable
of type WebResource we will use to access the properties resource:
private static WebResource propsResource = Client.create().resource(
"http://localhost:8080/jerseyservice/webresources/properties");
- Now, before we start implementing the individual methods, let's copy
the
PropertyBean class from the jerseyservice project
we developed in the previous exercise by right-clicking on it in the Projects tab,
choosing Copy from the pop-up menu and then right-clicking on com.mycompany.jerseyclient
package, choosing Paste->Refactor Copy and clicking Refactor in the Copy Class dialog.
We will use this class for representing a single property. Since it is a JAXB bean,
Jersey will be able to automatically unmarshall XML in server responses into
its instances.
- Get back to the
DataProvider class and replace getPropertyNames()
method implementation with the following:
List<PropertyBean> properties = propsResource.accept("application/xml")
.get(new GenericType<List<PropertyBean>>() {});
String[] propNames = new String[properties.size()];
int i = 0;
for (PropertyBean property : properties) {
propNames[i] = property.getName();
i++;
}
return propNames;
The call to the REST service is on the first line of this code. We are using
the accept() method of WebResource class to indicate
what media types our client accepts and then issue an HTTP GET request by
calling get() method on the resource. We are indicating what
type the response should be unmarshalled into by passing an instance of
GenericType representing List<PropertyBean>.
This ensures Jersey will try to process the server response using an
appropriate reader (in this case JAXB)
to construct a result of the requested type - so we can assign the returned
result directly to a variable of List<PropertyBean>.
The rest of the code is just constructing an array of property names from
the list of property beans.
- Besides the
get() method, WebResource defines
methods corresponding to the remaining HTTP methods - most importantly put()
and delete(). We can get to a particular sub-resource by calling
path() method on a resource. So now it should be straightforward
how to implement the remaining methods of DataProvider. Replace
the deleteProperty() implementation with the following:
propsResource.path(propertyName).delete();
- Replacing
getPropertyValue() should also be straightforward:
PropertyBean property = propsResource.path(propertyName)
.accept("application/xml").get(PropertyBean.class);
return property.getValue();
- And finally the code for
setPropertyValue() method:
propsResource.path(propertyName).put(propertyValue);
- The whole class should look as follows:
package com.mycompany.jerseyclient;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import java.util.List;
public class DataProvider {
private static WebResource propsResource = Client.create().resource(
"http://localhost:8080/jerseyservice/webresources/properties");
public static void setPropertyValue(String propertyName, String propertyValue) {
propsResource.path(propertyName).put(propertyValue);
}
public static String getPropertyValue(String propertyName) {
PropertyBean property = propsResource.path(propertyName)
.accept("application/xml").get(PropertyBean.class);
return property.getValue();
}
public static void deleteProperty(String propertyName) {
propsResource.path(propertyName).delete();
}
public static String[] getPropertyNames() {
List<PropertyBean> properties = propsResource.accept("application/xml")
.get(new GenericType<List<PropertyBean>>() {});
String[] propNames = new String[properties.size()];
int i = 0;
for (PropertyBean property : properties) {
propNames[i] = property.getName();
i++;
}
return propNames;
}
}
- Now we are done - run the application.
TROUBLESHOOTING: If the application does not work,
check if GlassFish V2 is running and that jerseyservice application has been deployed.
- Add a new property named "aaa". After clicking OK in the property dialog,
you should see the property added in the list.
- Try changing the value of the property by selecting it and clicking Edit. The
next time you select the property and click Edit you should see the new value.
- Delete the property by clicking Delete. After confirming, observe the property
is no longer in the list.
- You can play by modifying the properties from the web browser and from the
Swing client simultaneously.
NOTE: Don't modify or delete any of the existing properties.
Play only with the ones you added.
This concludes the third exercise.
Summary
In this exercise, you saw how the Jersey Client API could be used to consume a RESTful Web Service. You have seen how to:
- Get a handle to a web resource.
- Build request to a web resource using the
path() method.
- Send HTTP requests using the
get() , put() and delete() methods.
- Specify the mime-type in which you want to get the response to a request, using the
accept() method.
Back to top
To summary