SpringBoot写过滤器

149 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、过滤器简介 1、过滤器是什么?

Filter也称之为过滤器,过滤器是对数据进行过滤,预处理。开发人员可以对客户端提交的数据进行过滤处理,比如敏感词,也可以对服务端返回的数据进行处理。还有就是可以验证用户的登录情况,权限验证,对静态资源进行访问控制,没有登录或者是没有权限时是不能让用户直接访问这些资源的。类似的过滤器还有很多的功能,比如说编码,压缩服务端给客户端返回的各种数据,等等。

2、过滤器的运作原理?

java为我们提供了一个Filter接口,我们只需要实现这个接口就能实现自定义过滤器,然后添加一些必要的配置让过滤器生效。过滤器只能初始化一次,并且过滤器只会在项目停止或者是重新部署的时候才销毁。我们可以实现的这个Filter接口,里面最重要的是一个doFilter方法,当我们编写好Filter,并配置好对那个URL资源进行拦截时,每一次请求这个资源之前就会调用这个doFilter方法。并且在这个doFilter方法里面也有着一个FilterChain的对象参数 ,这个对象里面也有一个doFilter方法,是否调用这个方法决定了这个过滤器是否能调用后面的资源或者是执行后面的过滤器。也就是相当于目标资源。所以在过滤器里面可以进行一些什么操作呢?可以在调用目标资源之前,进行权限等的处理;判断是否调用目标资源;也可以在调用目标资源之后进行一些响应消息进行处理。

二、过滤器配置的两种方法 1、注解配置

首先我们定义一个MyFilter 实现Filter接口。重写里面的三个方法:


import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;

/**
 * @BelongsPackage: com.yhn.filter
 * @Author: 小叶
 * @CreateTime: 2022-08-24  17:56
 * @Description:
 * @Version: 1.0
 */
/**
* @author filterName 表示是一个filter 的名称
* @author urlPatterns 表示要拦截的URL资源  
*/
@WebFilter(filterName = "myFilter1",urlPatterns = {"/*"})
public class MyFilter 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("进入目标资源之前先干点啥");
        //这个方法其实就是一个 可以请求、响应  也就是放行的意思
        filterChain.doFilter(servletRequest, servletResponse);
        System.out.println("处理一下服务端返回的response");
    }

    /**
    * 只会在项目停止或者是项目重新部署的时候才会执行。
    */
    @Override
    public void destroy() {
        System.out.println("过滤器被销毁了");
    }
}

注意:你要是想让你的过滤器能起到作用,必须必须必须的重写doFilter方法

启动类加上注解 @ServletComponentScan


/**
* 使用过滤器最好用这个注解
 * SpringBootApplication 上使用@ServletComponentScan 注解后
 * Servlet可以直接通过@WebServlet注解自动注册
 * Filter可以直接通过@WebFilter注解自动注册
 * Listener可以直接通过@WebListener 注解自动注册
 * 
*/
@ServletComponentScan
@SpringBootApplication
public class FilterApplication {

    public static void main(String[] args) {
        SpringApplication.run(FilterApplication.class, args);
    }

}

写完了,当然要测试啊,是不是,这不就是妹子说到你家手机充电,呆了20分钟,你说妹子你手机充满了,你走把,我要休息了??????????是不是

/**
 * @BelongsPackage: com.yhn.controller
 * @Author: 小叶子
 * @CreateTime: 2022-08-24  18:07
 * @Description:
 * @Version: 1.0
 */
@RestController
@RequestMapping("/Filter")
public class FilterController {
    @RequestMapping("/testFilter")
    public String testFilter(){
        System.out.println("filter执行成功");
        return "filter";
    }
}

配置类

server.port= 9000

访问:localhost:9000/Filter/testFilter

image.png

为了大家 能看到过滤器平时是咋用的,我就自己随便写写一般的使用

/**

 * @BelongsPackage: com.yhn.reggie.filter

 * @Author: 叶浩楠

 * @CreateTime: 2022-07-30  20:40

 * @Description: TODO 过滤器

 * @Version: 1.0

 */

@WebFilter(filterName = "loginCheckFilter",urlPatterns = "/*")

@Slf4j

public class LoginCheckFilter implements Filter {



    //路径匹配

    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();



    @Override

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {



        //强转

        HttpServletRequest request = (HttpServletRequest) servletRequest;

        HttpServletResponse response = (HttpServletResponse) servletResponse;



        //1.获取本次请求的URI

        String requestURI = request.getRequestURI();



        //定义不需要处理的请求

        String[] urls = new String[]{

                "/employee/login",//登录

                "/employee/logout",//退出

                "/backend/**",

                "/front/**",

                "/common/**",

                "/user/login",

                "/user/sendMsg",

                "/doc.html",

                "/webjars/**",

                "/swagger-resources",

                "/v2/api-docs"

        };



        //2.判断本次请求是否需要处理

        boolean check = check(urls, requestURI);



        //3.如果不需要处理,则直接放行

        if (check) {

            filterChain.doFilter(request,response);

            return;

        }



        //4.判断是否登录  如果已登录 直接放行

        Object employee = request.getSession().getAttribute("employee");

        if (employee != null) {

            //获取当前登录用户id

            Long empID = (Long) request.getSession().getAttribute("employee");

            //设置用户id到当前线程

            BaseContext.setCurrentId(empID);



            filterChain.doFilter(request,response);

            return;

        }

        //4-2判断移动端是否登录

        Object user = request.getSession().getAttribute("user");

        if (user != null) {

            //获取当前登录用户id

            Long userID = (Long) request.getSession().getAttribute("user");

            //设置用户id到当前线程

            BaseContext.setCurrentId(userID);



            filterChain.doFilter(request,response);

            return;

        }





        //5.如果未登录则返回未登录结果,通过输出流方式向客户端页面响应数据

        response.getWriter().write(JSON.toJSONString(R.error("NOTLOGIN")));

        return;



    }



    public boolean check(String[] urls, String requestURI){

        for (String url : urls) {

            boolean match = PATH_MATCHER.match(url, requestURI);

            if (match) {

                //匹配

                return true;

            }

        }

        //不匹配

        return false;

    }

}