Spring MVC的主要组件有那些?

spring mvc 在使用 DispatcherServlet 处理 web 请求的时候,会用到 spring 中的九大组件,以下是几个关键的组件:

1、List<HandlerMapping> handlerMappings:映射处理器;

用来加载、解析容器中的 controller;

HandlerMapping 接口一共有 3 个实现类:

1)BeanNameUrlHandlerMapping -> @Controller("/xxx") 类注解 + HttpRequestHandler 接口

2)RequestMappingHandlerMapping -> @Controller 类注解 + @RequestMapping("/xxx")方法注解

3)RouterFunctionMapping ->函数式映射方式;

2、List<HandlerAdapter> handlerAdapters:映射适配器;

handlerMappings 用来寻找请求对应的 controller,handlerAdapters 就是使用反射机制,执行 controller 中处理请求的方法;

常用的就是 RequestMappingHandlerAdapter,如果 controller 类的方法中带有 @RequestMapping 注解,就是会被 RequestMappingHandlerAdapter 所处理的目标方法;

RequestMappingHandlerAdapter 实现了 InitializingBean 接口;

在 getBean 创建该对象时执行了 InitializingBean 接口的方法进行了初始化;

给对象中添加了【参数解析器】和【返回值处理器】,使用 27 种参数解析器创建目标方法的参数,使用 15 种返回值处理器对目标方法的返回值进行处理,生成 ModelAndView 对象;

3、List<HandlerExceptionResolver> handlerExceptionResolvers:异常解析器;

默认异常解析器有以下 3 类:

(1)DefaultHandlerExceptionResolver:判断是不是 spring mvc 自己定义的异常,如果是就处理了;

其实底层代码就是使用 if else 挨个判断异常类型来实现的;

(2)ResponseStatusExceptionResolver:判断该异常有没有继承 ResponseStatusException 类,或者有没有标注 @ResponseStatus 注解;

(1)注解版:
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
public class ExceptionAnnotation extends RuntimeException {
private String errorMessage;
public ExceptionAnnotation(String errorMessage) {
super(errorMessage);
}
}
(2)继承类:
public class ExceptionClass extends ResponseStatusException {
public ExceptionClass(HttpStatus status) {
super(status);
}
public ExceptionClass(HttpStatus status, String reason) {
super(status, reason);
}
public ExceptionClass(HttpStatus status, String reason, Throwable cause) {
super(status, reason, cause);
}
}

(3)ExceptionHandlerExceptionResolver:找到一个{@code @ExceptionHandler}方法并调用它来处理引发的异常;

@ExceptionHandler
public String error() {
return "error";
}

4、List<ViewResolver> viewResolvers:视图解析器;

相当于这个请求怎么去其他页面,比如说转发还是重定向,还是返回一个图片或文档;

以下是 DispatcherServlet 属性源码:

DispatcherServlet 的属性中有【九大组件】,在处理请求时,就是用这些组件进行相应的处理:

  /** 文件上传解析器 */
@Nullable
private MultipartResolver multipartResolver; /** 国际化解析器 */
@Nullable
private LocaleResolver localeResolver; /** 主题解析器 */
@Nullable
private ThemeResolver themeResolver; /** 请求映射处理器 List 集合,其实就是【请求地址 和 controller】的映射关系集合 */
@Nullable
private List<HandlerMapping> handlerMappings; /** 处理器的适配器,可以理解为对应的【超级反射工具】 */
/** 这是一个 Adapter 适配器,适配的是 【handlerMappings 中的映射方法】,和【响应的处理】进行适配
@Nullable
private List<HandlerAdapter> handlerAdapters; /** 处理器的异常解析器 */
@Nullable
private List<HandlerExceptionResolver> handlerExceptionResolvers; /** (其实这个没啥用,不用管)请求到视图名的转换器,把请求转换为要跳转的页面地址的转换器 */
@Nullable
private RequestToViewNameTranslator viewNameTranslator; /** 闪存管理器 */
@Nullable
private FlashMapManager flashMapManager; /** 视图解析器,相当于这个请求怎么去其他页面,比如说转发还是重定向,还是返回一个图片或文档 */
@Nullable
private List<ViewResolver> viewResolvers;

什么是DispatcherServlet

DispatcherServlet 的继承结构是这样的:

DispatcherServlet -> FrameworkServlet -> HttpServletBean -> HttpServlet -> Servlet;

DispatcherServlet、FrameworkServlet 、HttpServletBean 这三个 spring mvc 中的类;

