javajettyguiceembedded-jettyguice-servlet

Using Guice Servlet with Jetty to map paths to servlets without using a web.xml


I am struggling with getting Guice Servlet working to configure how Jetty serves web requests, in this simple case, for static pages.

I have created a simple application that is supposed to map two different requests, one using GuiceServlet, another not. The latter works, while the GuiceServlet mapped one returns a 404 error.

Any tips? I am using: JDK 1.7.0_15; eclipse.jetty.jetty-servlet 8.1.9.v20130131; guice-servlet 3.0. Thanks.

public class Main {
    public static void main(String... args) {
        Guice.createInjector().getInstance(Main.class).start();
    }

    public void start() {
        Server server = new Server(8080);
        ServletContextHandler handler = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
        handler.addEventListener(new MyGuiceServletConfig());
        handler.addServlet(MyServlet.class, "/non-guice");
        server.setHandler(handler);
        try {
            server.start();
            server.join();
        } catch (Exception e) {
            e.printStackTrace();
        }       
    }
}

public class MyGuiceServletConfig extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new ServletModule() {
            @Override
            protected void configureServlets() {
                System.out.println("MyGSC->getInjector->configureServlets"); //I'm seeing this in the console...
                serve("/guice").with(MyServlet.class);
            }
        });
    }
}

@Singleton
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.getWriter().print("Hello!\nYour path is: " + request.getServletPath());        
    }
}

Beyond this, what's the best way to create the various injectors? I have the main(..) structured like so, so that I can plug in other Modules, leaving the MyServletModule to be specified in MyGuiceServletConfig as I saw somewhere - is this correct?


Solution

  • I ended up being able to this much simpler, in a way that works. Adding a DefaultServlet for the "/" path was necessary:

    public class MyMain {
        public static void main(String... args) throws Exception {
            Guice.createInjector(new MyServletModule());
            Server server = new Server(8080);    
            ServletContextHandler handler = 
                new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
            handler.addFilter(GuiceFilter.class, "/*", allOf(DispatcherType.class));
            handler.addServlet(DefaultServlet.class, "/");
            server.start();
        }
    }
    
    @Singleton
    public class MyServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            response.getWriter().print("Hello!\nYour path is: " + request.getServletPath());        
        }
    }
    
    public class MyServletModule extends ServletModule {
        @Override
        protected void configureServlets() {
            serve("/guice").with(MyServlet.class);
        }
    }