【SpringMVC】| 拦截器 | 跨域请求 | 原理详解 | 代码实操

news2025/1/13 15:37:04

目录

  • 一. 🦁 前言
  • 二. 🦁 拦截器 & 跨域请求
    • 1. 拦截器
      • Ⅰ. 拦截器和过滤器(Filter)的区别
      • Ⅱ. 拦截器的使用步骤
          • 1. 创建SpringBoot项目,添加Spring Web依赖
          • 2. 创建控制器方法
          • 3. 创建拦截器类
          • 4. 编写JSP页面
          • 5. 配置Interceptor核心配置类
          • 6. 拦截器链与执行顺序
      • Ⅲ. 实操——拦截器过滤敏感词案例
    • 2. 跨域请求
      • Ⅰ.控制器接收跨域请求
        • 案例 一
        • 方案二
  • 三. 🦁 最后

一. 🦁 前言

Spring MVC 是 Spring 框架的一部分,主要用于构建 Web 应用程序和 RESTful 服务。Spring MVC 拦截器是一种在请求到达控制器之前或响应返回视图之前对请求进行处理的机制。它可以对请求进行拦截和修改,比如在请求中添加一些头信息、记录请求日志、进行身份验证等。跨域请求则是指在浏览器中发起的与当前页面所在域名不同的请求,例如从前端的一个页面向后端的另一个域名发起 AJAX 请求。为了保证安全性与可控性,通常需要对跨域请求进行一些限制和处理。Spring MVC 提供了一些用于处理跨域请求的解决方案,例如使用 CORS 或 JSONP 等。

二. 🦁 拦截器 & 跨域请求

1. 拦截器

image-20230422092510838

SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的

请求并做相应的处理,通常应用在权限验证记录请求信息的日志判断用户是否登录等功能上。

Ⅰ. 拦截器和过滤器(Filter)的区别

  • 拦截器是SpringMVC组件,而过滤器是Servlet组件。

  • 拦截器不依赖Web容器,过滤器依赖Web容器(Java EE 的组件)。

  • 拦截器只能对控制器请求起作用,而过滤器则可以对所有的请求起作用。

  • 拦截器可以直接获取IOC容器中的对象,而过滤器就不太方便获取

Ⅱ. 拦截器的使用步骤

tips:

咱们在学SpringMVC时,肯定是通过配置文件来配置拦截器的,现在狮子使用Springboot来搭建SpringMVC,就不需要写配置文件那么繁琐!!!可以使用WebMvcConfigurer接口来配置拦截器链,从而替代Spring MVC中的拦截器配置文件(mvc-dispatcher-servlet.xml,详细流程如下:

1. 创建SpringBoot项目,添加Spring Web依赖
2. 创建控制器方法
@RequestMapping("/m1")
public String m1(){
  System.out.println("控制器方法");
  return "result";
}
3. 创建拦截器类

该类实现HandlerInterceptor接口,需要重写三个方法:

preHandle:请求到达Controller前执行的方法,返回值为true通过拦截器,返回值为false被拦截器拦截。

postHandle:跳转到JSP前执行的方法。

afterCompletion:跳转到JSP后执行的方法。

// 拦截器类
public class MyInterceptor implements HandlerInterceptor {
  // 请求到达Controller前执行
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    System.out.println("请求到达Controller前");
    // 如果return false则无法到达Controller
    return true;
   }


  // 跳转到JSP前执行,此时可以向Request域添加数据
  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    System.out.println("跳转到JSP前");
    request.setAttribute("name","百战");
   }


  // 跳转到JSP后执行,此时已经不能向Request域添加数据
  @Override
  public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
    System.out.println("跳转到JSP后");
    request.setAttribute("age",10);
   }
}

4. 编写JSP页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>结果</title>
  </head>
  <body>
    <h3>name:${requestScope.name}</h3>
    <h3>age:${requestScope.age}</h3>
  </body>
</html>
5. 配置Interceptor核心配置类
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 InterceptorConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new UserInterceptor())	// addInterceptor()方法添加一个拦截器
                .addPathPatterns("/campus/**")			// addPathPatterns()方法指定拦截的路径
                .addPathPatterns("/edu/**")
                .addPathPatterns("/info/**")
                .addPathPatterns("/pos/**")
                .addPathPatterns("/project/**")
                .addPathPatterns("/project/**");
        		.excludePathPatterns("/login"); // 排除/login请求,   excludePathPatterns()方法则指定不拦截的路径
    }
}
6. 拦截器链与执行顺序

image-20230422095255645

如果一个URL能够被多个拦截器所拦截,全局拦截器最先执行,其他拦截器根据配置文件中配置的从上到下执行。

tips:

  • preHandle()顺序执行,postHandle()、afterComletion()逆序执行。

  • 只要有一个preHandle()拦截,后面的preHandle(),postHandle()都不会执行。

  • 只要相应的preHandle()放行,afterComletion()就会执行。

