天天看點

SpringMVC(五)--視圖和視圖解析器

1.Spring MVC如何解析視圖

   請求處理方法執行完成後,最終傳回一個 ModelAndView對象。對于那些傳回 String,View 或 ModeMap 等類型的處理方法,Spring MVC 也會在内部将它們裝配成一個ModelAndView 對象,它包含了邏輯名和模型對象的視圖。

• Spring MVC 借助視圖解析器(ViewResolver)得到最終的視圖對象(View),最終的視圖可以是 JSP ,也可能是Excel、JFreeChart 等各種表現形式的視圖。

• 對于最終究竟采取何種視圖對象對模型資料進行渲染,處理器并不關心,處理器工作重點聚焦在生産模型資料的工作上,進而實作 MVC 的充分解耦。

原理:對于那些傳回 String,View 或 ModeMap 等類型的處理方法,Spring MVC 會在内部将它們裝配成一個ModelAndView 對象,Spring MVC 借助視圖解析器(ViewResolver)得到最終的視圖對象(View),最終調用view對象的render方法得到結果。

SpringMVC(五)--視圖和視圖解析器

2.視圖

• 視圖的作用是渲染模型資料,将模型裡的資料以某種形式呈現給客戶。

• 為了實作視圖模型和具體實作技術的解耦,Spring 在org.springframework.web.servlet 包中定義了一個高度抽象的 View

接口:

SpringMVC(五)--視圖和視圖解析器

• 視圖對象由視圖解析器負責執行個體化。由于視圖是無狀态(就是每一次請求都會建立一個新的輸出對象)的,是以它們不會有線程安全的問題

• 常用的視圖實作類:主要是前三個類

SpringMVC(五)--視圖和視圖解析器

3.視圖解析器

• SpringMVC 為邏輯視圖名的解析提供了不同的政策,可以在 Spring WEB 上下文中配置一種或多種解析政策,并指定他們之間的先後順序。每一種映射政策對應一個具體的視圖解析器實作類。

• 視圖解析器的作用比較單一:将邏輯視圖解析為一個具體的視圖對象。

• 所有的視圖解析器都必須實作 ViewResolver 接口:

SpringMVC(五)--視圖和視圖解析器

 •  常用的視圖解析器實作類:主要前兩個

SpringMVC(五)--視圖和視圖解析器

我們可以選擇一種視圖解析器或混用多種視圖解析器

• 每個視圖解析器都實作了 Ordered 接口并開放出一個 order 屬性,可以通過 order 屬性指定解析器的優先順序,order 越小優先級越高。

• SpringMVC 會按視圖解析器順序的優先順序對邏輯視圖名進行解析,直到解析成功并傳回視圖對象,否則将抛出 ServletException 異常

4.InternalResourceViewResolver

• JSP 是最常見的視圖技術,可以使用InternalResourceViewResolver 作為視圖解析器:

<bean  class="org.springframework.web.servlet.view.InternalResourceViewResolver">

    <!--視圖路徑,轉發後會到這去找檔案-->

    <property name="prefix" value="/WEB-INF/views/"></property>

    <!--找字尾為jsp的檔案-->

    <property name="suffix" value=".jsp"></property>

</bean>
           

若項目中使用了 JSTL,則 SpringMVC 會自動把視圖由InternalResourceView 轉為 JstlView

• 若使用 JSTL 的 fmt 标簽則需要在 SpringMVC 的配置檔案中配置國際化資源檔案

    dispatcher-servlet.xml

<!--配置國際化資源檔案-->

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">

    <property name="basename" value="i18n"></property>

</bean>
           

    在類路徑下建立國際化資源檔案

    i18.properties

i18n.username=Username

i18n.password=Password

    i18n_en_US.properties

i18n.username=Username

i18n.password=Password

    i18n_zh_CN.properties

i18n.username=使用者名

i18n.password=密碼

    然後導入JSTL的兩個jar包

SpringMVC(五)--視圖和視圖解析器

    測試類:

private static final String SUCCESS = "success";

@RequestMapping("/testView")

