Spring MVC 六 - DispatcherServlet处理请求过程
前面讲过了DispatcherServlet的初始化过程(源码角度的DispatcherServlet的具体初始化过程还没说,先放一放),今天说一下DispatcherServlet处理请求的过程。
处理过程
- WebApplicationContext绑定在当前request属性上(属性键值DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE)
- localResolver绑定在request的属性上(属性键值LOCALE_RESOLVER_ATTRIBUTE)
- themeResolver绑定在request属性上(属性键值HEME_RESOLVER_ATTRIBUTE)
- servlet容器配置了multipart resolver,并且当前请求包含multpart file,则包装当前request为MultipartHttpServletRequest。
- 匹配当前请求的handlerMappings,获取到HandlerExecutionChain,匹配getHandlerAdapter
- 调用HandlerExecutionChain的applyPreHandle方法:获取拦截器,调用拦截器的preHandle方法
- 调用HandlerAdapter的handle方法,这儿会匹配并执行Conroller方法
- 执行HandlerExecutionChain的applyPostHandle方法:调用拦截器的postHandle方法
- 执行processDispatchResult方法,其中会调用拦截器的afterCompletion方法
以上过程都被try catch包围起来了,所以才会有Spring MVC的异常处理机制:应用层不管哪里(controller、service、dao层…)抛出的异常,都会在这里被捕获到,注册到WebApplicationContext容器中的HandlerExceptionResolver beans就有机会统一处理异常。
可以通过DispatcherServlet的初始化参数来定制化其行为,参数可以通过web.xml指定,包括:
- contextClass:指定当前DispatcherServlet绑定的容器类(ConfigurableWebApplicationContext的实现类),默认为XmlWebApplicationContext 。
- contextConfigLocation:上述contextClass指定的容器类的配置文件的位置,可以指定多个配置文件,逗号分割。
- namespace:WebApplicationContext的namespace,默认[servlet-name]-servlet。
- throwExceptionIfNoHandlerFound:某一请求request没有匹配到handle的话,是否抛出NoHandlerFoundException异常,NoHandlerFoundException随后可以被HandlerExceptionResolver捕获并处理。默认情况下该参数设置为false,DispatherServlet不抛出异常、直接导航到404。注意:如果配置了默认Servlet Handler(default servlet handling)的话,那么没匹配到的request会导航到默认handler处理,永远不会出现404。
拦截
HandlerMapping支持拦截器,拦截器需实现SpringMVC的HandlerInterceptor接口(org.springframework.web.servlet),包含如下方法:
- preHandle:HandlerMapping处理请求之前发生。
- postHandle:HandlerMapping处理请求之后发生。
- afterCompletion:整个请求处理完成之后。
preHandle返回true则请求继续被处理,返回false则后续不会再处理请求。
postHandle对@ResponseBody和ResponseEntity方法几乎没有什么作用,因为response已经在postHandle之前被HandlerAdapter处理完成了,因此不可能被postHandle修改了。比如你想通过postHandle在response header中增加一个头信息是不可能的了。这种需求只能通过ResponseBodyAdvice、 Controller Advice 或者直接在RequestMappingHandlerAdapter中直接实现。
异常处理
HandleMapping、HandlerAdapter、Controller中发生的任何异常,都可以被DispatcherServlet捕获、交给HandlerExceptionResolver bean去处理异常。
SpringMVC提供如下异常处理的实现类:

