Spring MVC拦截器和跨域请求

一、拦截器简介

SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。
拦截器和过滤器的区别

  1. 拦截器是SpringMVC组件,而过滤器是Servlet组件。
  2. 拦截器不依赖Web容器,过滤器依赖Web容器。
  3. 拦截器只能对控制器请求起作用,而过滤器则可以对所有的请求起作用。
  4. 拦截器可以直接获取IOC容器中的对象,而过滤器就不太方便获取。 

二、拦截器使用

接下来我们使用SpringMVC拦截器,首先使用maven创建SprinMVC的web项目

2.1 控制器方法

package com.example.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;@Controller
public class MyController1 {@RequestMapping ("/m1")public String m1(){System.out.println("控制器方法");return "result";}
}

2.2 编写拦截器类

创建拦截器类,该类实现HandlerInterceptor接口,需要重写三个方法:

  1. preHandle:请求到达Controller前执行的方法,返回值为true通过拦截器,返回值为false被拦截器拦截。
  2. postHandle:跳转到JSP前执行的方法
  3. afterCompletion:跳转到JSP后执行的方法
package com.example.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Scanner;public class MyInterceptor implements HandlerInterceptor {// 请求到达Controller前执行@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.print("请求到达Controller前\t");// 如果return false则无法到达Controller// 控制台输入决定是否进入ControllerSystem.out.print("控制台输入决定是否进入Controller: ");Scanner scanner = new Scanner(System.in);boolean flag;flag = scanner.nextBoolean();return flag;}// 跳转JSP前执行,此时可以向Request域添加数据@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.print("跳转JSP前\t");/*System.out.print("控制台输入决定是否添加数据: ");Scanner scanner = new Scanner(System.in);boolean flag;flag = scanner.nextBoolean();if(flag)*/request.setAttribute("name","HQX");}// 跳转JSP后执行,此时已经不能向Request域添加数据@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("跳转到JSP后");request.setAttribute("age",10);}
}

 OK,首先我们这里到达控制器前和是否进入控制器还有是否跳转JSP,跳转到JSP后都有对应的提示。 

2.3 JSP页面

result.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>

这里把我们控制台输入的name响应到前端页面,但是age注定是没有属性的,因为跳转到JSP后才添加注定是没有意义的。

2.4 配置拦截器

接下来我们需要在SpringMVC核心配置文件中配置拦截器

<!-- 配置拦截器-->
<mvc:interceptors> <mvc:interceptor>    <!-- 配置拦截器的作用路径-->   <mvc:mapping path="/**"/>    <!-- 拦截器对象 -->   <bean class="com.itbaizhan.interceptor.MyInterceptor"/> </mvc:interceptor>
</mvc:interceptors>

2.5 测试结果

OK,第一次输入true后后面的提示信息也是可以出来的。已经成功拦截了

2.6 全局拦截器

全局拦截器可以拦截所有控制器处理的URL,作用等于/**,配置方式如下:

<!-- 配置拦截器 -->
<mvc:interceptors> <!-- 全局拦截器 -->  <bean class="com.itbaizhan.interceptor.MyInterceptor"></bean>
</mvc:interceptors>

三、拦截器链与执行顺序

如果一个URL能够被多个拦截器所拦截,全局拦截器最先执行,其他拦截器根据配置文件中配置的从上到下执行,但是我实操下来发现并不是这样。接下来我来验证一下我的想法,再配置一个拦截器2:

3.1 拦截器2

package com.example.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Scanner;public class MyInterceptor2 implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.print("拦截器2:请求到达Controller前\t");// 如果return false则无法到达Controller// 控制台输入决定是否进入ControllerSystem.out.print("控制台输入决定是否进入Controller: ");Scanner scanner = new Scanner(System.in);boolean flag;flag = scanner.nextBoolean();return flag;}// 跳转JSP前执行,此时可以向Request域添加数据@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.print("拦截器2:跳转JSP前\t");/*System.out.print("控制台输入决定是否添加数据: ");Scanner scanner = new Scanner(System.in);boolean flag;flag = scanner.nextBoolean();if(flag)*/request.setAttribute("age","10");}// 跳转JSP后执行,此时已经不能向Request域添加数据@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("拦截器2:跳转到JSP后");request.setAttribute("age",10);}
}

这里再配置一个拦截器,为了更能体现拦截器的拦截顺序。 