Ⅲ. 实操——拦截器过滤敏感词案例

在Spring Boot中,配置拦截器链可以通过实现WebMvcConfigurer接口来完成。

  1. 创建一个WordFilter类,实现HandlerInterceptor接口,在preHandle方法中对请求参数中的敏感词进行过滤
@Component
public class WordFilter implements HandlerInterceptor {

    @Autowired
    private WordService wordService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String wordString = request.getParameter("words"); // 假设敏感词参数名为"words"
        if (wordString != null) {
            String[] words = wordString.split(",");
            List<String> sensitiveWords = wordService.getAllWords(); // 获取所有敏感词
            for (String word : words) {
                if (sensitiveWords.contains(word)) { // 判断是否为敏感词
                    // 如果是敏感词,则输出提示信息并返回false,终止请求
                    response.setContentType("text/html;charset=UTF-8");
                    PrintWriter out = response.getWriter();
                    out.print("<script>alert('请求中包含敏感词 " + word + ",请修改后重试!');</script>");
                    out.flush();
                    out.close();
                    return false;
                }
            }
        }
        // 如果请求中没有敏感词,则返回true,继续请求
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // do nothing
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // do nothing
    }
}
  1. 创建一个WordService类,用于获取所有敏感词。这里假设将敏感词保存在一个List中。在实际应用中,可以将敏感词保存在数据库中,并提供相关的增删查改接口。
@Service
public class WordService {

    private static final List<String> WORD_LIST = Arrays.asList("敏感词1", "敏感词2", "敏感词3");

    public List<String> getAllWords() {
        return WORD_LIST;
    }
}
  1. WebConfig类中注册拦截器WordFilter
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private WordFilter wordFilter;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(wordFilter).addPathPatterns("/**");
    }
}

到此为止,敏感词过滤的示例已经完成

2. 跨域请求

同源策略是浏览器的一个安全功能。同源,指的是两个URL的协议,域名,端口相同。浏览器出于安全方面的考虑,不同源的客户

端脚本在没有明确授权的情况下,不能读写对方资源。(即前端策略,跟后端没啥关系)

image-20230422102723704

当请求URL的协议、域名、端口三者中任意一个与当前页面URL不同时即为跨域。浏览器执行JavaScript脚本时,会检查当前请求是否

同源,如果不是同源资源,就不会被执行。

哪些不受同源策略限制:

  • 页面中的 跳转、表单提交不会受到同源策略限制的。

  • 静态资源引入也不会受到同源策略限制。如嵌入到页面中的

Ⅰ.控制器接收跨域请求

image-20230422103002043

SpringMVC提供了注解**@CrossOrigin**解决跨域问题。

案例 一

在Spring Boot中,可以通过添加一个WebMvcConfigurer bean来配置跨域请求。以下是一个示例:

  1. 首先,在application.properties中添加以下配置:
# 允许跨域请求的域名(*表示允许任何域名)
spring.mvc.cross-origin.allowed-origins=*
# 允许跨域请求的HTTP方法
spring.mvc.cross-origin.allowed-methods=GET,POST,PUT,DELETE
# 允许跨域请求的HTTP头部信息
spring.mvc.cross-origin.allowed-headers=*
# 是否允许发送cookie
spring.mvc.cross-origin.allow-credentials=true
  1. 创建一个WebMvcConfigurer bean并重写addCorsMappings方法,设置跨域请求规则。例如:
@Configuration
public class CorsConfig implements WebMvcConfigurer {
 
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 匹配所有路径
                .allowedOrigins("*") // 允许跨域请求的域名(*表示允许任何域名)
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许跨域请求的HTTP方法
                .allowedHeaders("*") // 允许跨域请求的HTTP头信息
                .allowCredentials(true); // 是否允许发送cookie
    }
}

以上代码中,通过addMapping方法来设置需要允许跨域的路径,使用allowedOrigins方法允许跨域请求的域名,使用allowedMethods方法允许跨域请求的HTTP方法,使用allowedHeaders方法允许跨域请求的HTTP头信息,使用allowCredentials方法设置是否允许发送cookie。

需要注意的是,如果在WebMvcConfigurer bean中配置了跨域请求规则,就不需要再在Controller层添加跨域请求注解了。例如,以下代码中就不需要使用@CrossOrigin注解了:

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

    @GetMapping("/hello")
    public String hello() {
        return "Hello, world!";
    }
}

到此为止,一个通过配置WebMvcConfigurer bean实现跨域请求的示例就完成了。

方案二

在Spring Boot中,可以使用@CrossOrigin注解来解决跨域请求,具体使用方法如下:

  1. 在Controller类或方法上添加@CrossOrigin注解。例如:
@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*", allowedHeaders = "*", methods = {RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT, RequestMethod.DELETE}, allowCredentials = "true")
public class ApiController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello, world!";
    }
}

以上代码中,@CrossOrigin注解的参数如下:

  • origins:允许跨域请求的域名,可以使用通配符*表示允许任何域名。
  • allowedHeaders:允许跨域请求的HTTP头信息。
  • methods:允许跨域请求的HTTP方法。
  • allowCredentials:是否允许发送cookie。
  1. 如果需要在多个Controller类或方法上使用相同的跨域请求规则,也可以在WebMvcConfigurer bean中配置全局的跨域请求规则。例如:
@Configuration
public class CorsConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 匹配所有路径
                .allowedOrigins("*") // 允许跨域请求的域名(*表示允许任何域名)
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许跨域请求的HTTP方法
                .allowedHeaders("*") // 允许跨域请求的HTTP头信息
                .allowCredentials(true); // 是否允许发送cookie
    }
}

以上代码中,通过addMapping方法来设置需要允许跨域的路径,使用allowedOrigins方法允许跨域请求的域名,使用allowedMethods方法允许跨域请求的HTTP方法,使用allowedHeaders方法允许跨域请求的HTTP头信息,使用allowCredentials方法设置是否允许发送cookie。

需要注意的是,如果在WebMvcConfigurer bean中配置了全局的跨域请求规则,就不需要在Controller层添加@CrossOrigin注解了。例如,以下代码中就不需要使用@CrossOrigin注解了:

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

    @GetMapping("/hello")
    public String hello() {
        return "Hello, world!";
    }
}

到此为止,一个通过@CrossOrigin注解实现跨域请求的示例就完成了。

三. 🦁 最后

到这里,SpringMVC专栏更新完成啦,欢迎小伙伴们关注学习哦!!!一起加油😄

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/494833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《理想国》读书感悟

第一卷 话题从年老谈到财富&#xff0c;引出了雪蒙拿的正义观&#xff1a;欠债还钱是正义&#xff0c;从而提出了“正义是什么”的探讨。 辩论中正义定义的演变&#xff1a; 实话实说欠债还债是正义&#xff08;商人的视角&#xff09;。报朋友以善&#xff0c;报敌人以恶是…

Springboot JSR303校验是怎么回事?

概述&#xff1a; 在做项目的过程中&#xff0c;除了要在前端进行数据校验外&#xff0c;服务端也必须做相应的校验&#xff0c;因为高手可绕过前端的校验&#xff0c;直接进入服务端调用相关的方法&#xff0c;进行资料的盗取或破坏。在前端如果使用VueElementUI的方式&#…

基于SpringBoot3从零配置SpringDoc

为了方便调试&#xff0c;更好的服务于前后端分离式的工作模式&#xff0c;我们给项目引入Swagger。 文章目录 1. SpringFox2. SpringDoc2.1 引入依赖2.2 配置文件2.3 语法2.4 使用示例Tag 用于标识controllerOperation 用于标识方法Schema 用于标识实体类和实体类的属性ApiRes…

Unity Nsight Graphcis 使用

前言 在渲染Profile中&#xff0c;大家经常喜欢使用Renderdoc软件, 之前我的一篇博客也介绍Renderdoc Profile渲染的流程 RenderDoc Debug UE4 Shader_ue4 debug shader_带帯大师兄的博客-CSDN博客 Renderdoc适合查看Draw哪一步出差了&#xff0c;导致效果不符合理想&#xf…

webpack : 无法加载文件 D:\...\node-v18.16.0-win-x64\webpack.ps1,因为在此系统上禁止运行脚本

用idea打开项目时&#xff0c;安装webpack打包的包之后&#xff0c;由于组策略问题拒绝执行脚本 解决方法 1、cmd打开命令行。输入&#xff1a;powershell 出现 PS 证明已经进入组策略模式 2、输入&#xff1a;get-executionpolicy&#xff0c;查看策略 ​ 输入&#xff1a…

浅谈线程池

浅谈线程池 1、线程池 1.1、线程池介绍 线程池是一种多线程处理形式&#xff0c;处理过程中将任务添加到队列&#xff0c;然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小&#xff0c;以默认的优先级运行&#xff0c;并处于多线程…

Golang每日一练(leetDay0057) 缺失区间、最大间距

目录 163. 缺失的区间 Missing Ranges &#x1f31f;&#x1f31f; 164. 最大间距 Maximum Gap &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏 Java每日一练 专栏…

空闲任务与阻塞延时(笔记)

目录 前言 空闲任务实现空闲任务1、定义空闲任务栈2、定义空闲任务的任务控制块4、定义空闲任务主体 实现阻塞延时vTaskDelay()函数任务与空闲任务切换的例子&#xff1a;vTaskSwitchContext()函数SysTick中断服务函数更新系统时基 SysTick初始化函数实验仿真 前言 软件延时是…

