javaweb之filter

过滤器

1、简单介绍

​ Filter:一个实现了特殊接口(Filter)的Java类. 实现对请求资源(jsp,servlet,html等)的过滤的功能.

​ 过滤器是一个运行在服务器的程序, 优先于请求资源(Servlet或者jsp,html[动态资源和静态资源])之前执行. 过滤器是javaweb技术中最为实用的技术.

过滤器是在服务器上的一项技术,实现了特定的接口。作用是请求到达目标资源的时候,对发送过来的请求进行特殊处理。这里是一个条件判断,如果满足了我们设置的请求,那么需要将其放行;如果不满足,那么进行拦截。
首先对路径来进行拦截,如果说,执行了doFilter方法,那么就说明本次请求放行了;如果没有执行doFilter方法,那么本次请求执行没有执行成功

最常见的几种作用:

1、对于请求和响应乱码的情况;
2、对于权限管理。客户端发送请求,通过过滤器可以实现判断用户是什么角色,对应的界面显示该怎么去进行显示,拥有哪些功能。
3、黑名单过滤。不允许让黑名单中的用户来进行访问

2、Filter的生命周期

filter的生命周期和servlet的生命周期非常的类似

​ init(FilterConfig):初始化

​ doFilter(ServletReqeust req,ServletResponse resp,FilterChain chain):执行过滤的方法

​ destroy():销毁

对方法来进行描述:

  1. 服务器启动的时候, 会调用init()方法进行初始化【调用一次】
  2. 任何一次请求都会调用doFilter()方法进行过滤【路径相匹配】
  3. 服务器正常关闭或者项目从服务器移除, 调用destory()方法进行销毁【调用一次】

这里和servlet的init方法还是有区别的,servlet的init方法默认是在服务器启动之后,在第一次访问的时候执行初始化方法,但是servlet的init方法的执行之间是可以来进行设置的,可以设置在服务器启动的时候就执行init方法。

3、映射路径

filter的映射路径和servlet中的路径及其相似。

servlet的路径分为:完全路径匹配、目录匹配、扩展名匹配和缺省匹配

假设有一个管理员权限的过滤器,它应该对用户发出的管理员功能的请求进行条件的过滤。但是当用户发出登录、注册等请求的时候,不应该进行过滤。所以我们过滤器,应该有选择的过滤器请求。这就需要学习配置过滤器不同的映射路径,从而让过滤器过滤希望过滤器的请求。

3.1完全路径匹配

以"/"开始

/demo01 ---> 过滤器只能拦截路径/demo01; 

3.2目录匹配

以"/"开始 以 *结束 .

/* --->当前项目下的所有的路径都可以拦截;   /aa/*  ---> 可以拦截 /aa/bb, /aa/bb/cc

3.3扩展名匹配

以"*"开始 例如: *.jsp *.do

*.do--->可以拦截路径的后缀是 do的 ;  *.jsp--->拦截所有JSP

3.4缺省匹配

/ 除了jsp以外的资源都匹配

当前Filter里面不支持, Servlet里面可行的. 后面在Servlet里面遇到

4、拦截方式

有了上面学习的映射路径,我们可以控制过滤器过滤指定的内容,但是我们在访问资源的时候,并不是每次都是之间访问,有时是以转发的方式访问的,这就需要我们要让过滤器可以区分不同的访问资源的方式,有不同的拦截方式。 是通过 DispatcherType 来指定的.

  • DispatcherType.REQUEST

​ 默认值,过滤从浏览器发送过来的请求和重定向 不过滤转发

  • DispatcherType.FORWARD

只过滤转发过来的请求

一般情况下, 转发我们不会过滤的. 转发属于服务器内部的行为. 直接使用默认值的情况偏多

案例:

/*只拦截转发*/
/*@WebFilter(urlPatterns = "/demo01",dispatcherTypes={DispatcherType.FORWARD})*/

/*转发,重定向,浏览器的直接请求都会拦截了*/
@WebFilter(urlPatterns = "/demo01",dispatcherTypes={DispatcherType.FORWARD,DispatcherType.REQUEST})
public class FilterDemo01 implements Filter {

    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
        System.out.println("FilterDemo01()  收到了请求...");
        chain.doFilter(req, resp);
    }
    public void destroy() {

    }
    public void init(FilterConfig config) throws ServletException {

    }
}

5、过滤器链

​ 过滤器链作用:当一个filter收到请求的时候,调用chain.doFilter才可以访问下一个匹配的filter,若当前的filter是最后一个filter,调用chain.doFilter才能访问目标资源

用一个图来进行表示一下执行顺序

那么接下来举一个例子来演示一下:

AFilter:

@WebFilter(filterName = "AFilter",value = "/aa/*")
public class AFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        System.out.println("AFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤");
        chain.doFilter(request, response);
    }
}

BFilter

@WebFilter(filterName = "BFilter",value = "/aa/demo06")
public class BFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        System.out.println("BFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤");
        chain.doFilter(request, response);
    }
}

ServletDemo06:

@WebServlet(name = "ServletDemo06", value = "/aa/demo06")
public class ServletDemo06 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("halo,浏览器端请求的资源被处理了");
    }
}

浏览器端输入URL:http://localhost:8080/filter_war_exploded/aa/demo06

查看控制台:

AFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤
BFilter拦截器拦截/aa/*下的路径的,拦截了就会执行这里的步骤
halo,浏览器端请求的资源被处理了

6、字符编码过滤器

/**
 * 为了让所有的请求中的字符编码都给设置好,所以将路径设置成所有的
 *
 * 需要注意的有三个点:
 *  1、访问路径是:/*
 *  2、需要将req和res进行强制类型转换;
 *  3、将转换后的req和res来进行放行;
 */
@WebFilter(filterName = "EncodingFilter",value = "/*")
public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig config) throws ServletException {
    }
    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        // 这里的这一步是可以将所有进行转换的req和res来进行转换,然后进行放行和过滤
        chain.doFilter(req, res);
    }
}
posted @ 2021-09-21 18:53  雩娄的木子  阅读(264)  评论(0编辑  收藏  举报