Search code examples
javaguiceservlet-filters

ServletModule.filter versus @WebFilter


I'm trying to follow a minimal tutorial on using Guice for a web server, without needing a web.xml: http://www.remmelt.com/post/minimal-guice-servlet-without-web-xml/

Like the creator of the tutorial, I cannot manage to make the ServletModule filter command work as expected, but all of the same code, instead using the @WebFilter attribute on the Filter class results in a working web server.

How do I make the ServletModule filter work? What is the difference between ServletModule's filter method and the @WebFilter attribute that lead to this difference in expectations?

Beyond what is covered in the tutorial, I have also tried to bind the filter before the "filter" command.

@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);
                filter("/*").through(GuiceWebFilter.class);
                bind(MessageSender.class).to(MessageSenderImpl.class);
            }
        });
    }
}

public class GuiceWebFilter extends GuiceFilter{
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        super.doFilter(servletRequest, servletResponse, filterChain);
    }
}

@Singleton
public class WiredServlet extends HttpServlet {
    @Inject
    private MessageSender messageSender;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getOutputStream().print("Hello world!");
    }
}

Using the @WebFilter("/*"), I get a simple response of "Hello World!".

Using the filter("/*"), I instead get a 404 on the same request.


Solution

  • As far as I can tell, what I'm looking for is impossible. In order to have a Filter declared without the @WebFilter attribute, you must have a web.xml like this:

    <!DOCTYPE web-app PUBLIC
            "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
            "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app id="WebApp_ID" version="2.4"
             xmlns="http://java.sun.com/xml/ns/j2ee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
        http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
        <display-name>Application</display-name>
    
        <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>
    

    So all in all, you can either use @WebFilter attribute, or you must have a web.xml, there is no way to avoid both for more easily readable configuration.