HttpServlet、Servlet 是 javax.servlet 中的类;

也就是说,DispatcherServlet 实现了 servlet 标准接口,遵循 servlet 的生命周期;

Spring 的 MVC 框架是围绕 DispatcherServlet 来设计的,用来处理所有的 HTTP 请求和响应;


请描述Spring MVC的工作流程?描述一下 DispatcherServlet 的工作流程?

(1)用户发送请求至前端控制器 DispatcherServlet;

(2) DispatcherServlet 收到请求后,调用 HandlerMapping 处理器映射器, 请求获取 Handle;

(3)处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给 DispatcherServlet;

(4)DispatcherServlet 调用 HandlerAdapter 处理器适配器;

(5)HandlerAdapter 经过适配调用具体处理器(Handler,也叫后端控制器);

(6)Handler 执行完成返回 ModelAndView;

(7)HandlerAdapter 将 Handler 执行结果 ModelAndView 返回给 DispatcherServlet;

(8)DispatcherServlet 将 ModelAndView 传给 ViewResolver 视图解析器进行解析;

(9)ViewResolver 解析后返回具体 View;

(10)DispatcherServlet 对 View 进行渲染视图(即将模型数据填充至视图中);

(11)DispatcherServlet响应用户;

以下是 doDispatch 方法的源码解析:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

    // 创建异步请求处理管理器,这也是响应式 web 的基础
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); // 检查请求是不是文件上传请求,其实就是根据 http 规范,检查 request 的 header 的 Content-Type 是不是 "multipart/" 开头的
// 如果是文件上传请求,就创建一个 MultipartHttpServletRequest 类型的 request 替换之前的 HttpServletRequest 类型的 request
processedRequest = checkMultipart(request); // 获取能够处理当前请求的 controller 的方法,mappedHandler 中封装了该方法(问题【2】和【3】)
mappedHandler = getHandler(processedRequest); // 如果 mappedHandler 为 null,返回相应 404(404 就是这么来的!)
if (mappedHandler == null) {
// 该方法中会 throw 报错,或者 response.sendError(HttpServletResponse.SC_NOT_FOUND); 抛出 404 错误
noHandlerFound(processedRequest, response);
return;
} // 确定当前请求的处理程序适配器,一共 4 种适配器,对应处理不同的 controller,适配器的加载和 handlerMappings 基本一样
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 执行过滤器链 HandlerExecutionChain 中的拦截器的前置拦截过程
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
} // 适配器真正执行 controller 处理请求的方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 如果没有指定的 view,设置默认的 view,注意:这里使用了九大组件之一的 viewNameTranslator,其实没啥用;
applyDefaultViewName(processedRequest, mv); // 执行拦截器链的 postHandle 方法
mappedHandler.applyPostHandle(processedRequest, response, mv); /* 以上所有代码,均被 try catch 包裹 */ // 处理调度结果,处理处理程序选择和处理程序调用的结果,它是一个 ModelAndView 或一个要解析为 ModelAndView 的异常。
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); }

Spring MVC常用的注解有哪些?

@RequestMapping:用于处理请求 url 映射的注解,可用于类或方法上。用 于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。

@RequestBody:注解实现接收http请求的json数据,将json转换为java对 象。

@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给 客户。


@ResponseBody注解的作用

作用: 该注解用于将Controller的方法返回的对象,通过适当的 HttpMessageConverter 转换为指定格式后,写入到 Response 对象的 body 数据区。

使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用;


Spring MVC怎么样设定重定向和转发的?

(1) 转发:在返回值前面加"forward:",譬如"forward:user.do?name=method4"

(2) 重定向:在返回值前面加"redirect:",譬如"redirect:http://www.baidu.com"

