JavaWeb④过滤器、监听器
Java Web 三大组件:Servlet、Filter、Listener
1、过滤器(Filter)
过滤器:客户端与服务器目标资源之间的一道过滤技术。
-
拦截请求,对客户端请求进行过滤处理。
-
封装共性代码,避免重复编码(如设置字符编码、登录验证)
1.1、Filter API
javax.Servlet API 中提供了 Filter 接口
注:三个方法都需要重写。
-
init():初始化,在 Filter 开始之前工作前由 web 容器调用。
-
doFilter():将请求和响应传递给链中的下一个实体。
-
destory():销毁。当调用了过滤器的 doFilter() 的所有线程都退出后,由 web 容器调用。
public interface Filter { default public void init(FilterConfig filterConfig) throws ServletException {} public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException; default public void destroy() {} }
使用
-
创建:实现 Filter 接口
- 在
doFilter()
中编写过滤逻辑 - 调用
chain.doFilter()
放行
- 在
-
配置:配置 Filter 的拦截路径(类似 Servlet 有两种方式)
-
注解:
@WebFilter
-
web.xml:类似 Servlet 配置,
/*
通配<filter> <filter-name>encodeFilter</filter-name> <filter-class>自定义Filter的全限类名</filter-class> </filter> <filter-mapping> <filter-name>encodeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
-
1.2、过滤路径
Filter 过滤路径有 3 种匹配形式
(相比 Servlet,Filter 不能使用
/
通配符)
匹配顺序:精确匹配 > 后缀匹配 > 通配
含义 | 说明 | |
---|---|---|
/具体URL |
精确过滤 | 过滤 指定 URL |
*.xxx |
后缀过滤 | 过滤 xxx 后缀 |
/* |
通配 | 过滤 任意 URL |
1.3、过滤器链、优先级
责任链模式的体现
在客户端和所请求的服务器端资源之间,可能存在多个过滤器。
-
过滤器和服务器端资源形成一条过滤器链。
-
多个过滤器之间,通过
FilterChain.doFilter()
传递请求和响应。
优先级问题
Filter 有两种配置方式:配置文件、注解。
- 基于配置文件:按
filter-mapping
的注册顺序从上往下执行 - 基于注解:按全限类名的字符串顺序决定顺序。
- 配置文件优先级比注解高。
- 同时为一个 Filter 进行配置文件和注解配置,则会注册多个过滤器对象,过滤多次。
1.4、应用
1.4.1、编码问题
抽取 Servlet 中处理请求(响应)编码的逻辑。
@WebFilter("/*")
public class EncodeFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
// init()、destory()
}
1.4.2、用户认证
回顾:状态管理-1.2.4
抽取 Servlet 中判断 Session 的逻辑。
注意:
-
向下转型
doFilter()
中的请求和响应是ServletRequest
和ServletResponse
。- 我们使用是
HttpServletRequest
、HttpServletResponse
、HttpSession
。
-
过滤路径:将涉及用户操作的页面进行拦截,尤其注意不能拦截登录页(否则登录也会被拦截)。
@WebServlet("/user/*") public class AuthenticationFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 向下转型 HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; // 判断 HttpSession session = req.getSession(); User user = (User) session.getAttribute("user"); if (user == null) { resp.sendRedirect("/"); } // 放行 chain.doFilter(req, resp); } // init()、destory() }
2、监听器(Listener)
观察者模式 的体现
监听器:监听对象的技术
- 作用:监听对象的创建和销毁、元素的增删改,自动执行相应功能。
- 监听对象:
application
、session
、request
2.1、Listener API
javax.Servlet API 中提供了 Listener 接口
共有以下 8 种
2.2、配置
Listener 的 2 种配置方式
-
XML 配置
<listener> <listener-class>监听器类</listener-class> </listener>
-
注解:
@WebListener
2.3、使用
以 ServletContextListener 为例,演示监听器
实现 ServletContextListener 接口
-
contextInitialized()
:ServletContext 对象创建时自动执行 -
contextDestroyed()
:ServletContext
对象销毁时自动执行 -
方法参数:被监听的事件。
@WebListener public class MyListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { System.out.println("Initializing..."); } @Override public void contextDestroyed(ServletContextEvent sce) { System.out.println("Destroying..."); } }
测试:启动 Tomcat 服务器
ServletContext 对应一个 Web 应用,Tomcat 服务器启动时创建,服务器关闭时销毁。