Guice 之 Servlet

简介

Guice对于Servlet有很好的支持,可以在Guice的容器中维护Servlet,替代web.xml和注解配置。此文章只关注Guice的Servlet内容,如果对Guice本身还不是很了解请先参看其它介绍Guice文章。

配置

Maven配置

在使用Guice Servlet 之前首先配置guice-servlet.jar依赖

1
2
3
4
5
6
7
8
9
10
<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>

配置GuiceFilter

GuiceFilter 负责对Guice中Servlet请求路由,对请求进行分发。在web.xml 中进行配置。

1
2
3
4
5
6
7
8
<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>

创建ServletModule

Guice通过ServletModule维护Servlet,创建ServletModule的示例代码如下:

1
Guice.createInjector(new ServletModule());

创建ServletModule的时机

对于Web项目可以系统启动的时候创建ServletModule,可以使用Listener的方式进行创建。Guice Servlet提供了一个GuiceServletContextListener,在项目中可以直接使用。

1
2
3
4
5
6
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule());
}
}

在web.xml中配置该listener

1
2
3
<listener>
<listener-class>com.up.GuiceServletConfig</listener-class>
</listener>

绑定Servlet

ServletModule 使用起来和web.xml配置类似,可以看做是web.xml 配置的API模式

1
2
3
4
5
6
7
Guice.createInjector(..., new ServletModule() {
@Override
protected void configureServlets() {
serve("/*").with(MyServlet.class);
filter("/*").through(MyFilter.class);
}
}

以上的配置等价于以下web.xml配置

1
2
3
4
5
6
7
8
<servlet>
<servlet-name>MyFilter</servlet-name>
<servlet-class>com.up.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyFilter</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

注入Servlet相关对象,除了配置Servlet之外,Guice还允许我们把Request、Response和Session对象注入到非Servlet对象中。下面是Guice的一个例子。

1
2
3
4
5
6
7
8
@RequestScoped
class SomeNonServletPojo {

@Inject
SomeNonServletPojo(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
...
}
}

我们还可以使用Guice注入请求参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
@RequestScoped
public class Information {
@Inject
@RequestParameters
Map<String, String[]> params;

public String getAllParameters() {
return params.entrySet()
.stream()
.map(entry -> entry.getKey() + " : " + Arrays.toString(entry.getValue()))
.collect(Collectors.joining(", "));
}
}

之后,我们就可以将该对象注入到Servlet中使用,将结果返回给页面。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Singleton
public class MainServlet extends HttpServlet {
@Inject
private Injector injector;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String name = req.getParameter("name");
req.setAttribute("name", name);
Information info = injector.getInstance(Information.class);
req.setAttribute("params", info.getAllParameters());
req.getRequestDispatcher("index.jsp").forward(req, resp);
}

@Override
public void init() throws ServletException {
super.init();
}

}

参考Guice官方文档