Spring MVC(一)— DispatcherServlet

 DispatcherServlet 是Spring MVC框架的HTTP 请求处理器的中央调度器。它具有以下的功能:

1)基于IoC容器JavaBean配置机制。

2)使用HandlerMappingl来实现请求到处理器的路由映射。

3)使用HandlerAdapter 来处理不同的处理器。

4)处理器抛出的异常解决策略由HandlerExceptionResolver指定。

5)视图解析策略可以通过ViewResolver实现指定。

6)文件上传策略通过MultipartResolver来确定。

7)Locale解析策略由LocaleResolver确定。

8)主题解析策略由ThemeResolver确定。

1 WebApplicationinitializer

Spring 中用于以编程方式配置ServletContext,来替代web.xml的方式。其本身的执行由任何Servlet3.0 容器自动引导。

图 WebApplicationInitializer UML

public class CustomWebApplicationInitializer implements WebApplicationInitializer {@Overridepublic void onStartup(ServletContext servletContext) throws ServletException {AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();webApplicationContext.register(CustomAutowireConfigurer.class); // 配置注解方式的IoC容器DispatcherServlet dispatcherServlet = new DispatcherServlet(webApplicationContext); // 可以在servlet中使用IoC容器ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcherServlet", dispatcherServlet);dynamic.addMapping("/app/*"); // 所以以/app开头的请求都会映射到servlet}
}

相当于下面的web.xml

<web-app><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/app-context.xml</param-value></context-param><servlet><servlet-name>dispatcherServlet</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class></servlet><servlet-mapping><servlet-name>dispatcherServlet</servlet-name><url-pattern>/app/*</url-pattern></servlet-mapping>
</web-app>

1.1 运行原理

javax.servlet.ServletContainerInitializer 接口是Servlet 3.0规范中定义的,当Servlet 3.0 的容器启动时,会调用其onStartup 方法。

图 ServletContainerInitializer UML

而Spring MVC通过SPI的方式,通过SpringServletContainerInitializer类来实现这个接口从而提供服务。在onStartup 方法中,会遍历IoC容器中定义的所有WebApplicationInitializer实例,并执行其onStart方法。

1.2 Servlet配置

AbstractDispatcherServletInitializer的customizeRegistration(ServletRegistration.Dynamic registration)方法用来定制Servlet。

图 Dynamic 的UML

1.2.1 WebMvcConfigurer

是一个用于配置Spring MVC的接口。允许你自定义视图解析器、消息转换器、拦截器、静态资源处理器等。使用时需将它的实例注册为容器的bean,并在其实现类上加上@EnableWebMvc注解。

图 WebMvcConfigurer UML

1.3 DispatcherServlet处理请求的流程

DispatcherServlet 处理请求的流程如下:

1)WebApplicationContext 被绑定到请求中,处理器及其他元素可以访问它。

2)Locale解析器被绑定到请求中,在解析请求时使用。

3)主题解析器被绑定到请求中,让视图等元素确定要使用的主题。

4)如果定义了文件解析器,会检查请求是否有文件,是则会把请求包装为MultipartHttpServletRequest。

5)找到一个合适的解析器,与处理程序关联的执行器会被执行。准备模型或渲染。可以呈现响应或返回视图。

2 基本组件

DispatcherServlet 通过代理模式来代理特殊的组件用以处理请求及渲染合适的响应。

2.1 HandlerInterception 拦截器

HandlerMapping 根据当前请求来找的对应的Handler。并与一系列的HandlerInterceptor封装到HandlerExecutionChain对象中。这个过程发生在容器启动的过程中。

当请求到达前端控制器(DispatcherServlet)时,DispatcherServlet会从容器取出所有的HandlerMapping实例并遍历,每个HandlerMapping 实例都会根据请求的信息(如URL、请求方法等)来确定对应的Handler(通常是Controller的一个方法)。

图 HandlerInterceptor 接口UML

preHandle 如果返回false,则其接下来的处理链都不会被执行。

2.2 HandlerExceptionResolver 异常解析器

处理在处理器方法执行过程中抛出的异常,不会处理拦截器中preHandle抛出的异常。

可以定义多个异常解析器来组成一条解析链。可以设置它们的优先级,其返回值有如下情况:

1)指向错误视图的ModelAndView。

2)如果处理了异常,则返回空的ModelAndView。

3)如果异常未解析,则返回null,供后续解析器尝试,最终可能会冒泡到Servlet容器。

@Configuration
public class CustomExceptionResolver implements HandlerExceptionResolver {@Overridepublic ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {// 设置响应内容类型为JSONresponse.setContentType("application/json;charset=UTF-8");response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);Map<String, Object> errorDetails = new HashMap<>();errorDetails.put("message", ex.getMessage());try {response.getWriter().write(errorDetails.toString());response.getWriter().flush();} catch (IOException e) {e.printStackTrace();}return new ModelAndView();}
}

2.3 LocaleResolver 区域解析器

Spring 容器可以实现国际化,通过LocaleResolver 来获取区域信息。

时区解析

LocaleContextResolver 扩展了该接口,包括了时区信息。

请求头解析

检查请求中的accept-language头部字段来获取区域信息。但该解析器不包含时区信息。

Cookie解析

检测Cookie中是否有区域与时区信息,需要在解析器中指出该cookie的属性名。过期时间(可选)

Session解析

从用户会话中检索区域和时区信息。这些信息是临时存储在HttpSession中的,会话结束时,信息会丢失。与外部会话管理机制(如Spring Session)没有直接关联。

区域拦截器

可以定义拦截器来设置区域信息。

表 LocaleResolver 的种类

2.4 MultipartResolver 文件解析器

如果设置了文件解析器(默认为空),DispatcherServlet 会检查请求是否带有文件,是,则会将请求包装为MultipartHttpServletRequest。其实现主要有两种:

CommonMultipartResolver: 是Spring在Apache Commons FileUpload组件的基础上封装而来的。允许进行更详细的配置。需要额外的依赖和配置。

StandardServletMultipartResolver: 是基于Servlet 3.0 规范来处理multipart请求。不需要额外的依赖,但要求使用支持Servlet3.0的容器。

public class CustomWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[]{RootAnnotationConfig.class};}@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{ServletAnnotationConfig.class};}@Overrideprotected String[] getServletMappings() {return new String[] {"/"};}@Overrideprotected void customizeRegistration(ServletRegistration.Dynamic registration) {MultipartConfigElement element = new MultipartConfigElement("");registration.setMultipartConfig(element);}
}

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

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

相关文章

Go 构建高效的二叉搜索树联系簿

引言 树是一种重要的数据结构&#xff0c;而二叉搜索树&#xff08;BST&#xff09;则是树的一种常见形式。在本文中&#xff0c;我们将学习如何构建一个高效的二叉搜索树联系簿&#xff0c;以便快速插入、搜索和删除联系人信息。 介绍二叉搜索树 二叉搜索树是一种有序的二叉…

探索SOCKS5代理、代理IP、HTTP与网络安全

在这个数字化时代&#xff0c;网络安全已成为我们日常生活中不可或缺的一部分。作为一名软件工程师&#xff0c;深入理解网络通信的核心技术&#xff0c;如SOCKS5代理、代理IP、HTTP协议&#xff0c;以及它们在网络安全中的应用&#xff0c;对于设计和实施安全的网络应用至关重…

uni-app 安卓手机判断是否开启相机相册权限

// 安卓相机权限 androidCameraPermiss(index){ plus.android.requestPermissions([android.permission.CAMERA],(e) > { if (e.deniedAlways.length > 0) { this.androidAuthCamera false …

【自动驾驶可视化工具】

自动驾驶可视化工具 自动驾驶可视化工具1.百度Apollo的Dreamview:2.Cruise的Worldview:3.Uber的AVS:4.Fglovex Studio: 自动驾驶可视化工具 介绍一下当前主流的自动驾驶可视化工具。 1.百度Apollo的Dreamview: Dreamview是百度Apollo平台开发的一种可视化工具&#xff0c;用…

使用Spark清洗统计业务数据并保存到数据库中

1、打开前面创建的项目“BigData-Etl-KongGuan”&#xff0c;创建一些数据库访问的工具类和辅助类。 1&#xff09;打开SpringBoot项目&#xff1a;BigData-Etl-KongGuan 2&#xff09;创建数据库访问的工具类和辅助类&#xff1a; com.qrsoft.etl.dao.IBaseDao数据库访问的通…

基于正点原子潘多拉STM32L496开发板的简易示波器

一、前言 由于需要对ADC采样性能的评估&#xff0c;重点在于对原波形的拟合性能。 考虑到数据的直观性&#xff0c;本来计划采集后使用串口导出&#xff0c;并用图形做数据拟合&#xff0c;但是这样做的效率低下&#xff0c;不符合实时观察的需要&#xff0c;于是将开发板的屏幕…

【DataWhale学习笔记】使用AgentScope调用同义倩文大模型

AgentScope AgentScope介绍 AgentScope是一款全新的Multi-Agent框架&#xff0c;专为应用开发者打造&#xff0c;旨在提供高易用、高可靠的编程体验&#xff01; 高易用&#xff1a;AgentScope支持纯Python编程&#xff0c;提供多种语法工具实现灵活的应用流程编排&#xff…

部署prometheus+Grafana可视化仪表盘监控服务

一、部署prometheus及监控仪表盘 简介 Prometheus是开源监控报警系统和时序列数据库(TSDB)。 Prometheus的基本原理是通过HTTP协议周期性抓取被监控组件的状态&#xff0c;任意组件只要提供对应的HTTP接口就可以接入监控&#xff0c;输出被监控组件信息的HTTP接口被叫做expo…

Node.js(1)

跨平台的node.js运行环境&#xff0c;使开发者可以搭建服务器端的js应用程序 它可以编写服务器端程序&#xff1b; 编写数据接口&#xff1b;提供网页资源浏览功能 前端工程化&#xff1a;开发集成的所有工具和技术 与浏览器环境的区别 node.js环境中没有DOM和BOM fs模块-读…

使用Jackson进行 JSON 序列化和反序列化

在Spring应用程序中&#xff0c;您可以通过Maven添加Jackson依赖&#xff0c;并创建一个工具类来封装对象的序列化和反序列化方法。以下是详细步骤&#xff1a; 1. 引入 Jackson 依赖 如果使用 Maven&#xff0c;您可以在 pom.xml 文件中添加以下依赖&#xff1a; <depend…

5 个适用于 Windows 10 和 11 的最佳 PDF 转 Word 转换器

PDF 文件是共享文档的首选格式&#xff0c;但是此类文件存在一些限制&#xff0c;导致难以修改或编辑。因此&#xff0c;您可能会发现自己正在寻找一种将 PDF 文件转换为 Word 或其他可编辑格式的方法。 有许多不同的 PDF 转换器&#xff0c;每种转换器提供的功能略有不同。本…

多人聊天室 (epoll - Linux网络编程)

文章目录 零、效果展示一、服务器代码二、客户端代码三、知识点1.bind() 四、改进方向五、跟练视频 零、效果展示 一个服务器作为中转站&#xff0c;多个客户端之间可以相互通信。至少需要启动两个客户端。 三个客户端互相通信 一、服务器代码 chatServer.cpp #include <…

突破编程_C++_设计模式(中介者模式)

1 中介者模式的基本概念 C中的中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;主要用于降低多个对象和类之间的通信复杂性。这种模式通过引入一个中介类来封装和处理不同类之间的通信&#xff0c;从而实现松耦合&#xff0c;使代码更易于…

每天一个数据分析题(二百零九)

某销售服饰的电商店铺想要通过漏斗模型分析转化率数据&#xff0c;关于单一漏斗模型的局限性&#xff0c;下列说法不正确的是&#xff08;&#xff09; A.不能反映趋势&#xff0c;单一漏斗模型只能反映某一时期的情况,不能看出转化率是在上升还是下降。需要增加时间维度上的比…

【unity与android的交互(一)】安卓打包相关的常见参数详解

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;Uni…

【解读】Synopsys发布2024年开源安全和风险分析报告OSSRA

软件供应链管理中&#xff0c;许可证和安全合规性至关重要。开源组件和库可降低风险&#xff0c;但需了解许可证内容。Synopsys 2023年审计发现&#xff0c;超过一半的代码库存在许可证冲突。MIT许可证是最常用的宽松许可证&#xff0c;但也与其他许可证存在不兼容风险。点此获…

AI新工具(20240315) 用户通过点击图像的特定部分实现域区图像动画; 先进的机器人操作框架

✨ 1: Follow-Your-Click 用户通过点击图像的特定部分实现域区图像动画 Follow-Your-Click 是一个开放领域的区域性图像动画创作工具&#xff0c;它可以通过简短的提示语实现图像中特定区域的动画效果。这种功能允许用户通过点击图像的特定部分并输入简短的指令&#xff08;例…

ViT学习笔记

一、Embedding层 对于标准的Transformer 模块&#xff0c;要求输入的是 token (向量 ) 序列&#xff0c;即二维矩阵 [num_token, token_dim] 在代码实现中&#xff0c;直接通过一个卷积层来实现以ViT- B/16为例&#xff0c;使用卷积核大小为 16x16 &#xff0c; stride 为 16 …

【Streamlit学习笔记】实现包含多个sheet的excel文件下载

1、什么是Streamlit Streamlit是一个免费的开源框架&#xff0c;用于快速构建和共享漂亮的机器学习和数据科学Web应用程序&#xff0c;官网链接 Streamlit Streamlit API链接 API reference 实际项目中遇到的问题&#xff1a;包含多个sheet的excel文件下载&#xff0c;下面将给…

二维数组_矩阵交换行

任务描述 给定一个5*5的矩阵&#xff08;数学上&#xff0c;一个rc的矩阵是一个由r行c列元素排列成的矩形阵列&#xff09;&#xff0c;将第n行和第m行交换&#xff0c;输出交换后的结果。 输入格式: 输入共6行&#xff0c;前5行为矩阵的每一行元素,元素与元素之间以一个空格…