Java API for RESTful Services (JAX-RS) is defined in three specifications:
- JAX-RS 1.0 (JSR 311, part of Java EE 6, Java SE/EE 5 compliant)
- JAX-RS 1.1 (JSR 311 maintenance release)
- JAX-RS 2.0 (JSR 339, part of Java EE 7, Java SE/EE 6 compliant)
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...
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.
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
An experience (first published in the blog - 2014-09-26 - too technical for such a place)...
For the client code, I followed the Jersey client doc sample. Well, all I got was:
MessageBodyReader not found for media type=application/json
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...
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>
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).
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();