3.2 配置拦截器链

    <!-- 配置拦截器--><mvc:interceptors><!-- 拦截器1 --><mvc:interceptor><!-- 配置拦截器的作用路径(没有该作用路径标签则是全局拦截器) --><mvc:mapping path="/m1"/><!-- 拦截器对象 --><bean class="com.example.interceptor.MyInterceptor"/></mvc:interceptor><!-- 拦截器2 --><mvc:interceptor><!-- 配置拦截器的作用路径(没有该作用路径标签则是全局拦截器) --><mvc:mapping path="/m1"/><!-- 拦截器对象 --><bean class="com.example.interceptor.MyInterceptor2"/></mvc:interceptor><!-- 全局拦截器 --><bean class="com.example.interceptor.GlobalInterceptor"/></mvc:interceptors>

我们这里测试的拦截器1,2拦截路径都是/m1,我们把全局拦截器放在最后看一下执行顺序是如何的,如果按照上面的说法的话,则应该先提示全局拦截器,再拦截器1,拦截器2的提示信息。接下来我们来看一下实际结果吧。 

3.3 测试结果

 我们可以看到当访问/m1的时候,首先进入控制器前出现的顺序是拦截器1,然后拦截器2,最后是全局拦截器,然后跳转JSP前的顺序才是全局拦截器、拦截器2,拦截器1,跳转JSP后的也是如此。

四、拦截器过滤敏感词案例

接下来我们编写一个拦截器案例,需求如下:
在系统中,我们需要将所有响应中的一些敏感词替换为 *** ,此时可以使用拦截器达到要求: 

4.1  编写控制方法

    @RequestMapping("/m2")public String m2(Model model){model.addAttribute("name","大笨蛋");return "result";}

4.2 创建敏感词拦截器

package com.example.interceptor;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Set;public class SensitiveWordInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {// 敏感词列表String[] sensitiveWords = {"坏人","暴力","笨蛋"};// model中所有数据if(modelAndView!=null) {Map<String, Object> model = modelAndView.getModel();Set<Map.Entry<String, Object>> entries = model.entrySet();// 遍历modelfor (Map.Entry<String, Object> entry : entries) {String key = entry.getKey();String value = entry.getValue().toString();// 将model值和敏感词列表遍历比对for (String sensitiveWord : sensitiveWords) {// 如果model包含敏感词,则替换if (value.contains(sensitiveWord)) {String newStr = value.replaceAll(sensitiveWord, "***");model.put(key, newStr);}}}}}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {}
}

4.3 配置拦截器

    <!-- 敏感词拦截器 --><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.example.interceptor.SensitiveWordInterceptor"/></mvc:interceptor>

4.4 测试结果

OK,我们可以发现笨蛋确实是被换成了***。 

五、跨域请求

5.1 同源策略

同源策略是浏览器的一个安全功能。同源,指的是两个URL的协议,域名,端口相同。浏览器出于安全方面的考虑,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。
哪些不受同源策略限制:

  1. 页面中的 <a> 跳转、表单提交不会受到同源策略限制的。
  2. 静态资源引入也不会受到同源策略限制。如嵌入到页面中的 <script src=""> , <img src=""> ,<link href=""> 等。

最容易收到同源策略影响的就是Ajax请求。

5.2 跨域请求

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

当前页面URL 被请求页面URL是否跨域原因
https://www.csdn.net/https://www.csdn.net/index.html
https://www.csdn.net/http://www.csdn.net/index.html跨域协议不同
http://www.csdn.com/http://www.baidu.com/跨域主域名不同
http://csdn.csdn.net/http://www.csdn.net/跨域子域名不同
http://www.csdn.net:8080http://www.csdn.net:8081跨域端口号不同

5.3 控制器接收跨域请求

SpringMVC提供了注解@CrossOrigin解决跨域问题。用法如下:

控制器方法

    @RequestMapping("/m3")@ResponseBody@CrossOrigin("http://localhost:8080")public String m3(){System.out.println("测试跨域请求");return "success";}

编写JSP页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>跨域请求</title><script src="js/jquery-2.1.1.min.js"></script><script>$(function (){$("#btn").click(function (){$.get("http://localhost:8080/m3",function (data){console.log(data);})/*$.get("http://127.0.0.1:8080/m3",function (data){console.log(data);})*/})})</script>
</head>
<body><button id="btn" >异步请求</button>
</body>
</html>

测试结果 

当注释掉跨域注解时,运行是这样的。因为是没有跨域,但是当我们使用127.0.0.1时就会报错。

使用127.0.0.1时,且没有添加注解时的运行结果是这样的:可以看到这时就不能成功success了

​ 

当添加到注解后,无论是8080还是127.0.0.1都能够成功success了

往期专栏&文章相关导读 

     大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。

1. Maven系列专栏文章

