当前位置: 首页 > news >正文

Spring MVC 六 - DispatcherServlet处理请求过程

前面讲过了DispatcherServlet的初始化过程(源码角度的DispatcherServlet的具体初始化过程还没说,先放一放),今天说一下DispatcherServlet处理请求的过程。

处理过程

  1. WebApplicationContext绑定在当前request属性上(属性键值DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE)
  2. localResolver绑定在request的属性上(属性键值LOCALE_RESOLVER_ATTRIBUTE)
  3. themeResolver绑定在request属性上(属性键值HEME_RESOLVER_ATTRIBUTE)
  4. servlet容器配置了multipart resolver,并且当前请求包含multpart file,则包装当前request为MultipartHttpServletRequest。
  5. 匹配当前请求的handlerMappings,获取到HandlerExecutionChain,匹配getHandlerAdapter
  6. 调用HandlerExecutionChain的applyPreHandle方法:获取拦截器,调用拦截器的preHandle方法
  7. 调用HandlerAdapter的handle方法,这儿会匹配并执行Conroller方法
  8. 执行HandlerExecutionChain的applyPostHandle方法:调用拦截器的postHandle方法
  9. 执行processDispatchResult方法,其中会调用拦截器的afterCompletion方法

以上过程都被try catch包围起来了,所以才会有Spring MVC的异常处理机制:应用层不管哪里(controller、service、dao层…)抛出的异常,都会在这里被捕获到,注册到WebApplicationContext容器中的HandlerExceptionResolver beans就有机会统一处理异常。

可以通过DispatcherServlet的初始化参数来定制化其行为,参数可以通过web.xml指定,包括:

  1. contextClass:指定当前DispatcherServlet绑定的容器类(ConfigurableWebApplicationContext的实现类),默认为XmlWebApplicationContext 。
  2. contextConfigLocation:上述contextClass指定的容器类的配置文件的位置,可以指定多个配置文件,逗号分割。
  3. namespace:WebApplicationContext的namespace,默认[servlet-name]-servlet。
  4. throwExceptionIfNoHandlerFound:某一请求request没有匹配到handle的话,是否抛出NoHandlerFoundException异常,NoHandlerFoundException随后可以被HandlerExceptionResolver捕获并处理。默认情况下该参数设置为false,DispatherServlet不抛出异常、直接导航到404。注意:如果配置了默认Servlet Handler(default servlet handling)的话,那么没匹配到的request会导航到默认handler处理,永远不会出现404。

拦截

HandlerMapping支持拦截器,拦截器需实现SpringMVC的HandlerInterceptor接口(org.springframework.web.servlet),包含如下方法:

  1. preHandle:HandlerMapping处理请求之前发生。
  2. postHandle:HandlerMapping处理请求之后发生。
  3. 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可以返回:

  1. ModelAndView :错误页面。
  2. 空ModelAndView:错误已经被处理,不需要导航到错误页面。
  3. 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的初始化过程&#xff08;源码角度的DispatcherServlet的具体初始化过程还没说&#xff0c;先放一放&#xff09;&#xff0c;今天说一下DispatcherServlet处理请求的过程。 处理过程 WebApplicationContext绑定在当前request属性上&#xff08;属…...

