一文搞懂Spring Boot自定义拦截器

简介: 为什么需要拦截器?

为什么需要拦截器?

在我们开发的Web系统中,资源可分为大致三类:公开资源个人资源隐私资源,比如公开资源有任何人都能看新闻、视频、文章等等,个人资源就是指系统用户的个人信息等等,隐私资源可以表示系统的后台管理、用户管理等等。

因此我们需要进行系统用户访问资源的认证规则,而Spring自带的拦截器处理器就可以很好地完成我们的需求,下面开始今天的表演!

1 场景需求分析

我们假设有三类资源,分别为公开资源个人资源隐私资源,请求路径分别对应为:

  • 公开资源:/user/getUserPublicInfo
  • 个人资源:/user/getUserInfo
  • 隐私资源:/user/getUserPrivateInfo

此外我们还需要一个别拦截后的跳转路径,防止用户在自己被拦截后还浑然不知

  • 未授权下跳转路径:/user/noAuth

下面我们罗列下访问这些资源都有什么要求

资源名称 资源路径 要求
公开资源 /user/getUserPublicInfo
个人资源 /user/getUserInfo 带上请求参数token
隐私资源 /user/getUserPrivateInfo 带上请求参数token加请求头ymx-name

2 项目架构

2.1 依赖和配置文件

我们新建Spring Boot项目,引入依赖,修改配置文件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

配置文件:

server.port=9000

2.2 项目结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1o8OoYIy-1632796828007)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928103228776.png)]

2.3 类的分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GuNFDZKq-1632796828009)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928102537477.png)]

3 具体代码实现

3.1 项目代码实现

UserController.java


/**
 * @desc: UserController
 * @author: YanMingXin
 * @create: 2021/9/27-17:12
 **/
@RestController
@RequestMapping("/user")
public class UserController {

    @Data
    @Accessors(chain = true)
    class User {
        private String name;
        private Integer age;
    }

    /**
     * 个人资源
     *
     * @return
     */
    @RequestMapping("/getUserInfo")
    public User getUserInfo() {
        return new User().setName("User:zs").setAge(12);
    }

    /**
     * 隐私资源
     *
     * @return
     */
    @RequestMapping("/getUserPrivateInfo")
    public User getUserPrivateInfo() {
        return new User().setName("PrivateUser:ls").setAge(2);
    }

    /**
     * 公开资源
     *
     * @return
     */
    @RequestMapping("/getUserPublicInfo")
    public User getUserPublicInfo() {
        return new User().setName("PublicUser:ww").setAge(15);
    }

    /**
     * 未授权跳转页面
     *
     * @return
     */
    @RequestMapping("/noAuth")
    public String noAuth() {
        return "You were intercepted~";
    }
}

WebInterceptorHandler.java

/**
 * @desc: 自定义拦截器
 * @author: YanMingXin
 * @create: 2021/9/27-17:10
 **/
@Component
public class WebInterceptorHandler implements HandlerInterceptor {

    private final String USER_TOKEN_NAME = "token";

    private final String USER_TOKEN_VALUE = "ymx";

    private final String AUTH_HEADER = "ymx-name";

    private final String PRIVATE_URL = "/user/getUserPrivateInfo";

    private final String REDIRECT_URL = "/user/noAuth";

    /**
     * 预处理回调方法
     *
     * @param request
     * @param response
     * @param handler
     * @return 返回true为继续处理,false为中断处理
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = request.getParameter(USER_TOKEN_NAME);
        String headerValue = request.getHeader(AUTH_HEADER);
        String requestURI = request.getRequestURI();
        //用户个人隐私
        if (PRIVATE_URL.equals(requestURI)) {
            if (USER_TOKEN_VALUE.equals(headerValue) && USER_TOKEN_VALUE.equals(token)) {
                return true;
            } else {
                //拦截后跳转路径
                response.sendRedirect(REDIRECT_URL);
                return false;
            }
        }
        //一般隐私
        if (USER_TOKEN_VALUE.equals(token)) {
            return true;
        }
        //拦截后跳转路径
        response.sendRedirect(REDIRECT_URL);
        return false;
    }

    /**
     * 后处理回调方法,在渲染视图之前实现处理器的后处理
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    }

    /**
     * 整个请求处理完毕回调方法,即在视图渲染完毕时回调,可用于记录日志
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

WebInterceptorConfig.java

/**
 * @desc: 拦截器配置
 * @author: YanMingXin
 * @create: 2021/9/27-17:01
 **/
@Configuration
public class WebInterceptorConfig extends WebMvcConfigurationSupport {

    /**
     * 注入自定义拦截器
     */
    @Resource
    private WebInterceptorHandler webInterceptorHandler;