Maven系列专栏Maven工程开发
Maven聚合开发【实例详解---5555字】

2. Mybatis系列专栏文章

Mybatis系列专栏MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 --(附实战案例--8888个字--88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发---实现增删查改和动态SQL
MyBatis注解开发---实现自定义映射关系和关联查询

3. Spring系列专栏文章

Spring系列专栏Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务

4. Spring MVC系列专栏文章   

SpringMVC系列专栏Spring MVC简介附入门案例
Spring MVC各种参数获取及获取方式自定义类型转换器和编码过滤器
Spring MVC获取参数和自定义参数类型转换器及编码过滤器
Spring MVC处理响应附案例详解
Spring MVC相关注解运用 —— 上篇

Spring MVC相关注解运用 —— 中篇

Spring MVC相关注解运用 —— 下篇
Spring MVC多种情况下的文件上传
Spring MVC异步上传、跨服务器上传和文件下载
Spring MVC异常处理【单个控制异常处理器、全局异常处理器、自定义异常处理器】
Spring MVC拦截器和跨域请求
SSM整合案例【C站讲解最详细流程的案例】

  

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小研究 - 微服务系统服务依赖发现技术综述(二)

微服务架构得到了广泛的部署与应用, 提升了软件系统开发的效率, 降低了系统更新与维护的成本, 提高了系统的可扩展性. 但微服务变更频繁、异构融合等特点使得微服务故障频发、其故障传播快且影响大, 同时微服务间复杂的调用依赖关系或逻辑依赖关系又使得其故障难以被及时、准确…

自监督去噪:Noise2Void原理和调用(Tensorflow)

文章原文: https://arxiv.org/abs/1811.10980 N2V源代码: https://github.com/juglab/n2v 参考博客&#xff1a; https://zhuanlan.zhihu.com/p/445840211https://zhuanlan.zhihu.com/p/133961768https://zhuanlan.zhihu.com/p/563746026 文章目录 1. 方法原理1.1 Noise2Noise回…

服务器数据恢复-raid5同步过程中又有一块磁盘报警的数据恢复案例

服务器数据恢复环境&#xff1a; 某研究院一台DELL存储&#xff0c;15块硬盘搭建的一组RAID5磁盘阵列。 该RAID5阵列只有一个卷组&#xff0c;该卷组占用了阵列的全部空间&#xff1b;该卷组只有一个起始位置为0扇区的XFS裸分区。 服务器故障&初检&分析&#xff1a; 该…

Spring Cloud Gateway - 新一代微服务API网关

Spring Cloud Gateway - 新一代微服务API网关 文章目录 Spring Cloud Gateway - 新一代微服务API网关1.网关介绍2.Spring Cloud Gateway介绍3.Spring Cloud Gateway的特性4.Spring Cloud Gateway的三大核心概念5.Gateway工作流程6.Gateway核心配置7.动态路由8.Predicate自定义P…

kafka第三课-可视化工具、生产环境问题总结以及性能优化

一、可视化工具 https://pan.baidu.com/s/1qYifoa4 密码&#xff1a;el4o 下载解压之后&#xff0c;编辑该文件&#xff0c;修改zookeeper地址&#xff0c;也就是kafka注册的zookeeper的地址&#xff0c;如果是zookeeper集群&#xff0c;以逗号分开 vi conf/application.conf 启…

Rust 数据类型 之 结构体(Struct)

目录 结构体&#xff08;Struct&#xff09; 定义与声明 结构体定义 结构体实例 结构体分类 单元结构体&#xff08;Unit Struct&#xff09; 元组结构体&#xff08;Tuple Struct&#xff09; 具名结构体&#xff08;Named Struct&#xff09; 结构体嵌套 结构体方法…

公网访问的Linux CentOS本地Web站点搭建指南

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 前言 在web项目中,部署的web站点需要被外部访问,则…

总结946

6:40起床 7&#xff1a;15~8:00早读&#xff0c;07年tex1,2 8:10~10:12 880第二章选填&#xff0c;题目有些综合&#xff0c;错的有些多呀&#xff0c;不要紧&#xff0c;拿下它&#xff0c;就有进步了。 10:28~11:27重做强化18讲6道题 12&#xff1a;10~2:15吃饭睡觉&…

Python实现GA遗传算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;最早是由美国的 John holland于20世…

chatgpt赋能python:如何让Python暂停?

如何让Python暂停&#xff1f; Python是一种高级编程语言&#xff0c;常用于数据分析、机器学习等领域。在Python编程中&#xff0c;我们经常需要让程序执行暂停一段时间&#xff0c;等待某些操作完成。本文将介绍如何让Python暂停&#xff0c;以及如何在SEO中优化文章标题&am…

分享 7 个不错的 AI 工具

人工智能的世界继续让我们着迷&#xff0c;近期的 OpenAI ChatGPT 掀起人们对人工智能的更大的期待&#xff0c;本文收集了 7 个人工智能 (AI) 工具&#xff0c;其中大部分易于使用&#xff0c;有些更复杂……比如构建 ML 模型。 1. GFP-GAN&#xff1a;照片修复 GFP-GAN 是一…

世界杯决赛解析

新体育 2023-01-04 10:03 发表于北京 卡塔尔世界杯决赛跌宕起伏&#xff0c;精彩纷呈。双方主帅斗智斗勇&#xff0c;妙手迭出&#xff0c;奉献了一场难得一见的对攻大战。赛后回顾&#xff0c;阿根廷的斯卡洛尼和法国的德尚用兵有很多值得学习领悟之处。从战术的角度看&#x…

谈一谈我心中的世界杯

2022卡塔尔世界杯 开赛在即 不论你喜不喜欢足球 恐怕都无法脱离 世界杯带来的影响 如果不能和人随时随地 聊上几句世界杯话题 那得多尴尬 有了这份“伪球迷速成指南” 一定能帮助你 在各种尬聊场合 脱颖而出↓↓ 1. 世界杯的由来 世界杯每4年举办一次。世界杯又称生…

十分钟带你玩转人工智能——调用百度AI接口实现文字转语音

调用别人的接口&#xff0c;实现人工智能就是站在巨人的肩膀上 打开百度AI&#xff0c;点这个控制台&#xff0c;&#xff08;你要是没有注册 &#xff0c;就注册一下&#xff0c;很简单的&#xff09; 点开这个语音技术 创建一下应用 好了以后&#xff0c;按照这个图的步…

含辞未吐,声若幽兰,史上最强免费人工智能AI语音合成TTS服务微软Azure(Python3.10接入)

所谓文无第一&#xff0c;武无第二&#xff0c;云原生人工智能技术目前呈现三足鼎立的态势&#xff0c;微软&#xff0c;谷歌以及亚马逊三大巨头各擅胜场&#xff0c;不分伯仲&#xff0c;但目前微软Azure平台不仅仅只是一个PaaS平台&#xff0c;相比AWS&#xff0c;以及GAE&am…

对接百度文心一言API---人工智能工作笔记0039

1.获取文心一言的api key 这个地址然后 点击 创建API key就可以了 然后先用postman测试一下 https://wenxin.baidu.com/moduleApi/portal/api/oauth/tokenclient_credentials application/x-www-form-urlencoded 注意 这里的参数grant_type这个是client_credentials是固定的…

斩获23项冠军,日均调用破万亿!百度交出年度AI成绩单:语音语言领衔技术突破,国产自研成大趋势...

乾明 雷刚 发自 凹非寺 量子位 报道 | 公众号 QbitAI 刚刚&#xff0c;百度一年AI成绩单官宣。 作为中国AI头雁&#xff0c;百度的成绩单不止代表巨头公司业绩&#xff0c;也代表了技术前沿现状和产业基本情况。 而且诸多进展&#xff0c;也是全新起跑线上全球AI发展的侧影&am…

AI百科:一个开启人工智能时代的综合性平台

无论是人工智能的快速发展还是AI技术在各个领域的广泛应用&#xff0c;都让我们对智能未来充满了期待和好奇。随着科技的进步&#xff0c;发现了一个好网站&#xff0c;一个集合了丰富AI工具和产品介绍的综合性网站—— AI百科。 在人工智能&#xff08;AI&#xff09;领域的快…

三大运营商乘风破浪,为什么离不开BAT等互联网企业?

【全球云观察 &#xff5c; 热点关注】对于中国联通从2017年开始的混改&#xff0c;业界关注挺多&#xff0c;之后确实带入了互联网企业如腾讯、京东、阿里、百度等参与&#xff0c;从而对中国联通在云计算、物联网等新兴技术领域的发展激发了业务的创新热情。 特别是2022年11…

周鸿祎:腾讯将来可能会是中国最大的运营商

近日&#xff0c;本刊记者采访了周鸿祎近一个小时&#xff0c;探讨未来互联网的变化、颠覆及未来&#xff0c;周鸿祎怎么看待互联网巨头的崛起对传统产业的影响和变化?在巨头林立的时代怎样才能颠覆式创新打败对手?如何选择你的对手和伙伴&#xff0c;周鸿祎说&#xff0c;“…