Spring MVC 常见问题
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 常见问题的更多相关文章
- spring boot 1.x完整学习指南(含各种常见问题servlet、web.xml、maven打包,spring mvc差别及解决方法)
spring boot 入门 关于版本的选择,spring boot 2.0开始依赖于 Spring Framework 5.1.0,而spring 5.x和之前的版本差距比较大,而且应该来说还没有广 ...
- 框架应用:Spring framework (五) - Spring MVC技术
软件开发中的MVC设计模式 软件开发的目标是减小耦合,让模块之前关系清晰. MVC模式在软件开发中经常和ORM模式一起应用,主要作用是将(数据抽象,数据实体传输和前台数据展示)分层,这样前台,后台,数 ...
- UEditor1.4.3.3整合Spring MVC和七牛
[前言] 项目中涉及将UEditor上传服务器整合进已有的基于Spring MVC的服务中,并且将上传到本地改为上传到七牛,看似简单的一个需求,实际做起来还是遇到了一些困难.在这里分享一下经验-- 七 ...
- Spring MVC 多语言化的实践和学习
一.主要参考: SpringMVC简单实现国际化/多语言 - CSDN博客 https://blog.csdn.net/u013360850/article/details/70860144/ 二.总 ...
- 第一个使用Spring Tool Suite(STS)和Maven建立的Spring mvc 项目
一.目标 在这篇文章中.我将要向您展示怎样使用Spring Frameworks 和 Maven build创建您的第一个J2ee 应用程序. 二.信息 Maven是一个java项目的构建工具(或者自 ...
- Spring MVC -- MVC设计模式(演示4个基于MVC框架的案例)
对于简单的Java Web项目,我们的项目仅仅包含几个jsp页面,由于项目比较小,我们通常可以通过链接方式进行jsp页面间的跳转. 但是如果是一个中型或者大型的项目,上面那种方式就会带来许多维护困难, ...
- spring mvc json返回防止乱码
乱码问题 乱码一直是编程的常见问题,spring mvc 返回json数据时可能导致乱码,需要在controller中添加如下代码: @RequestMapping("/test" ...
- 如何用Java类配置Spring MVC(不通过web.xml和XML方式)
DispatcherServlet是Spring MVC的核心,按照传统方式, 需要把它配置到web.xml中. 我个人比较不喜欢XML配置方式, XML看起来太累, 冗长繁琐. 还好借助于Servl ...
- Spring MVC重定向和转发以及异常处理
SpringMVC核心技术---转发和重定向 当处理器对请求处理完毕后,向其他资源进行跳转时,有两种跳转方式:请求转发与重定向.而根据要跳转的资源类型,又可分为两类:跳转到页面与跳转到其他处理器.对于 ...
- Spring MVC入门
1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...
随机推荐
- 面试题-react
对react的理解 是什么 React 是一个用于构建用户界面的 JavaScript 库. 能干什么 可以通过组件化的方式构建大型的,快速响应的大型web应用 如何做 声明式 React 使用jsx ...
- Android 内存优化浅析
一:内存占用几大要点 1,Object Cache:Image cache,single instance obj(重量级别,例如数据库连接obj,bitmap ref),Thread过多, 2,Vi ...
- jenkins 设置Git SSH凭证后,构建Git更新报错returned status code 128解决
报错问题如下: Failed to connect to repository : Command "git ls-remote -h git@IP地址:python/django.git ...
- java 动手动脑 方法重载
如下代码://MethodOverload.java //Using overloaded methods package HJssss; public class zhuce { public st ...
- fabric2.2学习笔记1
fabric2.2学习笔记1 20201303张奕博 2023年1月9日 hyperledger fabric 结构分析 每个Server作用: AdminServer:控制该节点的命运,可以删除该节 ...
- 实现MybatisPlus乐观锁
1.实体类中添加version字段及相关注解 @Version@TableField(fill = FieldFill.INSERT)//第一次添加数据时使其有个默认值1private Integer ...
- Docker部署OpenWRT-旁路由
1.确认网卡名称 命令 ip addr 显示如下图的 enp2s0 就是我们准备进行链接的网卡名称. 2.打开网卡的混杂模式 sudo ip link set enp2s0 promisc on 3. ...
- uiautomator2自动化工具的下载与安装
前言: 相信很多使用appium做过APP自动化的人都深有感触: 1,安装麻烦,配置环境可能会难道不少人 2,appium运行慢.时间长 3,uiautomatorviewer定位元素时得关掉appi ...
- 手动导入jar
mvn install:install-file -Dfile=D:\java_tools\maven\maven-repository\cn\afterturn\easypoi-base-cy\4. ...
- Erueka注册源码分析
在com.netfix.discovery包下有一个DiscoveryClient类中包含注册方法,DiscoveryClient实现了EurekaClient接口,并且是一个单例模式,而Eureka ...