Java学习笔记-Day57 过滤器
一、简介
在Web应用中,如果对服务器端的多个资源(Servlet、JSP)有通用的处理,可以在每个资源中写相同的代码,而这样做显然过于冗余,修改时就需要逐一修改,效率低下。过滤器可以解决这样的问题:把通用的、相同的处理代码用过滤器实现,然后在web.xml或@注解中将过滤器配置给相关的资源使用即可。
多个过滤器同时过滤称为一个过滤链(Filter chain)。编码过滤器可以设置请求和响应的编码格式,权限过滤器可以用于判断用户是否拥有访问的权限。
二、过滤器的开发和配置
1、过滤器的开发
过滤器类的 java 文件放在 Filter 包中。在Tomcat启动时就会实例化过滤器。
Filter接口中有三个方法:
方法声明 | 方法描述 |
---|---|
void init(FilterConfig filterConfig) | 容器初始化过滤器对象后调用该方法,其中参数可以获取过滤器配置信息; |
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | 过滤器的服务方法,有三个参数,其中FilterChain中也定义了名字为doFilter方法,不过只有两个参数,可以把当前的请求和响应沿着过滤链进行传递; |
void destroy() | 容器销毁过滤器对象前进行调用; |
过滤器的开发步骤:
(1)创建一个自定义类,该类实现Filter接口。
(2)实现接口中的doFilter方法(destroy和init方法都是default方法,所以实现接口只需要关注doFilter方法即可)。
(3)使用 web.xml 或者是注解来配置过滤器对哪些URL有效。
- 编码过滤器(设置请求和响应的编码格式)
package com.etc.bs.filter;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* 编码过滤器
*/
@WebFilter(dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.ERROR
}
, urlPatterns = {
"/*" })
public class EncodingFilter implements Filter {
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("EncodingFilter doFilter方法");
// 设置请求编码格式
request.setCharacterEncoding("utf-8");
// 设置响应编码格式
response.setCharacterEncoding("utf-8");
// 继续执行下一个过滤器(一定要有这行代码)
chain.doFilter(request, response);
}
}
- 权限过滤器(判断用户是否拥有访问的权限)
package com.etc.bs.filter;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter(dispatcherTypes = {
DispatcherType.REQUEST,
DispatcherType.FORWARD,
DispatcherType.INCLUDE,
DispatcherType.ERROR
},urlPatterns= {
"/sitebackground/*"})
public class AccessFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse res = (HttpServletResponse)response;
if(req.getSession().getAttribute("user") == null) {
res.sendRedirect("login.jsp");
}
chain.doFilter(request, response);
}
}
注意:在doFilter方法中要有这行代码:chain.doFilter(request, response);
2、过滤器的配置
方法1: Web.xml中配置了过滤器设置:
方法2:使用@WebFilter注解来配置过滤器。
(1) dispatcherTypes:过滤器对这些URL生效时的访问方式。
- DispatcherType.REQUEST : 直接URL访问、响应重定向、超级链接、表单提交、静态包含。
- DispatcherType.FORWARD:请求转发。
- DispatcherType.INCLUDE:动态包含
<jsp:include>
。 - DispatcherType.ERROR:错误页面跳转。
(2)urlPatterns :过滤器对哪些URL生效。
-
路径映射:以”/”开头和以”/*”结尾的是用来做路径映射的。
urlPatterns = {"/*"}
:根目录下所有请求。 -
扩展映射:以前缀”*.”开头的是用来做扩展映射(带指定后缀的)。
urlPatterns = {"*.do"}
:以do结尾的请求做过滤。 -
default servlet映射:“/” 是用来定义default servlet映射的。
-
详细映射:
urlPatterns = {"/ts.do"}
,明确到具体某个url的请求。 -
特例:
urlPatterns = {"/*.do"}
不能这样写,因为这个匹配即属于路径映射,也属于扩展映射,导致容器无法判断。