<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <dependency> <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> <version>4.0</version> </dependency> <dependency> <groupId>com.google.inject.extensions</groupId> <artifactId>guice-servlet</artifactId> <version>4.0</version> </dependency>
Lean example of Tomcat 8 + Guice 4
TweetPosted on Monday Aug 03, 2015 at 06:56PM in Technology
I prefer Java EE stack usually, but I need to learn a Tomcat based stack for some reasons these days. in this entry, I introduce you a very simple example of Tomcat 8 + Guice 4 app which uses GuiceFilter
and GuiceServletContextListener
so that bring Guice to a Servlet based web application.
The entire project which based on Maven can be obtained from My GitHub repository.
Dependencies
web.xml
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <listener> <listener-class>guice.tomcat.MyGuiceServletConfig</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>
MyGuiceServletConfig.java
We need to declare servlet mappings and the mappings between interfaces and implementations here.
public class MyGuiceServletConfig extends GuiceServletContextListener { @Override protected Injector getInjector() { return Guice.createInjector(new ServletModule() { @Override protected void configureServlets() { serve("/*").with(MyServlet.class); bind(MyService.class).to(MyServiceImpl.class); } }); } }
Service class
We use a pair of a very simple implementation of a service class. it simply creates a greetings which uses an argument.
MyService.java
public interface MyService { String hello(String name); }
MyServiceImpl.java
public class MyServiceImpl implements MyService { @Override public String hello(String name) { return "Hello, " + name; } }
MyServlet.java
Note that we use @javax.inject.Singleton
and @javax.inject.Inject
annotations, that are standardized JSR API.
@javax.inject.Singleton public class MyServlet extends HttpServlet { @javax.inject.Inject private MyService myService; @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().write(myService.hello("Guice")); } }
Test run
After deployment, send a request to check the response:
$ curl http://localhost:8080 Hello, Guice
Other things/functions need to be studied
-
Transaction management
-
CDI Producer equivalent
-
AOP
-
Automatic implementation scanning/binding
This is an excellent bare-bones example showing the base "root level" mapping which seems to work ok, but there is a quirky difference between web.xml's filter-mapping/url-pattern behavior and the GuiceServletContextListener's serve(urlPattern) behavior for non-root-level paths. The JEE pattern matches more actual urls. For example, if the url-pattern were "/someresource/*" it would match "/myresource/metadata" and "/myresource?param1=2" and even "/myresource" but serve("/myresource/*") won't match all of those, and serve("/myresource") won't either. You would need to serve() both patterns to get the same coverage.
Posted by Fred on April 21, 2020 at 09:52 AM JST #