<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 #