Here are instructions and a sample project to help you set up a minimal Guice servlet project without web.xml. The sample project can be found at github.com/remmelt/guice-web-servlet under the minimal-setup tag. Running it is as easy as cloning the repository, mvn package
and deploying the .war
file in the target
directory to a servlet 3.0 application server.
##Dependencies
Let’s start with the pom.xml
. We’ll need the following dependencies:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>3.0</version>
</dependency>
<dependency> <groupId>com.google.inject.extensions</groupId>
<artifactId>guice-servlet</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
##WebListener Next is the web listener. This is where the Guice injector and the ServletModule are created. According to the Guice documentation, the listener is the logical place to configure binding. I have done so on line 10, where I’m binding the MessageSenderImpl implementation to the MessageSender interface.
@WebListener
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule() {
@Override
protected void configureServlets() {
super.configureServlets();
serve("/*").with(WiredServlet.class);
bind(MessageSender.class).to(MessageSenderImpl.class);
}
});
}
}
##WebFilter
Note that you can also add filters in the configureServlets method like this: filter("/*").through(MyFilter.class);
Somehow these filters were not picked up by my webapp, so I created a separate WebFilter-annotated class. See below.
@WebFilter("/*")
public class GuiceWebFilter extends GuiceFilter{
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
super.doFilter(servletRequest, servletResponse, filterChain);
}
}
##The Servlet
I have configured the ServletModule to serve anything "/*"
with the WiredServlet
class.
This class needs to be a singleton.
Of note in this class is the injected MessageSender
service interface. The messageSender
object will get bound by the MessageSenderImpl
class due to the bind(MessageSender.class).to(MessageSenderImpl.class);
line in the WebListener
.
@Singleton
public class WiredServlet extends HttpServlet {
@Inject
private MessageSender messageSender;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getOutputStream().print(messageSender.sendMessage("Hello world!"));
}
}
##Service and implementation Finally we’ll need a service interface and its implementation.
public interface MessageSender {
String sendMessage(String msg);
}
public class MessageSenderImpl implements MessageSender {
@Override
public String sendMessage(String msg) {
return "Message sent: " + msg;
}
}
##Result
Package the project using mvn clean package
from the command line. This will result in a .war
file in the target
directory. Deploy this to any servlet-api 3.0
application server, I’m using Tomcat 7.0.x.
Visit the resulting site, any URL will be picked up by "/*"
.
For Tomcat, try visiting localhost:8080. Any page should display Message sent: Hello world!
The Hello world!
message was “sent” by the bound MessageSenderImpl implementation.
Now start binding parameters!