Python实现猎人猎物优化算法(HPO)优化BP神经网络回归模型(BP神经网络回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 猎人猎物优化搜索算法(Hunter–prey optimizer, HPO)是由Naruei& Keynia于2022年提出的一种最新的…...

【图论】SPFA求负环

算法提高课笔记 文章目录 基础知识例题虫洞题意思路代码 观光奶牛题意思路代码 单词环题意思路代码 基础知识 负环&#xff1a;环上权值之和是负数 求负环的常用方法 基于SPFA 统计每个点入队次数&#xff0c;如果某个点入队n次&#xff0c;则说明存在负环&#xff08;完全…...

vue3中的吸顶导航交互实现 | VueUse插件

目的&#xff1a;浏览器上下滚动时&#xff0c;若距离顶部的滚动距离大于78px&#xff0c;吸顶导航显示&#xff0c;小于78px隐藏。使用vueuse插件中的useScroll方法​​​​​​​和动态类名控制进行实现 1. 安装 npm i vueuse/core 2. 获得滚动距离 项目中导入&#xff0…...

MySql 笔记

数据结构&#xff1a;BTREE 二叉树&#xff1a;顺序增长依次查询效率低 红黑树&#xff1a; 数据多了深度越深&#xff0c;效率自然低了 HASH&#xff1a; 查询条件限制 B-TREE&#xff1a;度&#xff08;degree&#xff09;-节段的数据存储个数&#xff0c;叶节点具有 相…...

部署elasticsearch集群

创建es集群 编写一个docker-compose.yaml文件&#xff0c;内容如下 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密码&#xff08;现代密码&#xff09;因数分解因数分解 共享素数Bigrsa 低加密指数攻击&#xff08;小明文攻击&#xff09;crypto5 共模攻击rsa_output 广播攻击Crazy_Rsa_Tech 待补充 CTF入门学习笔记——Crypto密码&#xff08;现代密码…...

(3)MyBatis-Plus待开发

常用注解 TableName MyBatis-Plus在确定操作的表时&#xff0c;由BaseMapper的泛型决定即实体类型决定&#xff0c;且默认操作的表名和实体类型的类名一致,如果不一致则会因找不到表报异常 //向表中插入一条数据 Test public void testInsert(){User user new User(null, &…...

正则表达式参考手册

修饰符 修饰符用于执行区分大小写和全局匹配: 修饰符描述i执行对大小写不敏感的匹配。g执行全局匹配&#xff08;查找所有匹配而非在找到第一个匹配后停止&#xff09;。m执行多行匹配。 方括号 方括号用于查找某个范围内的字符&#xff1a; 表达式描述[abc]查找方括号之间…...

【农业生产模拟】WOFOST模型与PCSE模型实践

查看原文>>>【农业生产模拟】WOFOST模型与PCSE模型实践 实现作物产量的准确估算对于农田生态系统响应全球变化、可持续发展、科学粮食政策制定、粮食安全维护都至关重要。传统的经验模型、光能利用率模型等估产模型原理简单&#xff0c;数据容易获取&#xff0c;但是…...

PHP8中获取并删除数组中最后一个元素-PHP8知识详解

在php8中&#xff0c;array_pop()函数将返回数组的最后一个元素&#xff0c;并且将该元素从数组中删除。语法格式如下&#xff1a; array_pop(目标数组) 获取并删除数组中最后一个元素&#xff0c;参考代码&#xff1a; <?php $stu array(s001>明明,s002>亮亮,s…...

JS原理-笔记(1/3)

JS原理-笔记&#xff08;1/3&#xff09; 知识点自测 今天课程中涉及到的已学习知识点 函数的call方法-文档链接 // 以指定的this调用函数&#xff0c;并通过 从第二个参数开始依次传递参数 function func(food,drink){console.log(this)console.log(food)console.log(drink)…...

Django创建应用、ORM的进阶使用及模型类数据库迁移

1 Django项目创建第一个应用 Django 项目就是基于 Django 框架开发的 Web 应用&#xff0c;它包含了一组配置和多个应用&#xff0c;我们把应用称之为 App&#xff0c;在前文中对它也做了相应的介绍&#xff0c;比如 auth、admin&#xff0c;它们都属于 APP。 一个 App 就是一…...

tcpdump 如何使用

tcpdump 是一个在Unix和类Unix系统上运行的网络抓包工具&#xff0c;它用于捕获网络流量并将其转储到文件中以供后续分析。tcpdump非常强大&#xff0c;可以用于监控、调试和分析网络通信&#xff0c;用于排查网络问题以及安全审计。以下是关于如何使用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 安全策略限制&#xff0c;在 cross-request 升级到 3.0 后&#xff0c; 不再支持文件上传功能&#xff0c;并且需要通过以下方法查看 network:1.首先在chrome 输入 > chrome://extensions打开扩展页2.开启开发者模式3.点击 cross…...

自动驾驶(apollo)

&#x1f493;博主csdn个人主页&#xff1a;小小unicorn &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &#x1f339;&#x1f339;&#x1f339;关注我带你学习编程知识 自动驾驶技术 引言自动驾驶的基本原理自动驾驶的技术挑战自动驾驶的潜在影响结…...

web3.0涉及的技术

非同质化代币 非同质化代币&#xff08;Non-Fungible Tokens&#xff0c;NFTs&#xff09;是一种数字资产&#xff0c;与传统的加密货币&#xff08;如比特币或以太币&#xff09;不同&#xff0c;它们具有独特性和不可替代性。NFTs 是基于区块链技术的数字资产&#xff0c;用…...

26. 不相同的字符串(第一期模拟笔试)

题目&#xff1a;样例&#xff1a; 输入 1 abab 输出 2 思路&#xff1a; 这里的题目要求我们要最少操作删除次数&#xff0c;我们可以先统计每个字符个数&#xff0c;然后开始删除&#xff0c;每操作删除一次&#xff0c;就会产生一个新字符&#xff0c;ans r[i] >> 1…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

23-Oracle 23 ai 区块链表(Blockchain Table)

小伙伴有没有在金融强合规的领域中遇见&#xff0c;必须要保持数据不可变&#xff0c;管理员都无法修改和留痕的要求。比如医疗的电子病历中&#xff0c;影像检查检验结果不可篡改行的&#xff0c;药品追溯过程中数据只可插入无法删除的特性需求&#xff1b;登录日志、修改日志…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案

随着新能源汽车的快速普及&#xff0c;充电桩作为核心配套设施&#xff0c;其安全性与可靠性备受关注。然而&#xff0c;在高温、高负荷运行环境下&#xff0c;充电桩的散热问题与消防安全隐患日益凸显&#xff0c;成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...