WEB组件之Filter过滤器

Filter过滤器

最近学习到了Servlet过滤器,记录一下

  • 过滤器是一个驻留在服务器中的WEB组件(三大组件之一),他可以截取客户端和WEB资源(Servlet、JSP、HTML页面等)之间的请求和响应信息。
  • 过滤器可以在WEB资源收到请求之前,浏览器收到响应之前,对请求和响应信息做一些相应的操作。
  • 在一个WEB应用中可以部署多个过滤器,多个过滤器就组成了一个过滤器链,请求和响应必须在经过多个过滤器后才能到达目标。
  • 通俗的说 实现了Filter接口的类都是过滤器。
    在这里插入图片描述

在这里插入图片描述

  • 对当前的请求进行过滤,判断是否符合规则,是否具备访问目标资源的条件。若符合,则放行;若不符合,则进行其他操作

过滤器不是必须将请求传送到下一个过滤器(或WEB资源),也可以自己来处理请求,发送响应

Filter的生命周期

由Tomcat管理其生命周期,且Filter比Servlet先加载

  1. init()方法用于初始化Filter

  2. doFilter()作用和service()方法类似,是过滤请求和响应的主要方法。

  3. destroy()用于在Filter对象被销毁前做一些收尾工作。如:释放资源等。

即:

构造器(实例化):创建Filter实例是调用,Filter实例服务器一旦启动就会被创建

初始化:实例化之后紧接着初始化,服务器启动的过程中只执行一次

执行过滤:只要是需要进行过滤的请求,都会执行此方法

销毁:服务器关闭时销毁

Filter相关接口

一、Filter接口,实现Filter需要实现该接口

在这里插入图片描述

  1. init()方法用于初始化Filter

  2. doFilter()作用和service()方法类似,是过滤请求和响应的主要方法。

  3. destroy()用于在Filter对象被销毁前做一些收尾工作。如:释放资源等。

二、FilterConfig对象在服务器调用init()方法时传递进来

在这里插入图片描述

  1. getFilterName() 获取Filter的名字

  2. getServletContext() 获取ServletContext对象(即application)

  3. getInitParameter() 获取Filter的初始化参数

  4. getInitParameterNames() 获取所有初始化参数的名字

三、FilterChain对象是在doFilter()方法被调用时作为参数传递进来的。

在这里插入图片描述

  1. doFilter()方法用于调用Filter链上的下一个过滤器,如果当前过滤器为最后一个过滤器则将请求发送到目标资源。

Filter的创建和使用

  • 创建&使用
public class FirstFilter implements Filter {
	//实现三个抽象方法...
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
	// 放行操作,调用链上的下一个过滤器
	filterChain.doFilter(servletRequest, servletResponse);
}

在过滤器中,执行过滤的方法doFilter(),其中就是对当前请求的过滤过程,因此一定要在需要放行时使用chain.doFilter()实现放行功能

  • 注册(个人比较习惯使用xml注册的方式,也可以在创建filter时勾选注解的方式注册)
    方式一:在web.xml中进行注册
<filter>
        <filter-name>FirstFilter</filter-name>
        <filter-class>com.atguigu.filter.FirstFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>FirstFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

filter-name 指定的是过滤器的名字

filter-class 指定的是过滤器的全类名

url-pattern 指定的是需要过滤器处理的请求地址,/ 为当前工程下,* 为所有资源

方式二:在IDEA创建时勾选注解

在这里插入图片描述

在IDEA中创建FIlter

在IDEA中创建FIlter

Filter的过滤规则

  • url-pattern设置filter的过滤规则

1、精确匹配:在url-pattern中设置某个资源的完整路径,此时过滤器就会对路径指定的资源进行过滤

<url-pattern>/test/test.jsp</url-pattern>
<url-pattern>/index.jsp</url-pattern>

2、路径匹配(通用匹配):在url-pattern中使用*表示所有资源

<url-pattern>/*</url-pattern>
<url-pattern>/test/*</url-pattern>

3、后缀匹配:在url-pattern中使用" *.后缀名 "表示只能对某种后缀的资源进行过滤

以上三种过滤规则不能混合使用,但是一个filter可以有多个url-pattern

4、servlet匹配:通过filter-mapping中的servlet-name,对servlet-name所对应的servlet进行过滤

<filter-mapping>
    <filter-name>LoginFilter</filter-name>
    <servlet-name>OrderClientServlet</servlet-name>
</filter-mapping>

多个Filter的执行顺序

在这里插入图片描述

  • 执行顺序多用于springMVC

  • 多个Filter的doFilter()执行顺序只跟在web.xml中的注册顺序有关,其实是按照filter-mapping的顺序执行,越靠前,越先执行

  • 多个Filter的初始化和销毁的方法跟web.xml中注册的顺序没有关系,不需要考虑

  • 多个Filter中执行过滤的方法doFIlter(),其中的内容,放行之前按顺序执行,放行之后的代码按照倒序执行【即栈状态】

FIlter使用实例

业务场景:用户需要登录才能对购物车中的商品进行结账,需要通过FIlter进行请求过滤,当session保存有用户信息,才会对该请求放行。

1、封装了原始的FIlter,因为只需要关注doFIlter()内的业务逻辑,不需要关注filter的初始化、销毁。同时转换ServletRequest、ServletResponse —>HttpServletRequest、HttpServletResponse

public abstract class HttpFilter implements Filter {
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) resp;
        doFilter(request,response,chain);
    }
    public abstract void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws ServletException, IOException;

    @Override
    public void init(FilterConfig config) throws ServletException {

    }
}

2、继承HttpFilter ,只需要在doFIlter内写业务逻辑

public class LoginFilter extends HttpFilter {
    @Override
    public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpSession session = request.getSession();
        Object user = session.getAttribute("user");
        if (user == null){
            // 未登录,使用请求域+转发跳转到login页面,并且在界面中提示用户需要登录
            request.setAttribute("errorMsg","结账功能需要登录");
            request.getRequestDispatcher("/pages/user/login.jsp").forward(request,response);
        }else {
            // 已登录
            chain.doFilter(request,response);
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值