。下一步,視圖對象往往會對模型進一步渲染,再由視圖解析器進一步解析并向前端發出響應。在下面,我們詳細介紹視圖和視圖解析器的各種分類。
在view接口中,定義了一個核心方法是:
它的作用主要是渲染模型資料,整合web資源,并以特定形式響應給客戶,這些形式可以是複雜jsp頁面,也可以是簡單的json、xml字元串。
針對不同的響應形式,spring為我們設計了不同的view實作類:

針對不同的視圖對象,我們使用不同的視圖解析器來完成執行個體化工作。我們可以在spring上下文配置多個視圖解析器,并通過order屬性來指定他們之間的解析優先級順序,order 越小,對應的 viewresolver 将有越高的解析視圖的權利。當一個 viewresolver 在進行視圖解析後傳回的 view 對象是 null 的話就表示該 viewresolver 不能解析該視圖,這時候就交給優先級更低的進行解析,直到解析工作完成,如果所有視圖解析器都不能完成将解析,則會抛出異常。
類似于視圖,spring也為我們提供了衆多的視圖解析器實作類:
這是一個抽象類,這種視圖解析器會把它曾經解析過的視圖儲存起來,然後每次要解析視圖的時候先從緩存裡面找,如果找到了對應的視圖就直接傳回,如果沒有就建立一個新的視圖對象,然後把它放到一個用于緩存的 map 中,接着再把建立的視圖傳回。使用這種視圖緩存的方式可以把解析視圖的性能問題降到最低。
它繼承了abstractcachingviewresolver ,通過prefix、suffix**拼接 url** 的方式來解析視圖,支援傳回的視圖名稱中包含 redirect: 、forward等字首進行重定向或轉發。使用 urlbasedviewresolver 的時候必須指定屬性 viewclass ,表示解析成哪種視圖,一般使用較多的就是 internalresourceview ,利用它來展現 jsp ,但是當我們使用 jstl 的時候我們必須使用 jstlview 。下面是一段 urlbasedviewresolver 的執行個體定義:
它是 urlbasedviewresolver 的子類,是以 urlbasedviewresolver 支援的特性它都支援. internalresourceviewresolver 會把傳回的視圖名稱都解析為 internalresourceview 對象, internalresourceview 會把 controller 處理器方法傳回的模型屬性都存放到對應的 request 屬性中,然後通過 requestdispatcher 在伺服器端把請求 forword 重定向到目标 url 。下面是一個配置執行個體:
如果我們需要使用jstlview,則需指定vlewclass屬性為jstlview。
在前面的測試執行個體中,我們一直在使用這種視圖解析器,是以不再舉例。
根據它的名字,我們将視圖在spring容器中注冊為bean,bean的id即為視圖名。在我們控制層傳回視圖時,beannameviewresolver會自動根據我們的試圖名找到對應的視圖bean進行解析,下面我們看一個執行個體:
配置好視圖和視圖解析器後,我們可以在控制層通過如下方法通路視圖:
我們在遊覽器通路view1即會跳轉到對應的hello.jsp視圖。
它繼承自 abstractcachingviewresolver 抽象類,是以它也是支援視圖緩存的。 xmlviewresolver 需要給定一個 xml 配置檔案來定義視圖的 bean 對象。在該檔案中定義的每一個視圖的 bean 對象都給定一個名字,然後 xmlviewresolver 将根據 controller 處理器方法傳回的邏輯視圖名稱到 xmlviewresolver 指定的配置檔案中尋找對應名稱的視圖 bean 用于處理視圖。該配置檔案預設是 /web-inf/views.xml 檔案,如果不使用預設值的時候可以在 xmlviewresolver 的 location 屬性中指定它的位置。
這裡需要明确的是,使用xmlviewresolver最終不一定需要輸出xml視圖
以下是使用 xmlviewresolver 的一個示例:
使用 location 屬性指定其配置檔案所在的位置, order 屬性指定當有多個 viewresolver 的時候其處理視圖的優先級。
在下面的代碼中我們就配置了一個名為 hello 的 internalresourceview ,其 url 屬性為“ /index.jsp ”。
類似于beannameviewresolver的執行個體,我們通路view2,xmlviewresolver會到/web-inf/views.xml中尋找相應id的視圖完成解析。
它繼承自 abstractcachingviewresolver ,但是它緩存的不是視圖.和 xmlviewresolver 一樣它也需要有一個配置檔案來定義邏輯視圖名稱和真正的 view 對象的對應關系,不同的是 resourcebundleviewresolver 的配置檔案是一個屬性檔案,而且必須是放在 classpath 路徑下面的,預設情況下這個配置檔案是在* classpath 根目錄下的 views.properties 檔案,如果不使用預設值的話,則可以通過屬性 basename 或 basenames 來指定*。 basename 隻是指定一個基名稱, spring 會在指定的 classpath 根目錄下尋找以指定的 basename 開始的屬性檔案進行 view 解析,如指定的 basename 是 base ,那麼 base.properties 、 baseabc.properties 等等以 base 開始的屬性檔案都會被 spring 當做 resourcebundleviewresolver 解析視圖的資源檔案。 resourcebundleviewresolver 使用的屬性配置檔案的内容類似于這樣:
對應與上述配置,spring會将其解析成如下bean定義:
接下來講講 spring 通過 properties 檔案生成 bean 的規則。它會把 properties 檔案中定義的屬性名稱按最後一個點“ . ”進行分割,把點前面的内容當做是 bean 名稱,點後面的内容當做是 bean 的屬性。這其中有幾個特别的屬性, spring 把它們用小括号包起來了,這些特殊的屬性一般是對應的 attribute ,但不是 bean 對象所有的 attribute 都可以這樣用。其中 (class) 是一個,除了 (class) 之外,還有 (scope) 、 (parent) 、 (abstract) 、 (lazy-init) 。而除了這些特殊的屬性之外的其他屬性, spring 會把它們當做 bean 對象的一般屬性進行處理,就是 bean 對象對應的 property 。是以根據上面的屬性配置檔案将生成如下兩個 bean 對象:
從 resourcebundleviewresolver 使用的配置檔案我們可以看出,它和 xmlviewresolver 一樣可以解析多種不同類型的 view ,因為它們的 view 是通過配置的方式指定的,這也就意味着我們可以指定 a 視圖是 internalresourceview , b 視圖是 jstlview 。
除了以上的視圖解析器,常用的還有下面兩個模闆視圖解析器:freemarkerviewresolver 、 volocityviewresolver,在後面的文章會專門提到。