Filter过滤器
filter是过滤器,相比于Servlet的发送请求,filter是用于拦截请求。比如在登陆系统中,正常登陆的用户可以访问服务器的相关资源,而如果登陆信息错误,则拦截想要访问资源的请求。以下将具体介绍filter
1. Filter的生命周期
Filter的生命周期分为三部分,分别是init()初始化;doFilter()执行拦截;destroy()销毁;
具体如下代码
package com.company.Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; //注解配置实现所有请求访问都进行拦截 @WebFilter("/*") public class filterDemo1 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("在服务器关闭的时候,执行销毁函数"); } }
2.Filter的配置
Filter的配置分为两种,一种是xml配置,一种是通过注解类配置
- 通过xml配置(打开web.xml):
<filter> <!-- 随便创建想要的名称--> <filter-name>filterDemo1</filter-name> <!-- filter对应的具体类--> <filter-class>com.company.Filter.filterDemo1</filter-class> </filter> <!-- 创建filter对应的映射--> <filter-mapping> <!-- filter对应的名称--> <filter-name>filterDemo1</filter-name> <!-- 拦截路径,/*表示所有访问都会进行拦截--> <url-pattern>/*</url-pattern> </filter-mapping>
- 通过注解类进行配置:
@WebFilter(value=url-pattern)
如果只需要写拦截规路径可以省略掉value = ;
直接输入@WebFilter("/*")实现对数据所有访问时候进行拦截
3.拦截路径
刚才介绍了/*是所有请求的拦截,但是对于具体访问的请求的拦截还无法做到,下面介绍其他拦截路径
- 具体路径访问的拦截:/index.jsp (当访问index.jsp文件时候实现拦截)
- 某一个目录的访问的拦截:/user (当访问user目录以下的所有文件时候进行拦截)
- 后缀名访问的拦截:*.jsp (实现对所有文件以.jsp后缀结尾访问的拦截)
- 拦截所有相关路径:/* (访问所有服务器的资源时候都实现拦截)
4.拦截具体的使用
1.创建类实现Filter接口(注意Filter接口是包javax.servlet中的)
2.覆写生命周期函数
3.通过doFilter函数实现拦截。当通过后实现放行
案例代码:
拦截类
package com.company.Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; //通过注解类实现拦截路径 @WebFilter("/*") //实现接口 public class filterDemo2 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("发现请求,实施拦截"); //// 进行验证,如果通过则实现放行 // System.out.println("验证成功,放行"); // filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { System.out.println("服务器关闭时候执行销毁函数"); } }
模拟资源类
package com.company; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/FilterDemo3") public class FilterDemo3 extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("访问到资源啦"); } // 方法统一 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } }
当通过url访问资源类时候 可以看到请求被拦截了,无法执行资源类中输出"访问资源类啦"
编辑
编辑 再加上验证功能后如果允许通过则需要放行,执行FilterChain filterChain中filterChain对象的doFilter(servletRequest对象, servletResponse对象)即代码中的
// 拦截结束后如果通过则实现放行 System.out.println("验证成功,放行"); filterChain.doFilter(servletRequest, servletResponse);
此时再通过url访问后,查看控制台的信息可以看到:
编辑
5.拦截方式配置(资源被访问方式)
当然除了路径访问可以拦截以外,还可以设置拦截的方式,有些请求可以直接输入url直接访问类。有些通过一些网页实现跳转的方式获取类的资源。还有就是通过请求转发的形式获取类。所以基于如此可以对这些方法做一些限制。
拦截方法 | 描述 |
REQUEST(请求拦截) | 拦截直接通过 URL 访问的请求。 |
FOWARD(转发拦截) | 拦截通过请求转发方式获取资源的请求。 |
INCLUDE(包含拦截) | 拦截通过网页跳转方式获取资源的请求。 |
ERROR(错误拦截) | 拦截发生错误或异常情况的请求。 |
ASYNC(异步拦截) | 拦截异步请求,即延迟加载的请求,可以防止对响应进行预先缓存和使用。 |
默认情况下是通过REQUEST实现拦截
具体使用还需要看开始时候使用的配置
- 通过xml配置
<filter> <filter-name>filterDemo1</filter-name> <filter-class>com.company.Filter.filterDemo1</filter-class> </filter> <filter-mapping> <filter-name>filterDemo1</filter-name> <url-pattern>/*</url-pattern> <!-- 配置请求拦截方法--> <dispatcher>REQUEST</dispatcher> </filter-mapping>
- 通过注解类配置
编辑
6.FilterChain拦截链
拦截链,顾名思义就是由多个过滤器组成,就像是一条路设置了多个收费站一样。只有满足所有的拦截规则后才能通过。
设置多个拦截器(其中一个的代码)
package com.company.Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter("/*") public class filterDemo3 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("拦截器1进行拦截"); System.out.println("拦截器1放行"); // 拦截器放行 filterChain.doFilter(servletRequest, servletResponse); } @Override public void destroy() { } }
通过url访问时候结果如下
编辑
拦截器的顺序
一.注解配置
是通过拦截器名字的排序比如01、02、03,先比较第一个数字大小,如果相同就比较第二个数字大小以此类推
二.xml配置
只需要配置xml时候由上往下即可