• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • SpringMVC學習筆記(五)---視圖解析器(續)

    在Spring MVC中,當Controller將請求處理結果放入到ModelAndView中以后,DispatcherServlet會根據ModelAndView選擇合適的視圖進行渲染。那么在Spring MVC中是如何選擇合適的View呢?View對象是是如何創建的呢?答案就在ViewResolver中,ViewResolver接口定義了resolverViewName方法,根據viewName創建合適類型的View實現。

            那么,如何配置ViewResolver呢?在Spring中,ViewResolver作為Spring Bean存在,可以在Spring配置文件中進行配置,例如下面的代碼,配置了jsp相關的viewResolver。

     

    <!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->  
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
            <property name="prefix" value="/WEB-INF/views/"/>  
            <property name="suffix" value=".jsp"/>  
        </bean> 

     

    在Spring MVC中,因為ViewResolver是使用bean來配置的,所以擴展起來非常的容易,可以根據自己的需要定制ViewResolver,然后在配置文件中進行相關的配置即可。

           ViewResolver接口聲明了resolverViewName方法,這個方法的主要功能是根據ModelAndView中給定的viewName信息,再結合相關的配置,創建出合適類型的View對象。

           ViewResolver接口是在DispatcherServlet中進行調用的,當DispatcherServlet調用完Controller后,會得到一個ModelAndView對象,然后DispatcherServlet會調用render方法進行視圖渲染。

     

    protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {  
            // Determine locale for request and apply it to the response.  
            Locale locale = this.localeResolver.resolveLocale(request);  
            response.setLocale(locale);  
      
            View view;  
            if (mv.isReference()) {  
                // We need to resolve the view name.  
                view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);  
                if (view == null) {  
                    throw new ServletException(  
                            "Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" +  
                                    getServletName() + "'");  
                }  
            }  
            else {  
                // No need to lookup: the ModelAndView object contains the actual View object.  
                view = mv.getView();  
                if (view == null) {  
                    throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " +  
                            "View object in servlet with name '" + getServletName() + "'");  
                }  
            }  
      
            // Delegate to the View object for rendering.  
            if (logger.isDebugEnabled()) {  
                logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'");  
            }  
            view.render(mv.getModelInternal(), request, response);  
        }  

     在DispatcherServlet類中,init方法中已經進行了相關的初始化,配置的ViewResolver信息都存放在viewResolvers中。在render方法中調用resolverViewName方法,在這個方法中逐一調用ViewResolver去取得View對象。

    protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,  
            HttpServletRequest request) throws Exception {  
      
        for (ViewResolver viewResolver : this.viewResolvers) {  
            View view = viewResolver.resolveViewName(viewName, locale);  
            if (view != null) {  
                return view;  
            }  
        }  
        return null;  
    }  

     

    在這里需要關于ViewResolver的選擇是通過循環進行的,只選擇第一個符合要求的,因此在定義ViewResolver時,需要注意定義其優先級。

            下面就來著重關注一下ViewResolver的類結構。

     



     

    關于View對象的創建,不同的ViewResolver的解決方法是各部相同的。如BeanNameViewResolver是根據viewName選擇相應名稱的bean(這里需要注意bean的scope,是否需要線程安全),而UrlBasedViewResolver則是使用反射機制,根據viewClass信息創建view對象,因此這個view不受IoC容器的管理。ContentNegotiationViewResolver中可以嵌套ViewResolver,根據不同的的請求類型選擇合適的ViewResolver。

           DispatcherServlet得到View對象后,即調用View的render方法,執行真正的渲染工作。

           最后,看一下View的類結構圖。


    有上述的View類結構圖可知,Spring已經為我們提供了一系列可用的View。同時,如果當前提供的View不能滿足我們的要求時,可以通過實現View接口進行擴展。如需要根據model中的數據使用JFreeChart繪圖,或者將這些數據作為文件下載時,我們可以擴展出JFreeChartView和FileDownloadView等,這樣就能更靈活的將同一份數據用不同的方式展現出來。

     

     

     

    版權聲明:本文為iteye_21015原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/iteye_21015/article/details/82139001

    智能推薦

    SpringMVC 視圖解析器及攔截器

    視圖解析器 跳轉方式(設置返回值字符串內容) ①默認請求轉發 forward:資源路徑,forward可省略 ②重定向 redirect:資源路徑 自定義視圖解析器 SpringMVC會提供默認的視圖解析器: 可使用<bean>加載org.springframework.web.servlet.view.InternalResourceViewResolver 來自定義視圖解析器,默認...

    SpringMVC 11. 視圖,視圖解析,視圖解析器

    視圖,視圖解析,視圖解析器 1.Spring MVC如何解析視圖 2.視圖和視圖解析器 請求處理方法執行完成后,最終返回一個 ModelAndView對象。對于那些返回String,View 或 ModeMap 等類型的處理方法,Spring MVC 也會在內部將它們裝配成一個ModelAndView 對象,它包含了邏輯名和模型對象的視圖。 Spring MVC 借助視圖解析器(ViewResol...

    HTML中常用操作關于:頁面跳轉,空格

    1.頁面跳轉 2.空格的代替符...

    freemarker + ItextRender 根據模板生成PDF文件

    1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...

    電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!

    Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...

    猜你喜歡

    requests實現全自動PPT模板

    http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...

    Linux C系統編程-線程互斥鎖(四)

    互斥鎖 互斥鎖也是屬于線程之間處理同步互斥方式,有上鎖/解鎖兩種狀態。 互斥鎖函數接口 1)初始化互斥鎖 pthread_mutex_init() man 3 pthread_mutex_init (找不到的情況下首先 sudo apt-get install glibc-doc sudo apt-get install manpages-posix-dev) 動態初始化 int pthread_...

    統計學習方法 - 樸素貝葉斯

    引入問題:一機器在良好狀態生產合格產品幾率是 90%,在故障狀態生產合格產品幾率是 30%,機器良好的概率是 75%。若一日第一件產品是合格品,那么此日機器良好的概率是多少。 貝葉斯模型 生成模型與判別模型 判別模型,即要判斷這個東西到底是哪一類,也就是要求y,那就用給定的x去預測。 生成模型,是要生成一個模型,那就是誰根據什么生成了模型,誰就是類別y,根據的內容就是x 以上述例子,判斷一個生產出...

    styled-components —— React 中的 CSS 最佳實踐

    https://zhuanlan.zhihu.com/p/29344146 Styled-components 是目前 React 樣式方案中最受關注的一種,它既具備了 css-in-js 的模塊化與參數化優點,又完全使用CSS的書寫習慣,不會引起額外的學習成本。本文是 styled-components 作者之一 Max Stoiber 所寫,首先總結了前端組件化樣式中的最佳實踐原則,然后在此基...

    精品国产乱码久久久久久蜜桃不卡