异常处理链
我们可以配置多个HandlerExceptionResolver作为异常处理链(exception resolver chain)来处理异常,可以通过order属性指定其处理顺序,order值越大、在chain中排名越靠后。
HandlerExceptionResolver可以返回:
- ModelAndView :错误页面。
- 空ModelAndView:错误已经被处理,不需要导航到错误页面。
- Null:当前Resolver不处理,异常继续向上抛给chain中后面的Resolver,直到最后如果没有Resolver处理该异常的话,异常会抛出给Servlet容器(比如给到Tomcat,这种情况下Tomcat也不处理,可能就会直接抛出给前台)。
SpringMVC会自动配置内建的异常处理器,我们可以通过配置客户化异常处理器。SpringMVC的异常处理相对比较重要,后面我们还会从源码和应用角度做一次分析。
容器错误页面
如果异常没有被任何HandlerExceptionResolver处理,而且,如果response status被设置为4xx、5xx的话,servlet容器(比如tomcat)会导航到默认的错误处理页面,假如容器配置了错误处理页面的话。可以通过web.xml配置:
<error-page><location>/error</location>
</error-page>
以上配置需要DispatcherServlet进一步处理:
@RestController
public class ErrorController {@RequestMapping(path = "/error")public Map<String, Object> handle(HttpServletRequest request) {Map<String, Object> map = new HashMap<>();map.put("status", request.getAttribute("jakarta.servlet.error.status_code"));map.put("reason", request.getAttribute("jakarta.servlet.error.message"));return map;}
}
上一篇 Spring MVC 五 - DispatcherServlet初始化过程(续)
相关文章:
Spring MVC 六 - DispatcherServlet处理请求过程
前面讲过了DispatcherServlet的初始化过程(源码角度的DispatcherServlet的具体初始化过程还没说,先放一放),今天说一下DispatcherServlet处理请求的过程。 处理过程 WebApplicationContext绑定在当前request属性上(属…...
Python实现猎人猎物优化算法(HPO)优化BP神经网络回归模型(BP神经网络回归算法)项目实战
说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 猎人猎物优化搜索算法(Hunter–prey optimizer, HPO)是由Naruei& Keynia于2022年提出的一种最新的…...
【图论】SPFA求负环
算法提高课笔记 文章目录 基础知识例题虫洞题意思路代码 观光奶牛题意思路代码 单词环题意思路代码 基础知识 负环:环上权值之和是负数 求负环的常用方法 基于SPFA 统计每个点入队次数,如果某个点入队n次,则说明存在负环(完全…...
vue3中的吸顶导航交互实现 | VueUse插件
目的:浏览器上下滚动时,若距离顶部的滚动距离大于78px,吸顶导航显示,小于78px隐藏。使用vueuse插件中的useScroll方法和动态类名控制进行实现 1. 安装 npm i vueuse/core 2. 获得滚动距离 项目中导入࿰…...
MySql 笔记
数据结构:BTREE 二叉树:顺序增长依次查询效率低 红黑树: 数据多了深度越深,效率自然低了 HASH: 查询条件限制 B-TREE:度(degree)-节段的数据存储个数,叶节点具有 相…...
部署elasticsearch集群
创建es集群 编写一个docker-compose.yaml文件,内容如下 version: 2.2 services:es01:image: elasticsearch:7.12.1container_name: es01environment:- node.namees01- cluster.namees-docker-cluster- discovery.seed_hostses02,es03- cluster.initial_master_nod…...
CTF入门学习笔记——Crypto密码(现代密码)
文章目录 CTF入门学习笔记——Crypto密码(现代密码)因数分解因数分解 共享素数Bigrsa 低加密指数攻击(小明文攻击)crypto5 共模攻击rsa_output 广播攻击Crazy_Rsa_Tech 待补充 CTF入门学习笔记——Crypto密码(现代密码…...
(3)MyBatis-Plus待开发
常用注解 TableName MyBatis-Plus在确定操作的表时,由BaseMapper的泛型决定即实体类型决定,且默认操作的表名和实体类型的类名一致,如果不一致则会因找不到表报异常 //向表中插入一条数据 Test public void testInsert(){User user new User(null, &…...
正则表达式参考手册
修饰符 修饰符用于执行区分大小写和全局匹配: 修饰符描述i执行对大小写不敏感的匹配。g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。m执行多行匹配。 方括号 方括号用于查找某个范围内的字符: 表达式描述[abc]查找方括号之间…...
【农业生产模拟】WOFOST模型与PCSE模型实践
查看原文>>>【农业生产模拟】WOFOST模型与PCSE模型实践 实现作物产量的准确估算对于农田生态系统响应全球变化、可持续发展、科学粮食政策制定、粮食安全维护都至关重要。传统的经验模型、光能利用率模型等估产模型原理简单,数据容易获取,但是…...
PHP8中获取并删除数组中最后一个元素-PHP8知识详解
在php8中,array_pop()函数将返回数组的最后一个元素,并且将该元素从数组中删除。语法格式如下: array_pop(目标数组) 获取并删除数组中最后一个元素,参考代码: <?php $stu array(s001>明明,s002>亮亮,s…...
JS原理-笔记(1/3)
JS原理-笔记(1/3) 知识点自测 今天课程中涉及到的已学习知识点 函数的call方法-文档链接 // 以指定的this调用函数,并通过 从第二个参数开始依次传递参数 function func(food,drink){console.log(this)console.log(food)console.log(drink)…...
Django创建应用、ORM的进阶使用及模型类数据库迁移
1 Django项目创建第一个应用 Django 项目就是基于 Django 框架开发的 Web 应用,它包含了一组配置和多个应用,我们把应用称之为 App,在前文中对它也做了相应的介绍,比如 auth、admin,它们都属于 APP。 一个 App 就是一…...
tcpdump 如何使用
tcpdump 是一个在Unix和类Unix系统上运行的网络抓包工具,它用于捕获网络流量并将其转储到文件中以供后续分析。tcpdump非常强大,可以用于监控、调试和分析网络通信,用于排查网络问题以及安全审计。以下是关于如何使用tcpdump的详细介绍&#…...
goweb入门
创建gomod项目 go mod init web01新建main.go package mainimport ("fmt""net/http" )func handler(writer http.ResponseWriter, request *http.Request) {fmt.Fprintf(writer, "Hello World,%s!", request.URL.Path[1:]) } func main() {fmt…...
【python爬虫】批量识别pdf中的英文,自动翻译成中文下
不管是上学还是上班,有时不可避免需要看英文文章,特别是在写毕业论文的时候。比较头疼的是把专业性很强的英文pdf文章翻译成中文。我记得我上学的时候,是一段一段复制,或者碰到不认识的单词就百度翻译一下,非常耗费时间。之前的文章提供了批量识别pdf中英文的方法,详见【…...
YApi 新版如何查看 http 请求数据
YApi 新版如何查看 http 请求数据 因chrome 安全策略限制,在 cross-request 升级到 3.0 后, 不再支持文件上传功能,并且需要通过以下方法查看 network:1.首先在chrome 输入 > chrome://extensions打开扩展页2.开启开发者模式3.点击 cross…...
自动驾驶(apollo)
💓博主csdn个人主页:小小unicorn 🚚代码仓库:小小unicorn的代码仓库🚚 🌹🌹🌹关注我带你学习编程知识 自动驾驶技术 引言自动驾驶的基本原理自动驾驶的技术挑战自动驾驶的潜在影响结…...
web3.0涉及的技术
非同质化代币 非同质化代币(Non-Fungible Tokens,NFTs)是一种数字资产,与传统的加密货币(如比特币或以太币)不同,它们具有独特性和不可替代性。NFTs 是基于区块链技术的数字资产,用…...
26. 不相同的字符串(第一期模拟笔试)
题目:样例: 输入 1 abab 输出 2 思路: 这里的题目要求我们要最少操作删除次数,我们可以先统计每个字符个数,然后开始删除,每操作删除一次,就会产生一个新字符,ans r[i] >> 1…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
c# 局部函数 定义、功能与示例
C# 局部函数:定义、功能与示例 1. 定义与功能 局部函数(Local Function)是嵌套在另一个方法内部的私有方法,仅在包含它的方法内可见。 • 作用:封装仅用于当前方法的逻辑,避免污染类作用域,提升…...
