在 springboot3.X 中,强制要求使用Jakarta EE 9+(包名 jakarta.servlet),所以在 springboot 中使用 Filter 时,可能会遇到奇怪的报错,像这样的:

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2025-05-16T21:46:27.317+08:00 ERROR 14876 --- [           main] o.s.boot.SpringApplication               : Application run failed

所以,这篇文章使用的是 Jakarta EE 的 jakarta.servlat 包。

目录

Filter(过滤器)简介

在 springboot 中使用 Filter

1.  导入 jakarta.servlat 包

 2. 创建 Filter 类

3. Filter 中的内容

4. 拦截Token

5.启动拦截

6.运行测试

如果登录时有token,则在控制台上会有以下结果:

如果没有 token, 则控制台会有如下结果:

总结


Filter(过滤器)简介

Filter 是前端请求到达 Servlet 之前使用的工具,适用于处理与业务无关的通用逻辑,如:Token 校验、权限控制、重定向等

在 springboot 中使用 Filter

1.  导入 jakarta.servlat 包

我使用的是maven,将以下代码添加到pom文件中:

        <dependency>
            <groupId>jakarta.servlet</groupId>
            <artifactId>jakarta.servlet-api</artifactId>
            <version>6.0.0</version>
            <scope>provided</scope>
        </dependency>

 2. 创建 Filter 类

新建一个软件包,名为Filter,在里面新建一个名为 TokenFilter 的类,然后让其继承 Filter,用  WebFilter 标注这个类,就像这样:

@WebFilter("/*")  //在向这个 url 请求时,会使用该拦截器
public class TokenFilter implements Filter {

}

在 Filter 接口中,有三个方法,其中只有一个名为 doFilter 的方法需要实例化,接口内容如下:

public interface Filter {
    default void init(FilterConfig filterConfig) throws ServletException {
    }


    void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException;

    default void destroy() {
    }
}

然后在我们刚刚新建的TokenFilter中,实现这个方法,然后所有的方法:

@WebFilter("/*")  //在向这个 url 请求时,会使用该拦截器
public class TokenFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {


    }
}

3. Filter 中的内容

FIlter的执行过程可大致分为三个步骤:放行前、放行、放行后,主要的运行过程是:请求来了 -> 访问的拦截的url -> 进行拦截 -> 执行放行前的操作 -> 放行或其他操作 -> 相应请求 -> 执行放行后的操作。

所有的操作都要写在doFilter中,以 chain.doFilter(request, response) 为分界线:

@WebFilter("/*")  //在向这个 url 请求时,会使用该拦截器
public class TokenFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        
        //这里写放行前的代码        
        code
        

        //这段代码是放行的意思
        chain.doFilter(request, response);


        //这里写放行后的代码 
        code

    }
}

4. 拦截Token

一般 Token 放在在 HTTP 中的header里一个叫做 Authorization 的值里的。首先将传进来的 request 和 response 转化为 HttpServlet 的:

         //将 ServletRequest 转换为 HttpServletRequest
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

然后用一个 String 将 httpRequest 里 Authorization 的值装进去,里面的值就是 token,然后就可以对 token 进行操作了:

        //处理请求头(获取 Token)
        String token =httpRequest.getHeader("Authorization");

5.启动拦截

我们将代码完善一下,然后正常启动spring:

@WebFilter("/user/loginVip")  //在向这个 url 请求时,会使用该拦截器
public class TokenFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        //将 ServletRequest 转换为 HttpServletRequest
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        //处理请求头(获取 Token)
        String token =httpRequest.getHeader("Authorization");


        //验证Token逻辑
        if(token == null /*|| !isValidToken()*/){
            System.out.println("没有找到");
        }
        else{
            System.out.println("拦截到 Token:" + token);
            ((HttpServletResponse) response).setHeader("Authorization", token);
            chain.doFilter(request, response);
        }
    }
}

在 WebFilter 中的参数表示,当向这个url发送请求时,可以触发这个Filter。

这段代码的功能是:

在请求的 HTTP 的 header 中,接收 token,如果 token 是 null 就在控制台直接输出文字,然后就没有然后了(没有执行 chain.doFilter 就相当于没有放行,请求在这里直接被拦截了)

如果有就输出相应内容,并且在 servlet  response 时,在 HTTP 的 header 中,加上 Authorzation,值为 token,然后放行代码,在 servlet 处理完业务后,将响应送到 Filter 层时,输出文字内容

6.运行测试

用自己的登录功能实验一下,会得到以下结果:

如果登录时有token,则在控制台上会有以下结果:

发送的 http 中的 header 也包含有token:

如果没有 token, 则控制台会有如下结果:

因为没有请求直接被拦截,所以没有response,前端什么都接收不到

总结

以上就是对 Filter 的简单使用,我们可以用它在登录时验证 token 的有效性;用密码登录时,将 token 放到 header 中,以及验证用户是否有权限访问一些页面和功能。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