Listener 监听器

Listener 监听器是 Java EE 的三大组件之一。Java Web 的三大组件分别是 Servlet 程序,Filter 过滤器,Listener 监听器。Listener 是一个接口,只要实现这个接口,就获得了一个监听器

ServletContextListener 监听 ServletContext

首先编写一个类去实现 ServletContextListener 接口,编写监听到某个事件之后的需要执行的代码。

1
2
3
4
5
6
7
8
9
10
11
12
public class Listener implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContext is initialized!");
}

@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContext is destroyed!");
}
}

然后再 web.xml 中像配置 Servlet 一样去配置一个 Listener:

1
2
3
<listener>
<listener-class>space.xorex.BookStore.Listener.Listener</listener-class>
</listener>

然后当我们启动 Tomcat 成功之后,就可以捕捉到了 ServletContext 的初始化事件,然后交给 contextInitialized() 方法去处理。

Filter 过滤器

Filter 概述

对于非 Servlet 的资源请求,对非法请求进行拒绝只能依靠 Filter 来实现。Filter 过滤器的作用就是对请求进行过滤,所有请求在被处理之前,都会被交给 Filter。Filter 有权决定当前请求是否被继续传递下去(下一个 Filter 或者目标资源)。

Filter 建立

首先需要一个 Java 程序来对请求进行过滤处理,这里需要继承 Filter 接口,实现里面定义的几个方法,其中最重要的就是 doFilter() 方法,在访问目标资源之前会执行这个方法。

1
2
3
4
5
6
7
8
9
10
11
12
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest req=(HttpServletRequest)servletRequest;
String userName=(String)(req.getSession().getAttribute("userName"));
if(userName==null) {
req.getRequestDispatcher("/index.jsp").forward(servletRequest, servletResponse); //没有登录
} else if(userName.equals("Xorex")) {
filterChain.doFilter(servletRequest, servletResponse); //确认权限足够
} else {
req.getRequestDispatcher("/index.jsp").forward(servletRequest, servletResponse); //权限不足
}
}

然后需要在 web.xml 文件中加入对 Filter 的一个映射,用来确定在访问那里的资源的时候使用此过滤器。

1
2
3
4
5
6
7
8
<filter>
<filter-name>ManagerFilter</filter-name>
<filter-class>space.xorex.BookStore.filter.ManagerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ManagerFilter</filter-name>
<url-pattern>/pages/manager/*</url-pattern> <!-- 这里 * 表示任意字符匹配 -->
</filter-mapping>

然后就可以过滤非管理员对 manager 下面资源的访问了。

Filter 生命周期

  1. 首先执行 Filter 的构造方法。

  2. 然后执行 Filter 的 init() 方法。

  3. 遇到符合要求的过滤请求的时候,执行 doFilter() 方法。

  4. 服务器结束的时候执行 destroy() 方法。

Filter 运行过程

仔细看过上面的图之后,需要注意的是在 chain.doFilter() 执行交给下一个过滤器或者目标资源之后,还会像递归一样回来的,这里可以对资源的响应进行二次确认。还需要注意 FilterChain 的构造方法,在 web.xml 中按照合理的顺序声明 Filter 程序即可。

FilterConfig 类

可以直接在 Filter 中使用方法 filterConfig 获取一个 FilterConfig 对象实例,然后用方法 getInitParameter() 来获取在 web.xml 中设置的 Filter 初始化参数 <init-param>