public String testView(){

    System.out.println("Test View");

    return SUCCESS;

}
           

      success.jsp

<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<fmt:message key="i18n.username"></fmt:message>

<br/>

<fmt:message key="i18n.password"></fmt:message>
           

 - 注意:我一開始運作後随便點選以前的路徑,都會出現500,出現 The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml 異常。

   - 我的原因是 Tomcat中缺少這兩個jar包,雖然剛剛jar已經導入項目,但是沒有放入Tomcat下,直接複制兩個jar放入項目路徑下的out\artifacts\項目名\WEB-INF\lib中,就可以運作了

最後注意不要在谷歌浏覽器測試國際化資源,我本以為哪裡錯了,谷歌浏覽器切換成英文國際化資源還是不能變英文,我覺得原因是谷歌浏覽器的英文語言為 en而不是en-US吧。在火狐浏覽器就沒問題

• 若希望直接響應通過 SpringMVC 渲染的頁面,可以使用 mvc:viewcontroller 标簽實作

    注意:假設沒有配置mvc:annotation-driven,那麼一旦使用mvc:viewcontroller标簽那麼會導緻其他的 Handler方法失效(Handler方法就是@Controller類下的那些方法),是以先加上,以後再學mvc:annotation-driven

    dispatcher-servlet.xml

<!--配置直接轉發頁面-->

<mvc:view-controller path="/su" view-name="success"></mvc:view-controller>

<!--在實際開發中通常要配置 mvc:annotation-driven 标簽-->

<mvc:annotation-driven></mvc:annotation-driven>
           

    通路時直接:

SpringMVC(五)--視圖和視圖解析器

,就會跳轉到目标頁面- success.jsp

5. Excel 視圖

若希望使用 Excel 展示資料清單,僅需要擴充SpringMVC 提供的 AbstractExcelView 或AbstractJExcel View 即可。實作 buildExcelDocument()方法,在方法中使用模型資料對象建構 Excel 文檔就可以了。

• AbstractExcelView 基于 POI API,而AbstractJExcelView 是基于 JExcelAPI 的。

• 視圖對象需要配置 IOC 容器中的一個 Bean,使用BeanNameViewResolver 作為視圖解析器即可

<!--配置視圖 BeanNameViewResolver 解析器:使用視圖名來解析視圖-->

<!--通過 order 屬性來定義 視圖解析器的優先級,order值越小優先級越高-->

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">

    <property name="order" value="100"></property>

</bean>
           

• 若希望直接在浏覽器中直接下載下傳 Excel 文檔,則可以設定響應頭 Content-Disposition 的值為

attachment;filename=xxx.xls

    注意:最好設定一下視圖解析的優先級,使用order屬性來指定,order的值越低優先級越高,InternalResourceViewResolver的優先級為Integer.MAV_VALUE,也就是優先級最低

例子:先配置好上面那個xml檔案先

自定義的View類:

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.View;

import java.util.Date;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


@Component

public class HelloView implements View {

    @Override

    public String getContentType() {

        return "text/html";

    }


    @Override

    public void render(Map<String, ?> map, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {

        httpServletResponse.getWriter().println("My View Time is " + new Date());

    }

}
           

測試類

@RequestMapping("/testMyView")

public String testMyView(){

    System.out.println("My View");

    return "helloView";

}
           

如果遇到:HTTP Status 404 - /WEB-INF/views/helloView.jsp,則看看自定義的View是否有加入Spring中:

<!--配置自動掃描的包-->

<context:component-scan base-package="路徑"></context:component-scan>
           

6.關于重定向

• 一般情況下,控制器方法傳回字元串類型的值會被當成邏輯視圖名處理

• 如果傳回的字元串中帶 forward: 或 redirect: 字首時,SpringMVC 會對他們進行特殊處理:将 forward: 和redirect: 當成訓示符,其後的字元串作為 URL 來處理

    – redirect:success.jsp:會完成一個到 success.jsp 的重定向的操作

    – forward:success.jsp:會完成一個到 success.jsp 的轉發操作

繼續閱讀