Spring MVC 常见问题的更多相关文章

  1. spring boot 1.x完整学习指南(含各种常见问题servlet、web.xml、maven打包,spring mvc差别及解决方法)

    spring boot 入门 关于版本的选择,spring boot 2.0开始依赖于 Spring Framework 5.1.0,而spring 5.x和之前的版本差距比较大,而且应该来说还没有广 ...

  2. 框架应用:Spring framework (五) - Spring MVC技术

    软件开发中的MVC设计模式 软件开发的目标是减小耦合,让模块之前关系清晰. MVC模式在软件开发中经常和ORM模式一起应用,主要作用是将(数据抽象,数据实体传输和前台数据展示)分层,这样前台,后台,数 ...

  3. UEditor1.4.3.3整合Spring MVC和七牛

    [前言] 项目中涉及将UEditor上传服务器整合进已有的基于Spring MVC的服务中,并且将上传到本地改为上传到七牛,看似简单的一个需求,实际做起来还是遇到了一些困难.在这里分享一下经验-- 七 ...

  4. Spring MVC 多语言化的实践和学习

    一.主要参考: SpringMVC简单实现国际化/多语言 - CSDN博客 https://blog.csdn.net/u013360850/article/details/70860144/ 二.总 ...

  5. 第一个使用Spring Tool Suite(STS)和Maven建立的Spring mvc 项目

    一.目标 在这篇文章中.我将要向您展示怎样使用Spring Frameworks 和 Maven build创建您的第一个J2ee 应用程序. 二.信息 Maven是一个java项目的构建工具(或者自 ...

  6. Spring MVC -- MVC设计模式(演示4个基于MVC框架的案例)

    对于简单的Java Web项目,我们的项目仅仅包含几个jsp页面,由于项目比较小,我们通常可以通过链接方式进行jsp页面间的跳转. 但是如果是一个中型或者大型的项目,上面那种方式就会带来许多维护困难, ...

  7. spring mvc json返回防止乱码

    乱码问题 乱码一直是编程的常见问题,spring mvc 返回json数据时可能导致乱码,需要在controller中添加如下代码: @RequestMapping("/test" ...

  8. 如何用Java类配置Spring MVC(不通过web.xml和XML方式)

    DispatcherServlet是Spring MVC的核心,按照传统方式, 需要把它配置到web.xml中. 我个人比较不喜欢XML配置方式, XML看起来太累, 冗长繁琐. 还好借助于Servl ...

  9. Spring MVC重定向和转发以及异常处理

    SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...

  10. Spring MVC入门

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...

随机推荐

  1. linux内核源码编译加制作rpm包

    本章主要讲解实际操作步骤,具体理论知识可以自行百度 linux内核官网下载:https://cdn.kernel.org/pub/linux/kernel/   (如图) 根据官网发布的信息分析,目前 ...

  2. webstrom配置ES6 file watch没有生效

    参考了文章https://www.cnblogs.com/kiimi/p/8663467.html设置后,依然没有看到编译后的文件,然后设置了输出文件夹为当前项目,再重启webstrom就看到了--

  3. CF79D 题解

    题解 传送门 你有 \(n\) 个灯泡,一开始都未点亮. 同时你有 \(l\) 个长度,分别为 \(a_1 \sim a_l\). 每次你可以选择一段连续的子序列,且长度为某个 \(a_i\),并将这 ...

  4. Linux详解

    什么是操作系统?1.操作系统:(Operating System,OS)是计算机系统中的一个系统软件,它们管理和控制计算机系统中的硬件及软件资源,为用户提供一个功能强大.使用方便的和可扩展的工作环境. ...

  5. vue仿QQ聊天室|vue聊天实例,直播聊天室

    图片压缩 百亿站点 基于vue2.0+vue-cli+vuex+vue-router+webpack+es6+wcPop等技术开发的仿微信聊天界面|仿微信聊天室vue-chatRoom,实现了微信聊天 ...

  6. vue引入swiper的报错以及swiper在vue中的交互事件处理

    安装遇到找不到 css的问题,百度查了一些帖子也不行,可能是swiper 升级6.0后的一些变化导致 安装成功的帖子:转载于:https://www.jianshu.com/p/0150d2ee109 ...

  7. Qframework UIKit

    用QFramework的UIKit 功能很容易实现UI模块的MVC功能,但MVC模式构造起来还是会有些繁琐, 两个相互直接的UIElement 之间的一些数据传输和调用都要用Msg通过UIPanel ...

  8. heap 算法函数

    这一系列函数是在做 这道题 时发现的 这道题空间卡的很死,是不能用数组存下所有数字进行快排的 后来又尝试用 \(multiset\) 优化空间,发现不行,可能是 \(multiset\) 还有结构性存 ...

  9. Linux 服务器配置。

    关于防火墙 1.首先不管防火墙有没有关 都使用systemctl stop firewalld 关闭防火墙 2.然后使用 yum install iptables-services 安装或更新服务 3 ...

  10. APP性能测试——首次启动耗时测试

    首次启动耗时: 即第一次安装(清除数据也可以),打开软件,直到进入到首页activity页面,并计算耗时. 示例代码: import os import time # 测试首次启动时间 # 创建App ...