springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现

简介: 这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。

导言

SpringBoot 拦截器和过滤器区别及应用

一、拦截器

  1. 拦截器是什么?
    简单的来说,就是一道阀门,在某个方法被访问之前,进行拦截,然后在之前或之后加入某些操作,拦截器是AOP 的一种实现策略。
  2. 拦截器主要做什么?
    • 对正在运行的流程进行干预。
  3. 拦截器的代码实现。拦截器也主要有三个方法:
    • 其中preHandle是在请求之前就进行调用,如果该请求需要被拦截,则返回false,否则true;
    • postHandle是在请求之后进行调用,无返回值;
    • afterCompletion是在请求结束的时候进行调用,无返回值。

二、创建项目 springboot-interceptor

  1. 根据 springboot 学习二:springboot 第一次创建 web 项目,打包项目并测试成功 博文,快速创建本项目:springboot-interceptor
  2. 项目依赖仅勾选web即可。
  3. 项目结构如下:(记得修改application配置文件的后缀为 yml)
    在这里插入图片描述

三、Interceptor 快速入门

那么在 springBoot 中如何使用拦截器呢?
步骤:

  1. 创建一个类实现 HandlerInterceptor 接口
  2. 再创建一个配置类实现 WebMvcConfigurer接口 ,重写 addInterceptors 方法

1. 创建拦截器类

创建我们自己的拦截器类并实现 HandlerInterceptor 接口。

package com.feng.springboot_interceptor.interceptor;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor....在请求处理之前进行调用(Controller方法调用之前)");
        String requestUrl = request.getRequestURI();
        System.out.println("过滤器MyFilter拦截了请求为" + requestUrl);
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor...请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
        //HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor....在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对 应的视图之后执行(主要是用于进行资源清理工作)");
        //HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

2. 修改 application.yml

修改 application.properties 加入开发接口通配地址

#凡是请求地址层级带有 open 都放行
open:
  url: /**/open/**

3. 实现 WebMvcConfigurer

创建一个 Java 实现 WebMvcConfigurer , 并重写 addInterceptors 方法。

package com.feng.springboot_interceptor.config;

import com.feng.springboot_interceptor.interceptor.MyInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebAppConfig implements WebMvcConfigurer {
    @Value("${open.url}")
    private String openUrl;

    @Bean
    public MyInterceptor getMyInterceptor() {
        return new MyInterceptor();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 拦截以 /api 开头的请求,但是排除  openUrl:/**/open/**。 即 :匹配这个(/**/open/**)URL的所有请求不拦截
        registry.addInterceptor(getMyInterceptor()).addPathPatterns("/api/**").excludePathPatterns(openUrl);
        // WebMvcConfigurer.super.addInterceptors(registry);
    }
}

4. 创建接口Interceptorcontroller

package com.feng.springboot_interceptor.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class InterceptorController {

    @GetMapping("/home/open/info")
    public String home() {
        return "欢迎来到首页";
    }

    @GetMapping("/user/interceptor")
    public String interceptor() {
        return "我被拦截了并通过了拦截器";
    }
}

5. 项目结构

在这里插入图片描述

6. 测试

  1. 带有open http://localhost:8080/api/open/home/info 不拦截
    在这里插入图片描述
  2. 不带open http://localhost:8080/api/user/interceptor 拦截
    在这里插入图片描述
    在这里插入图片描述

四、拦截校验用户是否登录实战

1. 加入需要权鉴接口、未登录接口

a、加入接口

    @GetMapping("/open/unLogin")    // 带 open 放行
    public String getUnauthorized() {
        return "登录失效,请重新登录";
    }

b、全部接口

package com.feng.springboot_interceptor.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class InterceptorController {

    @GetMapping("/home/open/info") // 带 open 放行
    public String home() {
        return "欢迎来到首页";
    }

    @GetMapping("/user/interceptor")
    public String interceptor() {
        return "我被拦截了并通过了拦截器";
    }

    @GetMapping("/open/unLogin")    // 带 open 放行
    public String getUnauthorized() {
        return "登录失效,请重新登录";
    }
}

2. 修改拦截器校验逻辑

package com.feng.springboot_interceptor.interceptor;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class MyInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor....在请求处理之前进行调用(Controller方法调用之前)");
        String requestUrl = request.getRequestURI();
        System.out.println(requestUrl + "被 MyInterceptor 拦截了"); //判断是否携带凭证就可以了

        String token = request.getHeader("token");
        if (StringUtils.isEmpty(token)) {
            request.getRequestDispatcher("/api/open/unLogin").forward(request, response);
            return false;
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor...请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
        //HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor....在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对 应的视图之后执行(主要是用于进行资源清理工作)");
        //HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

3. 测试

a. 首先访问 开放接口

http://localhost:8080/api/home/open/info
在这里插入图片描述
在这里插入图片描述

b. 访问 需权鉴接口

  1. 带 token
    http://localhost:8080/api/user/interceptor
    在这里插入图片描述

在这里插入图片描述

  1. 不带 token:http://localhost:8080/api/user/interceptor
    在这里插入图片描述

在这里插入图片描述

相关文章
|
2天前
|
编解码 Java 程序员
写代码还有专业的编程显示器?
写代码已经十个年头了, 一直都是习惯直接用一台Mac电脑写代码 偶尔接一个显示器, 但是可能因为公司配的显示器不怎么样, 还要接转接头 搞得桌面杂乱无章,分辨率也低,感觉屏幕还是Mac自带的看着舒服
|
3天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1540 5
|
1月前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
7天前
|
人工智能 Rust Java
10月更文挑战赛火热启动,坚持热爱坚持创作!
开发者社区10月更文挑战,寻找热爱技术内容创作的你,欢迎来创作!
578 22
|
3天前
|
存储 SQL 关系型数据库
彻底搞懂InnoDB的MVCC多版本并发控制
本文详细介绍了InnoDB存储引擎中的两种并发控制方法:MVCC(多版本并发控制)和LBCC(基于锁的并发控制)。MVCC通过记录版本信息和使用快照读取机制,实现了高并发下的读写操作,而LBCC则通过加锁机制控制并发访问。文章深入探讨了MVCC的工作原理,包括插入、删除、修改流程及查询过程中的快照读取机制。通过多个案例演示了不同隔离级别下MVCC的具体表现,并解释了事务ID的分配和管理方式。最后,对比了四种隔离级别的性能特点,帮助读者理解如何根据具体需求选择合适的隔离级别以优化数据库性能。
201 3
|
10天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
10天前
|
Linux 虚拟化 开发者
一键将CentOs的yum源更换为国内阿里yum源
一键将CentOs的yum源更换为国内阿里yum源
578 5
|
23天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
6天前
|
XML 安全 Java
【Maven】依赖管理,Maven仓库,Maven核心功能
【Maven】依赖管理,Maven仓库,Maven核心功能
233 3
|
9天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
327 2