Spring Web MVC的实现(二)

最后,我们可以结合在DispatcherServlet中,对请求的分发处理来了解一个url请求到来时,MVC的实现和协同处理过程,如以下代码所示:
Java代码
  1. protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {  
  2.     HttpServletRequest processedRequest = request;  
  3.     HandlerExecutionChain mappedHandler = null;  
  4.     int interceptorIndex = -1;  
  5.     //这里为视图准备好一个ModelAndView,这个ModelAndView持有handler处理请求的结果  
  6.     try {  
  7.         ModelAndView mv = null;  
  8.         boolean errorView = false;  
  9.         try {  
  10.             processedRequest = checkMultipart(request);  
  11.             // Determine handler for the current request.  
  12.             // 根据请求得到对应的handler,hander的注册以及getHandler的实现在前面已经分析过  
  13.             mappedHandler = getHandler(processedRequest, false);  
  14.             if (mappedHandler == null || mappedHandler.getHandler() == null) {  
  15.                 noHandlerFound(processedRequest, response);  
  16.                 return;  
  17.             }  
  18.             // Apply preHandle methods of registered interceptors.  
  19.             // 调用hander的拦截器,从HandlerExecutionChain中取出Interceptor进行前处理  
  20.             HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();  
  21.             if (interceptors != null) {  
  22.                 for (int i = 0; i < interceptors.length; i++) {  
  23.                     HandlerInterceptor interceptor = interceptors[i];  
  24.                     if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {  
  25.                         triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
  26.                         return;  
  27.                     }  
  28.                     interceptorIndex = i;  
  29.                 }  
  30.             }  
  31.             // Actually invoke the handler.  
  32.             // 这里是实际调用handler的地方,在执行handler之前,用HandlerAdapter先检查一下handler的合法性:是不是按Spring的要求编写的handler  
  33.             // handler处理的结果封装到ModelAndView对象,为视图提供展现数据  
  34.             HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
  35.             //这里通过调用HandleAdapter的handle方法,实际上触发对Controller的handleRequest方法的调用  
  36.             mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
  37.             // Do we need view name translation?  
  38.             if (mv != null && !mv.hasView()) {  
  39.                 mv.setViewName(getDefaultViewName(request));  
  40.             }  
  41.             // Apply postHandle methods of registered interceptors.  
  42.             if (interceptors != null) {  
  43.                 for (int i = interceptors.length - 1; i >= 0; i--) {  
  44.                     HandlerInterceptor interceptor = interceptors[i];  
  45.                     interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);  
  46.                 }  
  47.             }  
  48.         }  
  49.         catch (ModelAndViewDefiningException ex) {  
  50.             logger.debug("ModelAndViewDefiningException encountered", ex);  
  51.             mv = ex.getModelAndView();  
  52.         }  
  53.         catch (Exception ex) {  
  54.             Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);  
  55.             mv = processHandlerException(processedRequest, response, handler, ex);  
  56.             errorView = (mv != null);  
  57.         }  
  58.         // Did the handler return a view to render?  
  59.         // 这里使用视图对ModelAndView数据的展现  
  60.         if (mv != null && !mv.wasCleared()) {  
  61.             render(mv, processedRequest, response);  
  62.             if (errorView) {  
  63.                 WebUtils.clearErrorRequestAttributes(request);  
  64.             }  
  65.         }  
  66.         else {  
  67.             if (logger.isDebugEnabled()) {  
  68.                 logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +  
  69.                         "': assuming HandlerAdapter completed request handling");  
  70.             }  
  71.         }  
  72.         // Trigger after-completion for successful outcome.  
  73.         triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);  
  74.     }  
  75.     catch (Exception ex) {  
  76.         // Trigger after-completion for thrown exception.  
  77.         triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
  78.         throw ex;  
  79.     }  
  80.     catch (Error err) {  
  81.         ServletException ex = new NestedServletException("Handler processing failed", err);  
  82.         // Trigger after-completion for thrown exception.  
  83.         triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);  
  84.         throw ex;  
  85.     }  
  86.     finally {  
  87.         // Clean up any resources used by a multipart request.  
  88.         if (processedRequest != request) {  
  89.             cleanupMultipart(processedRequest);  
  90.         }  
  91.     }  
  92. }  
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { HttpServletRequest processedRequest = request; HandlerExecutionChain mappedHandler = null; int interceptorIndex = -1; //这里为视图准备好一个ModelAndView,这个ModelAndView持有handler处理请求的结果 try { ModelAndView mv = null; boolean errorView = false; try { processedRequest = checkMultipart(request); // Determine handler for the current request. // 根据请求得到对应的handler,hander的注册以及getHandler的实现在前面已经分析过 mappedHandler = getHandler(processedRequest, false); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Apply preHandle methods of registered interceptors. // 调用hander的拦截器,从HandlerExecutionChain中取出Interceptor进行前处理 HandlerInterceptor[] interceptors = mappedHandler.getInterceptors(); if (interceptors != null) { for (int i = 0; i < interceptors.length; i++) { HandlerInterceptor interceptor = interceptors[i]; if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) { triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); return; } interceptorIndex = i; } } // Actually invoke the handler. // 这里是实际调用handler的地方,在执行handler之前,用HandlerAdapter先检查一下handler的合法性:是不是按Spring的要求编写的handler // handler处理的结果封装到ModelAndView对象,为视图提供展现数据 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); //这里通过调用HandleAdapter的handle方法,实际上触发对Controller的handleRequest方法的调用 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // Do we need view name translation? if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // Apply postHandle methods of registered interceptors. if (interceptors != null) { for (int i = interceptors.length - 1; i >= 0; i--) { HandlerInterceptor interceptor = interceptors[i]; interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv); } } } catch (ModelAndViewDefiningException ex) { logger.debug("ModelAndViewDefiningException encountered", ex); mv = ex.getModelAndView(); } catch (Exception ex) { Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null); mv = processHandlerException(processedRequest, response, handler, ex); errorView = (mv != null); } // Did the handler return a view to render? // 这里使用视图对ModelAndView数据的展现 if (mv != null && !mv.wasCleared()) { render(mv, processedRequest, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } else { if (logger.isDebugEnabled()) { logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() + "': assuming HandlerAdapter completed request handling"); } } // Trigger after-completion for successful outcome. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null); } catch (Exception ex) { // Trigger after-completion for thrown exception. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } catch (Error err) { ServletException ex = new NestedServletException("Handler processing failed", err); // Trigger after-completion for thrown exception. triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex); throw ex; } finally { // Clean up any resources used by a multipart request. if (processedRequest != request) { cleanupMultipart(processedRequest); } } }

通过MVC框架,实际上是DispatcherServlet的协调运作,得到了ModelAndView对象作为数据处理结果,最 后,DispatcherServlet把获得的模型数据交给特定的视图对象,从而完成这些数据的视图呈现工作,这个视图呈现由视图对象的render方 法来完成,毫无疑问,对应于不同的视图对象,render方法会完成不同的视图呈现处理,从而为用户提供丰富的Web UI表现。关于这些不同的视图展现,还可以看到很多很有参考意义的开源软件的灵活使用,限于篇幅,这里就不详细说了。

对Spring MVC框架的个人理解

对Spring作为应用平台的Web应用开发而言,Spring为它们提供了Spring MVC框架,作为一个像struts这样的Web框架的替代;当然,作为应用平台,Spring并不会强制应用对Web框架的选择。但对Web应用开发而 言,选择直接使用Spring MVC,可以给应用开发带来许多便利。因为Spring MVC, 毫无疑问,很好的提供了与Web环境中的IoC容器的集成。同时,和其他Web应用一样,使用Spring MVC, 应用只需要专注于处理逻辑和视图呈现的开发(当然这些开发需要符合Spring MVC的开发习惯),在视图呈现部分,Spring MVC同时也集成了许多现有的Web UI实现,比如像Excel, PDF这些文档视图的生成,因为,集成第三方解决方案,实在可以说是Spring的拿手好戏,从这种一致性的开发模式上看,它在很大程度上降低了Web应 用开发的门槛。

posted on 2010-10-15 16:39  画一个圆圈  阅读(225)  评论(0编辑  收藏  举报

导航