Notes of a (Java) developer

JAX-RS (category)

Software developer Programmer

Java API for RESTful Services (JAX-RS) is defined in three specifications:

The reference implementation is Jersey. These notes largely summarize the documentation. Here we consider JAX-RS development outside of any Java EE application server.

For non-maven developers, dependencies for pure JAX-RS development are limited. The only needed libraries are JARs in the RI bundle lib and api directories.

For a maven project:

<dependency>
    <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.12</version>
</dependency>

To use jersey-specific features, the following dependecies should be specified:

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet</artifactId>
    <version>2.12</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-client</artifactId>
    <version>2.12</version>
</dependency>

TODO concise conf & environment note for JAX-RS dev with Jersey in Java SE env...

Here are some personal notes about JAX-RS components and extensions...

Client API

The RESTful client API is part of the specification since JAX-RS 2.0. The classifiers are defined in the javax.ws.rs.client package. The component implementation is identified in CXF, RestEasty and Jersey.

Since JAX-RS 2.0, as the client API is part of the specification, Jersey does not require any more libraries than the RI bundle lib directory.

Multipart

Multipart does not seem to be covered by the JAX-RS specifications. However, CXF, RestEasy and Jersey provide a non-standard support for such a content-type.

This guide summarizes informations from the Jersey 2.12 documentation.

For a non-maven project, the list of dependencies should be satisfied. To the core, Jersey needs two additional JARs:

For a maven project:

<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-multipart</artifactId>
    <version>2.12</version>
</dependency>

The use is rather simple, e.g. with a file:

@FormDataParam("paramName")
		File f
		

JSON processing with Jersey 2

An experience (first published in the blog - 2014-09-26 - too technical for such a place)...

I tried to use with . Simple use case: turn a JSON server response into POJOs (a Jersey service is client of another RESTful service)...

First step, Jersey installation: for a non-maven project in a Tomcat environment, the list of dependencies should be satisfied in addition to the core framework. The elements can be found in:

For the client code, I followed the Jersey client doc sample. Well, all I got was:

MessageBodyReader not found for media type=application/json

Then, I discovered the following post. Consequently, I added an explicit default constructor. Same error. I read the Jersey-JSON doc again. What a shame:

POJO support represents the easiest way to convert your Java Objects to JSON and back. Media modules that support this approach are MOXy and Jackson

It seems JSONP is not able to provide a simple POJO support. I came back to the basics. All that mess with Jackson, Moxy, JSONP for such simple operations reminds me of an XML nightmare a few years ago...

Jersey 2 Integration with JSP

This guide summarizes informations from the Jersey 2.12 documentation. The MVC and MVC features are extensions.

For a non-maven project, the list of dependencies should be satisfied. The elements can be found in:

For a maven project:

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-mvc-jsp</artifactId>
    <version>2.12</version>
</dependency>

The next step is to specialize the ResourceConfig class and to register the McvFeature and JspMvcFeature classes so that the extensions are loaded (in the constructor). By the way, the JSP pages path has to be specified:

super.register(org.glassfish.jersey.server.mvc.MvcFeature.class)
    .register(org.glassfish.jersey.server.mvc.jsp.JspMvcFeature.class)
    .property(MvcProperties.TEMPLATE_BASE_PATH, "templates");

Finally, jersey has to be registered as a web application. As of 2.12 version, the servlet mapping mode (web.xml or ApplicationPath annotation) is not supported by the MVC extension. Jersey should be deployed as servlet filter. Extract from the doc:

<web-app>
    <filter>
        <filter-name>MyApplication</filter-name>
        <filter-class>org.glassfish.jersey.servlet.ServletContainer</filter-class>
        <init-param>
            ...
        </init-param>
    </filter>
    ...
    <filter-mapping>
        <filter-name>MyApplication</filter-name>
        <url-pattern>/myApp/*</url-pattern>
    </filter-mapping>
    ...
</web-app>

Encoding with Jersey 2

It seems Jersey 2 sets the encoding content type header as ISO-8859-1, even if the content is encoded in UTF-8 and a JSP page directive sets the proper value. The solution is to use a servlet filter to override the behavior. Tomcat provides one out of the box, ready to use (configuration only, no coding).

HTTP 301 status code: Moved Permanently

The JAX-RS API does not expose an out-of-the box method to produce an HTTP 301 response (as available for a temporary redirect - HTTP 307). The solution is to produce a Location header, here is the code (see here for more details):

String redirUri = ...;
    return Response.status(Status.MOVED_PERMANENTLY)
        .header("Location", redirUri).build();
Java Web REST