过滤器Filter
- 什么是Filter?
- 依据字面上的中文意思为过滤器。
- Filter的作用
- 当用户的请求到达指定的URL之前,可以借助Filter来改变这些请求的内容;同样地,当响应结果到达客户端之前,可以使用Filter修改输出的内容。
- 什么是FilterChain(过滤器链)?
- 一个FilterChain包含多个Filter。
Filter编程
过滤器的工作原理
过滤器的生命周期
过滤器的部署
在web.xml中配置如下:
<filter><filter-name>Logger</filter-name><filter-class>com.util.LoggerFilter</filter-class>
</filter><filter-mapping><filter-name>Logger</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
示例:
<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_4_0.xsd" version="4.0"> <!-- 定义Filter --> <filter> <filter-name>exampleFilter</filter-name> <!-- Filter的名称 --> <filter-class>com.example.ExampleFilter</filter-class> <!-- Filter的实现类 --> <!-- 初始化参数(可选) --> <init-param> <param-name>paramName</param-name> <param-value>paramValue</param-value> </init-param> <!-- 其他初始化参数(如果有的话)... --> </filter> <!-- Filter映射 --> <filter-mapping> <filter-name>exampleFilter</filter-name> <!-- 与上面定义的Filter的名称相对应 --> <url-pattern>/*</url-pattern> <!-- 指定Filter应用的URL模式,/* 表示应用于所有请求 --> <!-- 也可以指定多个<url-pattern>,或者使用<servlet-name>来指定应用于哪些Servlet --> <!-- 其他可选属性,如<dispatcher>,可以指定在哪些类型的请求上应用此Filter,如REQUEST、FORWARD、INCLUDE、ERROR等 --> </filter-mapping> <!-- Servlet和其他配置... --> </web-app>
- 在这个例子中,
filter
元素定义了一个名为exampleFilter
的过滤器,其实现类是com.example.ExampleFilter
。- 你可以在这个元素内部添加
<init-param>
元素来定义过滤器的初始化参数,这些参数可以在过滤器的init
方法(如果覆盖了Filter
接口的init(FilterConfig filterConfig)
方法)中通过FilterConfig
对象访问。filter-mapping
元素定义了过滤器的映射信息,即指定了过滤器应该应用于哪些URL模式或Servlet。在这个例子中,<url-pattern>/*</url-pattern>
表示过滤器将应用于Web应用中的所有请求。你也可以通过指定具体的URL模式或Servlet名称来限制过滤器的应用范围。注意:在servlet3.0版本以上,我们可以直接使用注解的方式快速定义一个过滤器
Filter接口
过滤器是一个对象,它根据用户的请求和资源的响应进行过滤.
Filter接口包含以下方法:
FilterConfig
FilterConfig是一个接口,它主要用于在过滤器(Filter)的初始化阶段,从web.xml配置文件中获取与过滤器相关的参数信息。
方法名 | 方法描述 |
---|---|
getInitParameter(String name) | 返回在部署描述符(web.xml)文件中指定名称的初始化参数的值。如果找不到该参数,则返回null。 |
getInitParameterNames() | 返回一个枚举集合,包含过滤器的所有初始化参数的名字。如果过滤器没有初始化参数,则返回一个空的枚举集合。 |
getFilterName() | 返回过滤器在web.xml中声明的名称。 |
getServletContext() | 返回表示Servlet上下文的ServletContext对象的引用。 |
过滤器的应用场合
- 加载:对于到达系统的所有请求,过滤器收集诸如浏览器类型,一天中的时间等相关信息,并对它们进行日志记录
- 性能:过滤器在内容通过线路传来并在到达Servlet和JSP页面之前解压缩该内容,然后再取得响应内容,并在响应内容发送到客户机器之前将它转换为压缩格式
- 安全:过滤器处理身份验证令牌的管理,并适当地限制安全资源的访问,提示用户进行身份验证或将它们指引到第三方进行身份验证.
- 会话管理:将Servlet和JSP页面与会话处理代码混杂在一起可能带来相当大的麻烦.使用过滤器来管理会话可以让WEB页面集中精力考虑内容显示和委托处理,而不必担心会话管理的细节.
Filter经典案例
字符集处理
定义类EncodingFilter实现Filter接口,重写doFilter()方法。
过滤器类
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {//设置请求字符集request.setCharacterEncoding("GBK");//请求向下传递chain.doFilter(request, response);
}
web.xml配置
<filter><filter-name>EncodingFilter</filter-name><filter-class>com.javaweb.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping><filter-name>EncodingFilter</filter-name><!-- 过滤所有请求 --><url-pattern>/*</url-pattern>
</filter-mapping>
登陆验证
解决把登录信息放入session会产生大量重复代码的问题
过滤器类
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpSession session = req.getSession();// 从session中获取用户信息User user = (User) session.getAttribute("user");// 能够从session获取到用户信息,代表用户已经成功登陆过if (user != null) {// 请求向下传递chain.doFilter(request, response);} else {//如果获取不到用户信息,代表用户没有登陆,则转向到登陆页面req.getRequestDispatcher("/login.jsp").forward(request, response);}}
FilterChain过滤链
一个过滤器链(FilterChain),在请求到达请求资源前会依次经过链中的所有过滤器,<filter-mapping>配置在前的Filter先执行,而请求处理完成后,会按照相反的顺序再次经过链中的所有过滤器。
总结
- Filter用于对request或者response进行修改。
- 可以使用Filter处理一些通用的业务操作:
- 字符集编码
- 权限验证
- session管理
- 日志记录
- 响应格式设置