Spring mvc 请求处理

来源:互联网 发布:移动台开户数据 编辑:程序博客网 时间:2024/04/28 13:57

转自:http://www.cnblogs.com/dreamworlds/p/5396112.html
转自:http://www.jianshu.com/p/baa3a05cd271
转自:http://blog.csdn.net/binglumeng/article/details/53585821
从web.xml中servlet的配置开始,根据servlet拦截的url-pattern,进行请求转发。
Spring MVC工作流程如下:
这里写图片描述
这里写图片描述
Spring工作流程如上图所示:
1.用户向服务器发送请求,请求被Spring前端控制Servlet DispatcherServlet捕获;
2.DispatcherServlet对请求URL进行解析,得到请求资源标识符(URI),调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
3.DispatcherServlet根据获得的Handler,选择一个合适的HandlerAdapter。(如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法);
4.提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。在填充Handler入参的过程中,根据你的配置,Spring帮你完成如下工作:
  HttpMessageConveter:将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息
  数据转换:对请求消息进行数据转化。如String转化成Integer、Double等;
  数据验证:验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中。
5.Handler执行完成后,向DispatcherServlet返回一个ModelAndView对象;
6.根据返回的ModelAndView,选择一个合适的ViewResolver返回给DispatcherServlet;
7.ViewResolver结合Model和View,来渲染视图;
8.将渲染结果返回给客户端。

为什么Spring只使用一个Servlet(DispatcherServlet)来处理所有请求?
主要原因由于J2EE核心模式-Font Controller(前端控制器)。Front Controller模式要求在WEB应用系统的前端(Front)设置一个入口控制器(Controller),所有的request请求都被发往该控制器统一处理。Front Controller一般可以用来做一共同处理比如认证,页面导航,Session管理,国际化或本地化处理等。在开发WEB应用系统(但不拘于WEB应用)时,存在很多不恰当的设计方法,比如让客户端(Client,一般指浏览器)可以直接访问各个视图(view,JSP等)。这样逻辑被分散到各个视图中,从而产生了各种问题:
1》对已有的功能修改困难,可维护性低。假如session管理,一旦session内容需要发生改变,则需要修改所有view中的相关代码。
2》很难增加新的功能,缺乏可扩展性。例如,需要在已有的系统中加入安全控制功能,控制用户对某些页面的访问,因为没有统一的处理入口,需要在所有的view中都加上认证代码。
使用Front Controller,强制分离view的显示逻辑与业务处理逻辑。

Spring为什么要结合使用HandlerMapping以及HnadlerAdapter来处理Handler?
主要原因是符合和面向对象中单一职责原则,代码架构清晰,便于维护,代码可复用性高。如HandlerAdapter可能会被用于处理多种Hander。
这里写图片描述
1. 当DispatcherServlet接到请求时,他先回查找适当的处理程序来处理请求。DispatcherServlet通过一个或者多个处理程序映射,将每个请求映射到处理程序中。处理程序映射配置在web应用程序的上下文中,是实现了HandlerMapping接口的Bean。它负责为请求返回一个适当的处理程序(也就是Controller)。处理程序映射通常根据请求的URL将请求映射到处理程序(Controller)。
2. 一旦DispatcherServlet选择了适当的控制器,它就会调用这个控制器来处理请求。
3. 控制器处理完请求后,会将模型和视图名(有时候是视图对象)返回给DispatcherServlet。模型包含了控制器要传递给视图进行显示的属性。如果返回的是视图名称,它会被解析成视图对象再进行呈现。绑定模型和视图的基本类是ModelAndView.
4. 当DispatcherServlet接收到模型和视图名称时,它会将逻辑视图名称解析成视图对象再进行呈现。DispatcherServlet从一个或者多个视图解析器中解析视图。视图解析器配置在Web应用程序上下文中,是实现了ViewResolver接口的Bean。它的任务是根据逻辑视图名称返回试图对象。
5. 一旦DispatcherServlet将视图名称解析称为视图对象,它就会呈现视图对象,并传递控制器返回的模型。视图的任务是将模型属性展示给用户。

DispatcherServlet接收到请求后如何映射到Controller?
在Spring MVC中,web请求被Web应用程序上下文中声明的一个或者多个处理程序映射Bean映射到Controller,Spring MVC提供了几种HandlerMapping实现:
  BeanNameUrlHandlerMapping(默认情况),他根据Controller Bean名称中指定的URL模式将请求映射到处理程序上。
eg. …
当你访问http://**/welcome.htm这个URL时,DispatcherServlet通过BeanNameUrlHandlerMapping映射就找到了WelcomeController。
  ControllerClassNameHandlerMapping,它是按控制器类名称映射请求。
   SimpleUrlHandlerMapping,用定制的映射定义来映射请求。
这里写图片描述
Controller接口是Spring MVC中所有控制器类的基本接口。通过实现这个接口,你可以创建自己的控制器。在handleRequest()方法中,可以随意地处理Web请求。
AbstractController:如果你想让控制器具备一些基本的特性,如过滤受支持的HTTP方法(GET,POST和HEAD),以及在HTTP响应中生成cache-control头部等,你可以让它扩展AbstractController类。
ParameterizableViewController:用来创建带有参数化视图的控制器。
SimpleFormController:它支持命令对象的概念(commandName),并且可以将表单域的值绑定到命令对象的同名属性上。
AbstractWizardFormController:为向导表单的处理定义了基本的任务。向导表单有多个单页,因此必须为向导表单控制器定义多个页面视图。然后这个控制器可以跨越所有这些表单页面来管理表单状态。向导表单会有多个动作,不像SimpleFormController只有单个提交动作。AbstractWizardFormController会根据特殊的请求参数决定用户的动作,通常是用提交按钮的名称来指定动作的。
_finished: 完成向导表单。
_cancel: 取消向导表单。
_targetx: 进入目标页面,这里的x是从0开始的页面索引。
MultiActionController:允许你将多个相关的动作分组到一个控制器中。
常见的视图类型:
这里写图片描述

几种常见的ViewResolver的解析:
InternalResourceViewResolver: 根据URL解析视图。通过添加前缀和后缀的方法,将每个视图名称都映射到一个URL上。
XmlViewResolver: 从XML配置文件中解析视图。将视图声明成Spring的Bean,并按他们的Bean Name进行解析。
ResourceBundleViewResolver: 从ResourceBundle中解析视图。
用多个视图解析器解析视图, 需要注意的是,您需要为你配置的视图解析器配置解析的优先级。 value越小,优先级越高。