JavaWeb-Springboot-过滤器【Filter】


一、概述

  • 过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
  • 过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。

在这里插入图片描述

二、快速入门

  • 定义Filter

定义一个类,实现Filter的接口,并重写其所有的方法。

  • 配置Filter

在Filter类上增加@WebFilter注解,配置拦截资源的路径。引导类上增加@ServletComponentScan开启Servlet组件支持。

在这里插入图片描述

注意:这里一定要使用的是jakarta包下的,javax包下的已经不生效了

import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")  // 拦截的请求:/*表示拦截所有请求
public class DemoFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("init ---> Filer初始化!!!");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("doFilter ---> Filter拦截请求成功!!!");
        // 放行请求,必须增加,否则所有的请求都会卡在这里
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {
        log.info("destroy ---> Filter销毁!!!");
    }
}

注意:一定要在SpringBoot主启动类上增加@ServletComponentScan否则无效

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;

@ServletComponentScan  // 开启对Servlet组件的支持
@SpringBootApplication
public class SpringbootManagementApplication {

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

}

三、详解

3.1 执行流程

在这里插入图片描述

先对请求进行拦截,执行放行之前的逻辑,然后放行执行web资源的逻辑,在回到过滤器执行放行之后的逻辑,最后返回数据。

3.2 拦截路径

拦截路径使用@WebFilter(urlPatterns = “/*”) 注解

在这里插入图片描述

3.3 过滤器链

在一个Web应用中,可以配置多个过滤器,这多个过滤器就形成了一个过滤器链。优先级:按照类名划分

在这里插入图片描述

四、登录校验

登录校验流程:

  • 获取请求的URL
  • 判断URL中是否包含login,如果包含,说明是登录操作,放行
  • 获取请求头中的令牌(token)
  • 判断令牌是否存在,如果不存在,返回错误结果(未登录)
  • 解析token,如果解析失败,返回错误结果(未登录)
  • 放行请求

登录校验代码实现

import com.alibaba.fastjson.JSONObject;
import com.ming.pojo.Result;
import com.ming.utils.JwtUtils;
import jakarta.servlet.*;
import jakarta.servlet.annotation.WebFilter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.io.IOException;

@Slf4j
@WebFilter(urlPatterns = "/*")  // 拦截的请求:/*表示拦截所有请求
public class LoginCheckFilter implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 1. 获取请求的URL
        String url = request.getRequestURI();
        log.info("请求的URL ---> {}!!!", url);

        // 2. 判断URL中是否包含login,如果包含,说明是登录操作,放行
        if (url.contains("login")) {
            log.info("登录操作 ---> 放行!!!");
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }

        // 3. 获取请求头中的令牌(token)
        String jwt = request.getHeader("token");

        // 4. 判断令牌是否存在,如果不存在,返回错误结果(未登录)
        if (!StringUtils.hasLength(jwt)) {
            log.info("请求头token为空 ---> 登录失败!!!");
            Result error = Result.error("NOT_LOGIN");
            // 手动转换 对象 ---> json
            String notLogin = JSONObject.toJSONString(error);
            // 响应给浏览器
            response.getWriter().write(notLogin);
            return;
        }

        // 5. 解析token,如果解析失败,返回错误结果(未登录)
        try {
            JwtUtils.parseJWT(jwt);
        } catch (Exception e) {
            e.printStackTrace();
            log.info("令牌解析失败 ---> 登录失败!!!");
            Result error = Result.error("NOT_LOGIN");
            // 手动转换 对象 ---> json
            String notLogin = JSONObject.toJSONString(error);
            // 响应给浏览器
            response.getWriter().write(notLogin);
            return;
        }

        // 6. 放行请求,必须增加,否则所有的请求都会卡在这里
        log.info("令牌合法 ---> 放行!!!");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}
  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Monly21

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值