Servlet高级-Filter过滤器
一、Filter接口
1.1、概念
Filter被称为过滤器,Filter基本功能就是对Servlet容器调用Servlet的过程进行拦截,它位于客户端和处理程序之间,能够对请求和响应进行检查和修改。Filter就好比现实中的污水净化设备,专门用于过滤污水杂质。Filter在Web应用中的拦截过程如下图所示。
上图中展示了Filter在Web应用中的拦截过程,当客户端对服务器资源发出请求时,服务器会根据过滤规则进行检查,如果客户的请求满足过滤规则,则对客户请求进行拦截,对请求头和请求数据进行检查或修改,并依次通过过滤器链,最后把过滤之后的请求交给处理程序。请求信息在过滤器链中可以被修改,也可以根据客户端的请求条件不将请求发往处理程序。
1.2、作用
拦截请求,实现一些特殊的功能
完成一些通用的功能,比如:权限控制,统一字符编码、敏感字符处理等。
1.3、常用方法
方法声明 | 功能描述 |
---|---|
init(FilterConfig filterConfig) | init()方法是Filter的初始化方法,创建Filter实例后将调用init()方法。该方法的参数filterConfig用于读取Filter的初始化参数。 |
doFilter(ServletRequest request,ServletResponse response,FilterChain chain) | doFilter()方法完成实际的过滤操作,当客户的请求满足过滤规则时,Servlet容器将调用过滤器的doFilter()方法完成实际的过滤操作。doFilter()方法有多个参数,其中,参数request和response为Web服务器或Filter链中的上一个Filter传递过来的请求和响应对象;参数chain代表当前Filter链的对象。 |
destroy() | 该方法用于释放被Filter对象打开的资源,例如关闭数据库和 IO流。destroy()方法在Web服务器释放Filter对象之前被调用。 |
1.4、生命周期
创建阶段–init()
Web服务器启动的时候会创建Filter实例对象,并调用init()方法,完成对象的初始化。需要注意的是,在一次完整的请求当中,Filter对象只会创建一次,init()方法也只会执行一次
执行阶段–doFilter()
当客户端请求目标资源时,服务器会筛选出符合映射条件的Filter,并按照类名的的先后顺序依次执行doFilter() 方法。在一次完整的请求当中,doFilter()方法可以执行多次。
销毁阶段–destroy()
服务器关闭时,Web服务器调用destroy()方法销毁Filter对象。
二、Filter快速入门
2.1、实现步骤:
1.创建一个类实现Filter接口,重写其方法
2.配置Filter拦截资源的路径,可使用@WebFilter注解 或者在web.xml中配置
3.在 doFilter方法中进行资源拦截和处理
// 注意:实现的Filter接口是 javax.servlet包下的Filter
@WebFilter("/*") // * 表示拦截所有请求
public class MyFilterDemo implements Filter {
//创建阶段
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化。。。。");
}
//执行阶段
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("拦截器执行啦。。。");
}
//销毁阶段
@Override
public void destroy() {
System.out.println("销毁阶段");
}
}
@WebFilter注解的属性:
属性名 | 类型 | 描述 |
---|---|---|
filterName | String | 指定过滤器的名称。默认是过滤器类的名称。 |
urlPatterns | String[] | 指定一组过滤器的URL匹配模式。 |
value | String[] | 该属性等价于urlPatterns属性。urlPatterns和value属性不能同时使用。 |
servletNames | String[] | 指定过滤器将应用于哪些Servlet。取值是 @WebServlet 中的 name 属性的取值。 |
dispatcherTypes | DispatcherType | 指定过滤器的转发模式。具体取值包括:ERROR、FORWARD、INCLUDE、REQUEST。 |
initParams | WebInitParam[] | 指定过滤器的一组初始化参数。 |
2.2、Filter执行流程
Filter拦截到资源后,交给doFilter方法处理,在doFilter方法中分为放行前,放行,放行后三个过程。放行之后访问到Web资源,会再次回到doFilter方法中执行放行后的逻辑逻辑代码。
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
//放行前的逻辑代码
req.setCharacterEncoding("utf-8");
//放行
filterChain.doFilter(req,resp);
//放行后
resp.setCharacterEncoding("utf-8");
}
三、Filter路径配置
Filter可以根据需求,配置不同的拦截资源路径。
@WebFilter(" /*)
public class FilterDemo
- 拦截具体的资源:/index.jsp: 只有访问index.jsp时才会被拦截。
- 目录拦截:/user/*: 访问/user下的所有资源,都会被拦截。
- 后缀名拦截:* *.jsp:访问后缀名为jsp的资源,都会被拦截。
- *拦截所有:/**:访问所有资源,都会被拦截。
四、案例
需求:使用过滤器设置字符编码
@WebFilter("/*")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("----初始化---");
System.out.println(filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//设置字符编码
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//放行
chain.doFilter(request,response);
System.out.println("--------放行后--------");
}
}