牛客网专项练习Pytnon分析库(二)

1.Z-score标准化公式&#xff0c;,中的σ表示的是什么&#xff08;C&#xff09;。 A.总体平均值 B.数据的方差 C.数据的标准差 D.数据的众数 解析&#xff1a; Z-score标准化也叫标准差标准化法&#xff0c;其中X表示数据样本值&#xff0c;μ表示数据样本的平均值&#x…

婚姻的本质,不是爱情

婚姻的本质&#xff0c;不是爱情 结婚是为了爱情么&#xff1f;普通人或许以为是&#xff0c;但实际并不是。如果你是为了爱情&#xff0c;那你不需要结婚。什么叫爱情。所谓爱情&#xff0c;就是你对她朝思暮想&#xff0c;时时刻刻都想和她在一起。而她也对你朝思暮想&#…

Vue学习笔记1 - Vue是什么?

1&#xff0c;Vue概念 官网上&#xff08;简介 | Vue.js&#xff09; 上说&#xff0c; Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。 这个还好理解&#xff0c;就是说它是一款前端框架&#xff0c;用于构建 前端界面的。 但是它…

NewBing 还无法访问的几个问题

大部分的AI自媒体都在说&#xff0c;Bing new已经向全世界开放了&#xff0c;我也凑一下这个热闹&#xff0c;用Edge浏览器打开&#xff0c;访问https://www.bing.com/new?ccus 想体验一下Bing new的效果&#xff0c;结果如下&#xff1a; 相信很多人都碰到了这个问题 此体验…

Windows上使用CLion配置OpenCV环境,CMake下载,OpenCV的编译,亲测可用的方法(一)

一、Windows上使用CLion配置OpenCV环境,亲测可用的方法: Windows上使用CLion配置OpenCV环境 教程里的配置: widnows 10 clion 2022.1.1 mingw 8.1.0 opencv 4.5.5 Cmake3.21.1 我自己的配置: widnows 10 clion 2022.2.5 mingw 8.1.0 https://sourceforge.net/projects/min…

二十三种设计模式第三篇--抽象工厂模式

介绍 抽象工厂模式&#xff08;Abstract Factory Pattern&#xff09;是围绕一个超级工厂创建其他工厂&#xff0c;该超级工厂又称为其他工厂的工厂。 这种类型的设计模式属于创建型模式&#xff0c;它提供了一种创建对象的最佳方式。 在抽象工厂模式中&#xff0c;接口是负责…

对标世界一流|亚马逊供应链管理经验借鉴

当前电商零售行业竞争日趋激烈&#xff0c;服务标准的提升、产品价格的竞争力等因素&#xff0c;导致企业经营成本持续上升&#xff0c;供应链的管理水平已经成为零售行业成败的关键。然而在电商零售行业的红海竞争中&#xff0c;亚马逊却始终保持着高速增长的态势&#xff0c;…

港联证券|4连板的AI+传媒概念股火了,近5亿资金抢筹

今天&#xff0c;沪深两市共51股涨停&#xff0c;除掉10只ST股&#xff0c;合计41股涨停。别的&#xff0c;11股封板未遂&#xff0c;全体封板率为81%。 涨停战场&#xff1a;长江传媒封单量最高 从收盘涨停板封单量来看&#xff0c;长江传媒封单量最高&#xff0c;有39.96万手…

STL初识

什么是STL? 菜鸟教程的解释是&#xff1a;C STL&#xff08;标准模板库&#xff09;是一套功能强大的 C 模板类&#xff0c;提供了通用的模板类和函数&#xff0c;这些模板类和函数可以实现多种流行和常用的算法和数据结构&#xff0c;如向量、链表、队列、栈。 也就是说&am…

4.1 数据结构引入

目录 什么是数据结构 语言出生顺序 基本概念 数据的逻辑结构 数据的存储结构 顺序储存 链式存储 索引存储 散列存储 基本概念 第一卷《基本算法》 第二卷《半数字化算法》 第三卷《排序与搜索》 第四卷《组合算法》 什么是数据结构 数据结构研究计算机数据间关系…

每日学术速递5.5

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CL 1.ResiDual: Transformer with Dual Residual Connections 标题&#xff1a;ResiDual&#xff1a;具有双剩余连接的Transformer 作者&#xff1a;Shufang Xie, Huishuai Zhang, Jun…

制造企业选择库存管理条码工具需要关注哪些点?

Dynamsoft Barcode Reader SDK 一款多功能的条码读取控件&#xff0c;只需要几行代码就可以将条码读取功能嵌入到Web或桌面应用程序。这可以节省数月的开发时间和成本。能支持多种图像文件格式以及从摄像机或扫描仪获取的DIB格式。使用Dynamsoft Barcode Reader SDK&#xff0c…