A couple of years ago, a coworker and I worked on a project that used Jersey, Guice, and Jackson together. At the time, he did all the wiring up of the various bits to make them play nice together. The other day, I wanted to create a new projet for some personal work that used the same stack.
I googled how to setup Guice and Jersey, and I found it surprisingly difficult to actually come up with a working example (besides this one from the incomparable Sonny Gleason). However, Sonny does all his stuff as embedded Jetty in an java application, and I prefer to use war files deployed to a container. So, I went about putting together a simple example, and I’ll pass along the salient points here.
1) you need to tell the servlet to use Guice as the delegate for requests
2) you need to setup Guice to handle the requests
3) profit!!!!
1) convert your web.xml to the following
<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html#d4e194 -->
<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">
<listener>
<listener-class>com.mathew.JerseyServletGuiceModule</listener-class>
</listener>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2) create your Guice servlet module (note the usage of Jackson as the serialization library)
public class JerseyServletGuiceModule extends GuiceServletContextListener{
@Override
protected Injector getInjector() {
return Guice.createInjector(new JerseyServletModule() {
@Override
protected void configureServlets() {
//our persistence layer
bind(PeristenceManager.class).to(PeristenceManagerImpl.class);
//We can bind impls for resources
bind(HandlerA.class).to(HandlerAImpl.class);
//or we can bind the resource directly
bind(HandlerB.class);
/* bind jackson converters for JAXB/JSON serialization */
bind(MessageBodyReader.class).to(JacksonJsonProvider.class);
bind(MessageBodyWriter.class).to(JacksonJsonProvider.class);
// Route all requests through GuiceContainer
serve("/*").with(GuiceContainer.class, ImmutableMap.of(JSONConfiguration.FEATURE_POJO_MAPPING, "true"));
}
});
}
}
Now you can create your handlers (with constructor injection, etc)
public class HanlderAImpl implements HandlerA {
@Context
final UriInfo info;
final PersistenceManager pm;
@Inject
public HandlerAImpl(@Context UriInfo uriInfo, final PersistenceManager pm){
info = uriInfo;
this.pm = pm;
}
@Override
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Result send() {
//Result is just an simple pojo with jackson annotations
return new Result();
}
}