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

测试成功!

今天的表演到此结束咯~

相关文章
|
4天前
|
存储 运维 安全
Spring运维之boot项目多环境(yaml 多文件 proerties)及分组管理与开发控制
通过以上措施,可以保证Spring Boot项目的配置管理在专业水准上,并且易于维护和管理,符合搜索引擎收录标准。
15 2
|
1月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
52 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
1月前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
25 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
1月前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
58 2
|
2月前
|
前端开发 Java Spring
springboot自定义拦截器的简单使用和一个小例子
本文介绍了如何在Spring Boot中创建和使用自定义拦截器,通过一个登录验证的示例,演示了拦截器在MVC流程中的preHandle、postHandle和afterCompletion三个环节的作用,并说明了如何在Spring Boot配置类中注册拦截器。
|
3月前
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
|
3月前
|
JSON 安全 Java
|
3月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
170 0
|
3月前
|
前端开发 JavaScript Java
Spring Boot中使用拦截器
本节主要介绍了 Spring Boot 中拦截器的使用,从拦截器的创建、配置,到拦截器对静态资源的影响,都做了详细的分析。Spring Boot 2.0 之后拦截器的配置支持两种方式,可以根据实际情况选择不同的配置方式。最后结合实际中的使用,举了两个常用的场景,希望读者能够认真消化,掌握拦截器的使用。
|
4月前
|
消息中间件 Java Kafka
Spring boot 自定义kafkaTemplate的bean实例进行生产消息和发送消息
Spring boot 自定义kafkaTemplate的bean实例进行生产消息和发送消息
182 5