There has been some confusion on StackOverflow lately about how to register JAX-RS resource classes and custom providers in Jersey 2. The main problem seemed to be finding and using correct properties and methods to configure a JAX-RS/Jersey application. In this article I’d like to discuss 3 ways how to configure such an application properly.
Biggest difference between Jersey 1 and Jersey 2 in this regard is used namespace. Jersey 1 uses prefix
com.sun.jersey
(even for property names) which is not true for the namespace of Jersey 2 that starts withorg.glassfish.jersey
. Besides that Jersey 2 does NOT support properties from Jersey 1 and you need to use specific ones (from Jersey 2) to make things work.
Let’s assume I am working on a Jersey 2 application and I already have some resource classes and providers. What I want to do is to register my custom ContainerRequestFilter called SecurityRequestFilter
that is responsible for setting correct SecurityContext for incoming requests. Since I am still developing my application I’d also like to see and log communication (incl. request/response entity) between client/server and be able to trace my requests if needed. For logging purposes I can use proprietary filter from Jersey called LoggingFilter. As mentioned I’d like to log the entity as well so I need to provide an instance of this filter created using the following constructor: LoggingFilter. Tracing support can be turned on by setting special property called ServerProperties.TRACING.
You can find a lot of other useful properties in *Properties classes like:
To register my providers I can use one of these approaches:
Application (JAX-RS)
Application defines the components of a JAX-RS application and supplies additional meta-data. With this approach you’re supposed to register everything (resource classes, providers, properties) the application will need:
@ApplicationPath("/")
public class MyApplication extends ResourceConfig {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>();
// Register my custom provider.
classes.add(SecurityRequestFilter.class);
// Register resources.
classes.add(...);
return classes;
}
@Override
public Set<Object> getSingletons() {
final Set<Object> singletons = new HashSet<Object>();
// Register an instance of LoggingFilter.
singletons.add(new LoggingFilter(LOGGER, true));
return singletons;
}
@Override
public Map<String, Object> getProperties() {
final Map<String, Object> properties = new HashMap<String, Object>();
// Enable Tracing support.
properties.put(ServerProperties.TRACING, "ALL");
return properties;
}
}
ResourceConfig (Jersey specific)
ResourceConfig is itself an extension of JAX-RS Application class but it provides some convenience methods to make registering resources and providers more friendly:
@ApplicationPath("/")
public class MyApplication extends ResourceConfig {
public MyApplication() {
// Register resources and providers using package-scanning.
packages("my.package");
// Register my custom provider - not needed if it's in my.package.
register(SecurityRequestFilter.class);
// Register an instance of LoggingFilter.
register(new LoggingFilter(LOGGER, true));
// Enable Tracing support.
property(ServerProperties.TRACING, "ALL");
}
}
web.xml (JAX-RS & Jersey specific)
Web application descriptor allows you to define JAX-RS Application (JAX-RS spec) for non Servlet 3.0 apps (you can use it with Servlet 3.0 as well but in Servlet 3.0 it’s enough to have an Application subclass on your class-path) or define contex-param
/init-param
for package-scanning, properties, …
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>my.package.MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- Register JAX-RS Application, if needed. -->
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>my.package.MyApplication</param-value>
</init-param>
<!-- Register resources and providers under my.package. -->
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>my.package</param-value>
</init-param>
<!-- Register my custom provider (not needed if it's in my.package) AND LoggingFilter. -->
<init-param>
<param-name>jersey.config.server.provider.classnames</param-name>
<param-value>my.package.SecurityRequestFilter;org.glassfish.jersey.filter.LoggingFilter</param-value>
</init-param>
<!-- Enable Tracing support. -->
<init-param>
<param-name>jersey.config.server.tracing</param-name>
<param-value>ALL</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>my.package.MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>