Spring MVC(一)— DispatcherServlet

news2025/1/11 5:39:40

 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 {
    @Override
    public 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 {
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        // 设置响应内容类型为JSON
        response.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 {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{RootAnnotationConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{ServletAnnotationConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration) {
        MultipartConfigElement element = new MultipartConfigElement("");
        registration.setMultipartConfig(element);
    }
}

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

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

相关文章

uni app 钓鱼小游戏

最近姑娘喜欢玩那个餐厅游戏里的钓鱼 &#xff0c;经常让看广告&#xff0c;然后就点点点... 自己写个吧。小鱼的图片自己搞。 有问题自己改&#xff0c;不要私信我 <template><view class"page_main"><view class"top_linear"><v…

GPT实战系列-LangChain的OutPutParser解析器

GPT实战系列-LangChain的OutPutParser解析器 LangChain GPT实战系列-LangChain如何构建基通义千问的多工具链 GPT实战系列-构建多参数的自定义LangChain工具 GPT实战系列-通过Basetool构建自定义LangChain工具方法 GPT实战系列-一种构建LangChain自定义Tool工具的简单方法…

蓝桥杯历年真题省赛Java b组 2017年第八届

一、题目 纸牌三角形&#xff08;难度&#xff1a;★★★&#xff09; A,2,3,4,5,6,7,8,9 共9张纸牌排成一个正三角形&#xff08;A按1计算&#xff09;。要求每个边的和相等。 下图就是一种排法。 这样的排法可能会有很多。 如果考虑旋转、镜像后相同的算同一种&#xff0c;…

基于单片机的自动售货机的设计

摘 要 自动售货机是近些年来兴起的一种通过FPGA或者单片机等硬件支持的智能设备。它广泛的应用于商场&#xff0c;公寓&#xff0c;火车汽车站等人流较密集且购物需求大的地方。自动售货机通过硬件支持&#xff0c;通过以编写好的程序自动出货自动找零&#xff0c;但货物一旦售…

SpringMVC基础之工作流程

文章目录 SpringMVC 的工作流程1. 总图2. DispatcherServlet3. 必需的配置4. 加载配置文件的两个时机5. 定义控制器6. 创建 JSP 视图 SpringMVC 的工作流程 1. 总图 如上图&#xff0c;Spring MVC 程序的完整执行流程如下&#xff1a; 用户通过浏览器发送请求&#xff0c;请求…

Django之图形验证码

Django之图形验证码 目录 Django之图形验证码【1】静态图片【2】视图层绑定静态文件【3】PIL生成图片(固定背景)【4】将图片存储在内存【5】生成文本信息【6】实现图片刷新 【1】静态图片 最基础的生成图片就是获取静态文件 <div style"margin-left: 10px;">…

单片机毕业设计智能家居集成控制器

项目介绍 物联网技术的兴起和发展逐渐的改变了我们的工作方式和生活方式。不仅需要办公变得智能&#xff0c;也需要家居生活逐渐变得智能化起来。智能家居就是在这样的影响下产生的。智能家居提供家电控制、照明控制、遥控控制、环境监测、防盗报警、人体红外扫描等多种功能和…

中电金信:技术实践|Flink维度表关联方案解析

导语&#xff1a;Flink是一个对有界和无界数据流进行状态计算的分布式处理引擎和框架&#xff0c;主要用来处理流式数据。它既可以处理有界的批量数据集&#xff0c;也可以处理无界的实时流数据&#xff0c;为批处理和流处理提供了统一编程模型。 维度表可以看作是用户来分析数…

1.2 课程架构介绍:STM32H5 芯片生命周期管理与安全调试

1.2 课程架构介绍&#xff1a;STM32H5 芯片生命周期管理与安全调试 下面开始学习课程的第二节&#xff0c;简单介绍下STM32H5芯片的生命周期和安全调试&#xff0c;具体课程大家可以观看STM32官方录制的课程&#xff0c;链接&#xff1a;1.2. 课程架构介绍&#xff1a;STM32H5…

专业无网设备如何远程运维?向日葵远程控制能源场景案例解析

清洁能源领域&#xff0c;拥有庞大的上下游产业链&#xff0c;涉及的相关工业设备门类多、技术覆盖全、行业应用广。在这一领域内&#xff0c;相关专业设备的供应商的核心竞争力除了本身产品的技术能力之外&#xff0c;服务也是重要的一环。 某企业作为致力于节能环保方向的气…

Oracle 一键巡检自动生成 Word 报告

前言 Oracle 数据库巡检通常需要消耗大量时间和精力&#xff0c;包括收集数据库以及主机的相关信息。针对 Word 报告的样式调整&#xff0c;也是重复和费事的&#xff0c;所以我针对 Oracle 巡检所需检查的信息以及报告模板&#xff0c;写了一套自动巡检并且生成报告的脚本。巡…

【回归预测】基于DBO-RF(蜣螂优化算法优化随机森林)的回归预测 多输入单输出【Matlab代码#67】

文章目录 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】1. 随机森林RF算法2. 蜣螂优化算法3. 实验模型4. 部分代码展示5. 仿真结果展示6. 资源获取 【可更换其他算法&#xff0c;获取资源请见文章第6节&#xff1a;资源获取】 1. 随机森林RF算法 …

【每日一问】手机如何开启USB调试?

一、背景 当电脑跟手机之间需要进行交互的时候&#xff0c;可以考虑使用usb进行连接。那么手机如何开启USB调试呢&#xff1f; 二、操作步骤&#xff1a; 思路&#xff1a; 步骤1&#xff1a;手机开启开发者模式 步骤2&#xff1a;在开发者模式中&#xff0c;开启“USB调试”…

孙宇晨最新研判:加密货币将成为全球金融基础设施的一部分

近日,波场TRON创始人、火币HTX全球顾问委员会委员孙宇晨接受了在加密社区有重要影响力的媒体平台Bankless的专访,就自己的从业经历、涉足加密行业的理想、波场TRON本身的发展和未来的市场走向等话题进行了详细的分享。 孙宇晨认为,波场TRON的使命是为那些没有银行账户的人提供…

数据结构——字符串

1.leetcode 151 题目链接&#xff1a; . - 力扣&#xff08;LeetCode&#xff09;. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/reverse-words-in-a-string/…

Vue.js+SpringBoot开发天沐瑜伽馆管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 瑜伽课程模块2.3 课程预约模块2.4 系统公告模块2.5 课程评价模块2.6 瑜伽器械模块 三、系统设计3.1 实体类设计3.1.1 瑜伽课程3.1.2 瑜伽课程预约3.1.3 系统公告3.1.4 瑜伽课程评价 3.2 数据库设计3.2.…

HTML—标签的分类,span和div标签,不同的标签之间类型转换

标签的分类&#xff1a; ①块级标签&#xff1a;无论内容多少&#xff0c;会充满整个行。大小可自定义 例&#xff1a;p&#xff0c;h1&#xff0c;ul&#xff0c;ol&#xff0c;hr 等 ②行级标签&#xff1a;自身的大小就是标签的大小&#xff0c;不会占一整行。大小不可调 例…

免费升级https的方式(含教学)

背景&#xff1a;随着现在全民网络安全意识的日益提升&#xff0c;各个网站实现的https数量也随之提升&#xff0c;那么如何将原本网站的http访问方式升级为https呢&#xff1f;下面均为干货内容。 目录 http访问和https访问的区别&#xff1a; 实现https后有哪些好处&#x…

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

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

Java代码审计安全篇-反序列化漏洞

前言&#xff1a; 堕落了三个月&#xff0c;现在因为被找实习而困扰&#xff0c;着实自己能力不足&#xff0c;从今天开始 每天沉淀一点点 &#xff0c;准备秋招 加油 注意&#xff1a; 本文章参考qax的网络安全java代码审计和部分师傅审计思路以及webgoat靶场&#xff0c;记录…