Spring MVC读书笔记

来源:互联网 发布:淘宝卖家旺旺号怎么看 编辑:程序博客网 时间:2024/06/05 04:58

1、Spring MVC,与Struts2类似,实现web开发,表现层、控制层及业务层的解耦。Spring MVC是基于请求驱动指的就是使用请求-响应模型。作为对比:其它web框架,Tapestry是基于组件的、JSF是基于事件驱动

2、Spring MVC处理流程:

  

具体执行步骤如下:

1、  首先用户发送请求————>前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个业务控制器或页面控制器进行处理并把请求委托给它,图2-1中的1、2步骤;

2、  业务/页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名);图2-1中的3、4、5步骤;

3、  前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染;图2-1中的步骤6、7;

4、  前端控制器再次收回控制权,将响应返回给用户,图2-1中的步骤8;至此整个结束。

3、Spring Web MVC架构

 

可以将Spring MVC处理请求流程和它的架构结合看。

从Spring MVC的架构看,从前台控制器到业务控制器需要映射处理器(HandlerMapping)和映射处理器和业务处理器的桥连器(HandlerAdapter)以及业务处理器Controller。Controller可以根据实际项目需求定制实现。可以通过此处桥接到Spring web flow,因为FlowContoller也是对此接口的实现

3、核心架构处理请求流程

     1.请求首先到前台控制器DispatcherServlet中,此类进行流程的全局控制,具体流程处理在doDispatch方法中。

  1. //前端控制器分派方法  
  2. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  3.         HttpServletRequest processedRequest = request;  
  4.         HandlerExecutionChain mappedHandler = null;  
  5.         int interceptorIndex = -1;  
  6.   
  7.         try {  
  8.             ModelAndView mv;  
  9.             boolean errorView = false;  
  10.   
  11.             try {  
  12.                    //检查是否是请求是否是multipart(如文件上传),如果是将通过MultipartResolver解析  
  13.                 processedRequest = checkMultipart(request);  
  14.                    //步骤2、请求到处理器(页面控制器)的映射,通过HandlerMapping进行映射  
  15.                 mappedHandler = getHandler(processedRequest, false);  
  16.                 if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  17.                     noHandlerFound(processedRequest, response);  
  18.                     return;  
  19.                 }  
  20.                    //步骤3、处理器适配,即将我们的处理器包装成相应的适配器(从而支持多种类型的处理器)  
  21.                 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  22.   
  23.                   // 304 Not Modified缓存支持  
  24.                 //此处省略具体代码  
  25.   
  26.                 // 执行处理器相关的拦截器的预处理(HandlerInterceptor.preHandle)  
  27.                 //此处省略具体代码  
  28.   
  29.                 // 步骤4、由适配器执行处理器(调用处理器相应功能处理方法)  
  30.                 mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  31.   
  32.                 // Do we need view name translation?  
  33.                 if (mv != null && !mv.hasView()) {  
  34.                     mv.setViewName(getDefaultViewName(request));  
  35.                 }  
  36.   
  37.                 // 执行处理器相关的拦截器的后处理(HandlerInterceptor.postHandle)  
  38.                 //此处省略具体代码  
  39.             }  
  40.             catch (ModelAndViewDefiningException ex) {  
  41.                 logger.debug("ModelAndViewDefiningException encountered", ex);  
  42.                 mv = ex.getModelAndView();  
  43.             }  
  44.             catch (Exception ex) {  
  45.                 Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
  46.                 mv = processHandlerException(processedRequest, response, handler, ex);  
  47.                 errorView = (mv != null);  
  48.             }  
  49.   
  50.             //步骤5 步骤6、解析视图并进行视图的渲染  
  51. //步骤5 由ViewResolver解析View(viewResolver.resolveViewName(viewName, locale))  
  52. //步骤6 视图在渲染时会把Model传入(view.render(mv.getModelInternal(), request, response);)  
  53.             if (mv != null && !mv.wasCleared()) {  
  54.                 render(mv, processedRequest, response);  
  55.                 if (errorView) {  
  56.                     WebUtils.clearErrorRequestAttributes(request);  
  57.                 }  
  58.             }  
  59.             else {  
  60.                 if (logger.isDebugEnabled()) {  
  61.                     logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +  
  62.                             "': assuming HandlerAdapter completed request handling");  
  63.                 }  
  64.             }  
  65.   
  66.             // 执行处理器相关的拦截器的完成后处理(HandlerInterceptor.afterCompletion)  
  67.             //此处省略具体代码  
  68.   
  69.   
  70.         catch (Exception ex) {  
  71.             // Trigger after-completion for thrown exception.  
  72.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
  73.             throw ex;  
  74.         }  
  75.         catch (Error err) {  
  76.             ServletException ex = new NestedServletException("Handler processing failed", err);  
  77.             // Trigger after-completion for thrown exception.  
  78.             triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
  79.             throw ex;  
  80.         }  
  81.   
  82.         finally {  
  83.             // Clean up any resources used by a multipart request.  
  84.             if (processedRequest != request) {  
  85.                 cleanupMultipart(processedRequest);  
  86.             }  
  87.         }  
  88.     }  

      *  首先判断是否是文件上传。

      *  查找本次请求的映射处理器(HandlerMapping),查找依据是:请求的URL,因为在xx-servlet.xml中可能配置数个HandlerMapping,但它们对应不的URL路径,同时也可以为每个HandlerMapping配置HandlerInterceptor。找到HandlerMapping时同时构建HandlerExecutionChain链,HandlerExecutionChain构造方法:HandlerExecutionChain(Object handler, HandlerInterceptor[] interceptors),其中handler是业务处理器,如Controller等。请求交由此链条处理,如将请求走一遍此HandlerMapping配置的HandlerInterceptor。

* 根据HandlerMapping中配置的具体的业务处理器找到HandlerAdapter。需要说明的是:HandlerAdapter可以在xx-servlet.xml中配置,也可以用spring mvc默认的配置在spring-webmvc.jar中的DispatcherServlet.properties中(HandlerMapping,MultipartResolver,LocaleResolver,ThemeResolver均有默认配置,在xx-servlet.xml中没有配置时均采用此默认配置),HandlerAdapter是应用了策略模式,若业务处理器是Controller实例,则会匹配到SimpleControllerHandlerAdapter。由HandlerAdapter调用具体的业务处理器进行处理。

 *业务处理器处理结束后返回一个ModelAndView实例。ModelAndView的逻辑视图名——> ViewResolver, ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;

*  View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;

*返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。




原创粉丝点击