Filter过滤器
什么是过滤器
引入
- 假设一名游客想去动物园,然后她跑到腾讯公司的前台说“给我来张动物园门票”,对于这种没必要的请求 由于完成一次完整的请求和响应,这无形之中给Servlet增加了压力,所以我们希望利用过滤器将这些没有必要的请求进行过滤出去。
- 而对于前往来面试人员的请求传送给人事部,并将响应及时返回。
- 这就说明过滤器就相当是一个中介,过滤掉没必要的请求,向Servlet传递有必要的请求
定义
- 过滤器是一个用于拦截在数据源和数据目的地之间消息的一个对象。
- 广义的Filter:所有实现了Filter接口的类
- 狭义的Filter:指Filter这个类
功能
1.分析请求,将请求发送给指定的资源(将面试人员来面试的消息发送给人事部)或自己创建一个响应 (对于买门票的消息直接对其进行响应告诉他“我们这里不是买门票的”)
2.在请求到达服务器端前处理请求,设置请求信息,将请求封装成符合规则的对象
3.在响应到达客户端前处理响应,将响应封装成符合规则的对象
综上所述,过滤器不仅可以过滤不合理的请求,还可以将请求和响应封装成符合规则的对象
过滤器对请求的三种处理情况
- 过滤器自身产生一个响应,返回客户端 (也就是拦截了客户端的请求,给他说“我们这里不买票”)
- 把请求转发给过滤链中的下一个过滤器,如果是最后一个过滤器则把请求转发给指定资源
- 把请求转发给另一个资源 (过滤器可以根据请求将他转发给其对应的Servlet,也就是将他转发到“动物园售票处”)
过滤器中的一些方法
-
Flter在配置文件.XML中的相关配置
<filter> <filter-name>NameFilter</filter-name> <!-- 这里的名字是随便起的,是什么都可以,但是必须保证和filter-mapping中的name属性值一样 --> <filter-class>com.NameFilter</filter-class> </filter> <filter-mapping> <filter-name>NameFilter</filter-name> <url-pattern>/*</url-pattern> <!-- 在这里要说明对哪些请求进行过滤 /*表示对所有请求都进行过滤 --> </filter-mapping>
上面值得我们注意的是**<** 中的值不一定非得是类名,可以随便起,但是一定要和中的name值保持一致 。同样对于Servlet配置文件中的name属性值也是一样的道理
-
我们写的所有的过滤器类都实现了Filter接口 ,Filter接口中有三个抽象方法 ,所以Filter的实现类要重写这三个抽象方法
-
过滤器类和Servlet一样都具有生命周期,其中Servlet为加载类–>实例化–>初始化–>服务–>销毁 ,而Filter是:加载类–>实例化–>初始化–>过滤–>销毁
package com; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.annotation.WebFilter; public class NameFilter implements Filter { public NameFilter() { /** * 这个方法是我们写的类的构造方法 */ } public void destroy() { /** * 过滤器的销毁的方法,这个方法在Filter的生命周期中只调用一次 */ } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { /** 1.在这个方法里面完成实现过滤的逻辑代码,相当于Servlet实现类里面的service方法 2.该方法的参数是ServletRequest和ServletResponse,但是我们得到的客户端发来的请求都是HttpServletRequest类型,所以我们需要在得到请求之后记得将请求和响应进行类型的强转 3.方法中的参数chain代表的是过滤器链,但是FilterChain是一个接口类,含有doFilter()一个抽象方法,我们是没有办法直接创建接口的对象的,所以我们猜测Filter的底层一定是有一个类实现了FilterChain这个接口,重写了抽象方法doFilter()并实例化了chain这个对象,所以我们就能明白为什么chain也可以调用doFilter方法了 */ //对请求的过滤条件写在这里 chain.doFilter(request, response);//过滤链的条件,执行结束后就应该去执行服务器对请求的响应的过滤条件了,所以这句换就相当于是一条分水岭 //这里写对响应的一些过滤条件 } public void init(FilterConfig fConfig) throws ServletException { /* 完成对过滤器的初始化 */ } }
-
如何配置使用过滤器
-
实例1 完成用户登录,登陆完成后才能进入主界面,不能直接访问主界面
-
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi
-