Handling different subresources with JAX-RS subresource locator

1 Introduction

In this article I won’t explain what a resource or sub resource is. There are several pages that explain perfectly well its meaning. For example, you can check Oracle tutorial or Jersey documentation. I will focus on implementing a RESTful service with a JAX-RS sub resource locator. This locator will decide at runtime what type of sub resource will be returned.

You can check the source code on my Github repository.

2 Configuration

First of all, you need to include the JAX-RS reference implementation libraries:

The first two dependencies are necessary if you want to develop services, while the third contains the implementation to convert your classes to JSON.

Next step is to define the Jersey servlet that will handle requests to our services. So, include the content below on your web.xml file:

 

I have included two init parameters:

  • com.sun.jersey.config.property.packages: Required. It must define one or more packages separated by “;”. These are the packages where you put your resource classes.
  • com.sun.jersey.api.json.POJOMappingFeature: Activates POJO support, which means that it will use the Jackson library to convert your Java Objects to JSON and the other way back.

We are done with the configuration. Let’s implement the resources.

3 The root resource

To declare a root resource you must annotate your class with @Path:

 

The @GET annotated getWarehouseInfo() method will handle requests to the root resource. So, when the user enters the following URI:

http://localhost:8080/rest-subresources/rest/warehouse

It will return the warehouse information.

Take into account that if I had included the @Path annotation in conjunction with @GET, I would be declaring a sub resource method.

The getItem method is annotated with @Path but not with any request method designator (get, post…). This is because I’m declaring a sub resource locator. This sub resource locator will return an object  that will handle the HTTP request, but which one? It will depend on the id parameter. Both the TypeAResource and TypeBResource implement the same interface ItemResource. So, we can return any of them.

4 Subresources

These sub resources have a method with a request method designator, but no @Path annotation has been included:

The following requests will return a different sub resource:

http://localhost:8080/rest-subresources/rest/warehouse/items/1: Will return a Type B resource:

{“id”:1,”price”:33.5,”type”:”B”}

http://localhost:8080/rest-subresources/rest/warehouse/items/12: Will return a Type A resource:

{“id”:12,”price”:35.5,”type”:”A”,”code”:”12SS34″}

 

5 Possible mistakes

I’m including some errors that may occur if you fail to configure the application properly:

 

Fail on deploy. com.sun.jersey.api.container.ContainerException

The ResourceConfig instance does not contain any root resource classes

You did not define the packages init-param, so it will fail to find nor load your resource classes.

 

Fail on runtime. com.sun.jersey.api.MessageException

A message body writer for Java class [yourModelClass], and Java type class [yourModelClass], and MIME media type application/json was not found.

You did not define the JSON feature on web.xml. It won’t be able to convert your object to JSON:

 

Fail on runtime. com.sun.jersey.api.MessageException

A message body writer for Java class [yourModelClass], and Java type class [yourModelClass], and MIME media type application/json was not found.

This error might also be produced because the JSON maven dependency was not included:

 

Fail on deploy. java.lang.ClassNotFoundException: com.sun.jersey.spi.container.servlet.ServletContainer

The jersey-servlet maven dependency was not included. Older versions of Jersey included this class in jersey-core library, but in newer versions they have put it in a separate jar.

 

Share it:

2 thoughts on “Handling different subresources with JAX-RS subresource locator

Leave a Reply

Your email address will not be published. Required fields are marked *