zoukankan      html  css  js  c++  java
  • spring mvc流程理解

    1.controller处理的终究就是一个结果,默认是modelandview对象,controller里自己随便调用service或者dao,终究都还是在controller里有返回值。

    2.  在spring MVC中,当Controller将请求处理结果放入到ModelAndView中以后,DispatcherServlet会根据ModelAndView选择合适的视图进行渲染。

    那么在Spring MVC中是如何选择合适的View呢?View对象是是如何创建的呢?答案就在ViewResolver中,ViewResolver接口定义了resolverViewName方法,根据viewName创建合适类型的View实现。

            那么,如何配置ViewResolver呢?在Spring中,ViewResolver作为Spring Bean存在,可以在Spring配置文件中进行配置,例如下面的代码,配置了jsp相关的viewResolver。

    [xhtml] view plain copy
     
    1. <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->  
    2.     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
    3.         <property name="prefix" value="/WEB-INF/views/"/>  
    4.         <property name="suffix" value=".jsp"/>  
    5.     </bean>  

           在Spring MVC中,因为ViewResolver是使用bean来配置的,所以扩展起来非常的容易,可以根据自己的需要定制ViewResolver,然后在配置文件中进行相关的配置即可。

           ViewResolver接口声明了resolverViewName方法,这个方法的主要功能是根据ModelAndView中给定的viewName信息,再结合相关的配置,创建出合适类型的View对象。

           ViewResolver接口是在DispatcherServlet中进行调用的,当DispatcherServlet调用完Controller后,会得到一个ModelAndView对象,然后DispatcherServlet会调用render方法进行视图渲染。

    [java] view plain copy
     
    1. protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {  
    2.         // Determine locale for request and apply it to the response.  
    3.         Locale locale = this.localeResolver.resolveLocale(request);  
    4.         response.setLocale(locale);  
    5.   
    6.         View view;  
    7.         if (mv.isReference()) {  
    8.             // We need to resolve the view name.  
    9.             view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);  
    10.             if (view == null) {  
    11.                 throw new ServletException(  
    12.                         "Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +  
    13.                                 getServletName() + "'");  
    14.             }  
    15.         }  
    16.         else {  
    17.             // No need to lookup: the ModelAndView object contains the actual View object.  
    18.             view = mv.getView();  
    19.             if (view == null) {  
    20.                 throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +  
    21.                         "View object in servlet with name '" + getServletName() + "'");  
    22.             }  
    23.         }  
    24.   
    25.         // Delegate to the View object for rendering.  
    26.         if (logger.isDebugEnabled()) {  
    27.             logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");  
    28.         }  
    29.         view.render(mv.getModelInternal(), request, response);  
    30.     }  

            在DispatcherServlet类中,init方法中已经进行了相关的初始化,配置的ViewResolver信息都存放在viewResolvers中。在render方法中调用resolverViewName方法,在这个方法中逐一调用ViewResolver去取得View对象。

    [java] view plain copy
     
    1. protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,  
    2.         HttpServletRequest request) throws Exception {  
    3.   
    4.     for (ViewResolver viewResolver : this.viewResolvers) {  
    5.         View view = viewResolver.resolveViewName(viewName, locale);  
    6.         if (view != null) {  
    7.             return view;  
    8.         }  
    9.     }  
    10.     return null;  
    11. }  

            在这里需要关于ViewResolver的选择是通过循环进行的,只选择第一个符合要求的,因此在定义ViewResolver时,需要注意定义其优先级。

            下面就来着重关注一下ViewResolver的类结构。

     ViewResolver类结构图

           关于View对象的创建,不同的ViewResolver的解决方法是各部相同的。如BeanNameViewResolver是根据viewName选择相应名称的bean(这里需要注意bean的scope,是否需要线程安全),而UrlBasedViewResolver则是使用反射机制,根据viewClass信息创建view对象,因此这个view不受IoC容器的管理。ContentNegotiationViewResolver中可以嵌套ViewResolver,根据不同的的请求类型选择合适的ViewResolver。

           DispatcherServlet得到View对象后,即调用View的render方法,执行真正的渲染工作。

           最后,看一下View的类结构图。

     View类结构图

           有上述的View类结构图可知,Spring已经为我们提供了一系列可用的View。同时,如果当前提供的View不能满足我们的要求时,可以通过实现View接口进行扩展。如需要根据model中的数据使用JFreeChart绘图,或者将这些数据作为文件下载时,我们可以扩展出JFreeChartView和FileDownloadView等,这样就能更灵活的将同一份数据用不同的方式展现出来。

    本文转自http://blog.csdn.net/prince2270/article/details/5891085 谢谢

  • 相关阅读:
    HDU 1010 Tempter of the Bone(DFS剪枝)
    HDU 1013 Digital Roots(九余数定理)
    HDU 2680 Choose the best route(反向建图最短路)
    HDU 1596 find the safest road(最短路)
    HDU 2072 单词数
    HDU 3790 最短路径问题 (dijkstra)
    HDU 1018 Big Number
    HDU 1042 N!
    NYOJ 117 求逆序数 (树状数组)
    20.QT文本文件读写
  • 原文地址:https://www.cnblogs.com/panxuejun/p/6739901.html
Copyright © 2011-2022 走看看