    /**
     * 配置拦截器和拦截、放行路径
     *
     * @param registry
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(webInterceptorHandler)
                .excludePathPatterns("/user/getUserPublicInfo")
                .excludePathPatterns("/user/noAuth")
                .addPathPatterns("/**");
    }
}

3.2 总体分析

实现自定义拦截器:

在Spring5之前

@Component
public class WebInterceptorHandler extends WebMvcConfigurerAdapter {}

Spring5及以后

@Component
public class WebInterceptorHandler implements HandlerInterceptor {}

@Component
public class WebInterceptorHandler extends WebMvcConfigurationSupport {}

拦截器配置:

@Configuration
public class WebInterceptorConfig extends WebMvcConfigurationSupport{}

4 测试

启动项目,打开postman

4.1 访问公开路径:http://127.0.0.1:9000/user/getUserPublicInfo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0usbDvJz-1632796828011)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928103347665.png)]

4.2 访问个人路径:http://127.0.0.1:9000/user/getUserInfo

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zPinn2tP-1632796828013)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928103410257.png)]

带上需要的参数再次访问:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UuOjmKZV-1632796828015)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928103506420.png)]

4.3 访问隐私路径:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8jdS1XC8-1632796828016)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928103528767.png)]

带上参数和请求头再次访问:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rwr3BG4d-1632796828018)(一文搞懂Spring Boot自定义拦截器.assets/image-20210928103607515.png)]

测试成功!

今天的表演到此结束咯~

相关文章
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
14797 60
|
6月前
|
缓存 监控 Java
《深入理解Spring》拦截器(Interceptor)——请求处理的艺术
Spring拦截器是Web开发中实现横切关注点的核心组件,基于AOP思想,可在请求处理前后执行日志记录、身份验证、权限控制等通用逻辑。相比Servlet过滤器,拦截器更贴近Spring容器,能访问Bean和上下文,适用于Controller级精细控制。通过实现`HandlerInterceptor`接口的`preHandle`、`postHandle`和`afterCompletion`方法,可灵活控制请求流程。结合配置类注册并设置路径匹配与执行顺序,实现高效复用与维护。常用于认证鉴权、性能监控、统一异常处理等场景,提升应用安全性与可维护性。
|
7月前
|
监控 安全 Java
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
Spring Boot 通过 Actuator 模块提供了强大的健康检查功能,帮助开发者快速了解应用程序的运行状态。默认健康检查可检测数据库连接、依赖服务、资源可用性等,但在实际应用中,业务需求和依赖关系各不相同,因此需要实现自定义健康检查来更精确地监控关键组件。本文介绍了如何使用 @HealthEndpoint 注解及实现 HealthIndicator 接口来扩展 Spring Boot 的健康检查功能,从而提升系统的可观测性与稳定性。
577 0
使用 @HealthEndpoint 在 Spring Boot 中实现自定义健康检查
|
存储 人工智能 Java
【图文详解】基于Spring AI的旅游大师应用开发、多轮对话、文件持久化、拦截器实现
【图文详解】基于Spring AI的旅游大师应用开发、多轮对话、文件持久化、拦截器实现
|
9月前
|
人工智能 安全 Java
Spring Boot 过滤器 拦截器 监听器
本文介绍了Spring Boot中的过滤器、拦截器和监听器的实现与应用。通过Filter接口和FilterRegistrationBean类,开发者可实现对请求和响应的数据过滤;使用HandlerInterceptor接口,可在控制器方法执行前后进行处理;利用各种监听器接口(如ServletRequestListener、HttpSessionListener等),可监听Web应用中的事件并作出响应。文章还提供了多个代码示例,帮助读者理解如何创建和配置这些组件,适用于构建更高效、安全和可控的Spring Boot应用程序。
835 0
|
XML Java 应用服务中间件
Spring Boot 两种部署到服务器的方式
本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
3129 17
Spring Boot 两种部署到服务器的方式
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
1032 1
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
Java 微服务 Spring
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器使用实例
本文主要讲解了Spring Boot中拦截器的使用实例,包括判断用户是否登录和取消特定拦截操作两大场景。通过token验证实现登录状态检查,未登录则拦截请求;定义自定义注解@UnInterception实现灵活取消拦截功能。最后总结了拦截器的创建、配置及对静态资源的影响,并提供两种配置方式供选择,帮助读者掌握拦截器的实际应用。
715 0
|
前端开发 JavaScript Java
微服务——SpringBoot使用归纳——Spring Boot中使用拦截器——拦截器的快速使用
本文介绍了在Spring Boot中使用拦截器的方法,包括拦截器的基本原理、定义与配置步骤。拦截器是AOP的一种实现,主要用于拦截对动态资源的请求,如判断用户权限或结合WebSocket使用。文章详细讲解了通过实现`HandlerInterceptor`接口来自定义拦截器,并重写`preHandle`、`postHandle`和`afterCompletion`三个核心方法。
1678 0