一文搞懂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)]

测试成功!

今天的表演到此结束咯~

相关文章
|
3天前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
3天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
10天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
55 14
|
27天前
|
监控 Java 数据安全/隐私保护
如何用Spring Boot实现拦截器:从入门到实践
如何用Spring Boot实现拦截器:从入门到实践
48 5
|
1月前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
44 2
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
79 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
安全 Java 应用服务中间件
如何将Spring Boot应用程序运行到自定义端口
如何将Spring Boot应用程序运行到自定义端口
50 0
|
2月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
35 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
2月前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
88 2
|
3月前
|
前端开发 Java Spring
springboot自定义拦截器的简单使用和一个小例子
本文介绍了如何在Spring Boot中创建和使用自定义拦截器,通过一个登录验证的示例,演示了拦截器在MVC流程中的preHandle、postHandle和afterCompletion三个环节的作用,并说明了如何在Spring Boot配置类中注册拦截器。