JAVAWEB-过滤器

本文介绍了Java Web中的过滤器概念,强调了过滤器在Web容器中的位置和作用,如拦截请求、处理响应、避免乱码和权限验证。通过实际例子展示了过滤器的实现、注册到Spring Boot以及效果验证,探讨了多层过滤器的配置和执行顺序。过滤器作为后端资源的防火墙,简化了编码工作,提供了预处理和后处理功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章摘录自微信公众号:java3y。Java3y同学的文章非常棒,内容详实。这篇文章是借用他的文章再做些修改。

1、什么是过滤器

首先,我们来看看过滤器究竟Web容器的哪处:

从上面的图我们可以发现,当浏览器发送请求给服务器的时候,先执行过滤器,然后才访问Web的资源。服务器响应Response,从Web资源抵达浏览器之前,也会途径过滤器。。

我们很容易发现,过滤器可以比喻成一张滤网。我们想想现实中的滤网可以做什么:在泡茶的时候,过滤掉茶叶。那滤网是怎么过滤茶叶的呢?规定大小的网孔,只要网孔比茶叶小,就可以实现过滤了!

引申在Web容器中,过滤器可以做:过滤一些敏感的字符串【规定不能出现敏感字符串】、避免中文乱码【规定Web资源都使用UTF-8编码】、权限验证【规定只有带Session或Cookie的浏览器,才能访问web资源】等等等,过滤器的作用非常大,只要发挥想象就可以有意想不到的效果。

也就是说:当需要限制用户访问某些资源时、在处理请求时提前处理某些资源、服务器响应的内容对其进行处理再返回、我们就是用过滤器来完成的。

很多事情,你不需要在每个controller里面去写,比如编码,比如验证登录,统一都放到filter里面去做。过滤器相当于是后端资源的防火墙和大管家。

2 实际例子

    上一个例子来演示过滤器的作用。

2.1 实现过滤器方法

   主要需要实现方法的是doFilter。他能实现来回的过滤,那么都加上看看效果。

public class FilterDemo1 implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("FilterDemo1 init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("before doFilter");

        //发送过去的时候过滤
        HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequest;
        httpServletRequest.setAttribute("t1_Attr","sss");
        //返回的时候过滤
        HttpServletResponse httpServletResponse=(HttpServletResponse)servletResponse;
        httpServletResponse.setHeader("myhead","hahaha");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("after doFilter");
    }

    @Override
    public void destroy() {
        System.out.println("FilterDemo1 destroy");
    }
}

2.2 把这个filter注册进springboot。

这里描述了要过滤哪些链接

@Configuration
public class MyFilterConfig {
    /**
     * 注册Filter组件
     */
    @Bean
    public FilterRegistrationBean myFilter() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        //设置自定义filter
        bean.setFilter(new FilterDemo1());
        //过滤哪一些请求
        bean.setUrlPatterns(Arrays.asList("/test1/*"));
//        bean.setUrlPatterns(Arrays.asList("/test1/*","/test2/*"));
        return bean;
    }

}

2.3 效果验证

访问后端前过滤了一道,在请求头加了Attribute,所以这里就能拿到值。

@RequestMapping("/test1")
@RestController
public class Test1 {

    @RequestMapping("/t1")
    public String T1(HttpServletRequest httpServletRequest){
        String headName=(String)httpServletRequest.getAttribute("t1_Attr");
        System.out.println(headName);
        return "test1-t1";
    }
}

返回给浏览器的时候,在响应头里面加了一个,所以浏览器中也能看到。

至此最基本的效果实现了。

3 多层过滤器

 先新增两个过滤器

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("FilterDemo2 开始过滤");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("FilterDemo2 过滤结束");

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("FilterDemo3 开始过滤");
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("FilterDemo3 过滤结束");

    }

然后分别注册进去,下面还设置了这两个过滤器的顺序。

    @Bean
    public FilterRegistrationBean myFilterTest2Controller1() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        //设置自定义filter
        bean.setFilter(new FilterDemo2());
        //指定顺序
        bean.setOrder(1);
        //过滤哪一些请求
        bean.setUrlPatterns(Arrays.asList("/test2/*"));
        return bean;
    }

    @Bean
    public FilterRegistrationBean myFilterTest2Controller2() {
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new FilterDemo3());
        //指定顺序
        bean.setOrder(2);
        //过滤哪一些请求
        bean.setUrlPatterns(Arrays.asList("/test2/*"));
        return bean;
    }

得到下面的打印

FilterDemo2 开始过滤
FilterDemo3 开始过滤
test2访问到了
FilterDemo3 过滤结束
FilterDemo2 过滤结束

4、过滤器的简单应用小结

  1. 可以在filter中根据条件决定是否调用chain.doFilter(request, response)方法,即是否让目标资源执行。在上面的测试过滤器顺序的例子中,我们把两个过滤器的dofilter方法注释掉,可以发现controller的返回,页面上也看不到了,而且只执行了filter2的打印,因为水流直接在这里被截断了,都没流到filter3去。
  2. 在让目标资源执行之前,可以对request\response作预处理,再让目标资源执行。特别适合在响应头上做动作,返回给前端。
  3. 在目标资源执行之后,可以捕获目标资源的执行结果,从而实现一些特殊的功能
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值