前言
前面學習了編寫
Web請求的控制器,創建簡單的視圖,本篇博文講解控制器完成請求到結果渲染到用戶的瀏覽器的過程。
渲染Web視圖
理解視圖解析
前面所編寫的控制器方法都沒有直接產生瀏覽器中渲染所需要的HTML,只是將數據填充到模型中,然后將模型傳遞給視圖,方法返回值是String類型的值,其是視圖的邏輯名稱,不會直接引用具體的視圖實現。將控制器中請求處理的邏輯和視圖中的渲染解耦是Spring MVC的重要特征,控制器只通過邏輯視圖名了解視圖,而視圖解析器用於確定使用哪個視圖實現來渲染模型。前面在WebConfig中,使用了InternalResourceViewResolver,其配置了prefix為/WEB-INF/views/,suffix為.jsp用於確定渲染模型的jsp文件的物理位置。Spring自帶了12個視圖解析器用於將邏輯視圖名轉化為物理實現。

對於不同的視圖解析器,一般對應某種特定的視圖技術,如InternalResourceViewResolver一般用於JSP視圖、TilesViewResolver用於Apache Tiles視圖、FreeMarkerViewResolver用於FreeMarker視圖、VelocityViewResolver用於Velocity視圖。
創建JSP視圖
Spring提供了兩種支持JSP視圖的方式。
InternalResourceViewResolver會將視圖名解析為JSP文件。Spring提供了兩個JSP標簽庫,一個用於表單到模型的綁定,一個用於提供了通用的工具類特性。
配置適用於JSP的視圖解析器
InternalResourceViewResolver會在視圖名上添加前綴和后綴,進而確定Web應用中的視圖資源的物理路徑,如下代碼使用@Bean注解,並設置了前綴和后綴的解析器。
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
也可使用XML的配置如下。
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/"
p:suffix=".jsp" />
配置視圖解析器后,home會被解析為/WEB-INF/views/home.jsp,/books/detail會被解析為/WEB-INF/views/books/detail.jsp。
InternalResourceViewResolver最終會將邏輯視圖名解析為InternalResourceView實例,該實例會引用JSP文件,如果JSP文件中使用JSTL標簽處理信息和格式化時,需要將其解析為JSTLView,此時需要設置解析器的viewClass為JstlView.class即可。
使用Spring的JSP庫
Spring提供了兩個用來幫助定義Spring MVC Web視圖的JSP標簽庫,其中一個標簽庫會用來渲染HTML表單標簽,另一個標簽庫包含工具類標簽。
Spring的表單綁定JSP標簽庫包含了14個標簽,其中大多數用來渲染HTML的表單標簽,其能夠根據模型中對象的屬性填充值,還包含展現用戶錯誤的的標簽,其會將錯誤信息渲染到最終的HTML中,可通過如下方式指定。
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="cf" %>
在聲明后,即可使用如下14個標簽庫。

針對不同地區展示不同信息已是國際化的重要組成部分,其關鍵在於使用<s:message>標簽,如在home.jsp中添加<s:message code="spittr.welcome" />標簽,然后在WebConfig中添加如下代碼。
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource resourceBundleMessageSource = new ResourceBundleMessageSource();
resourceBundleMessageSource.setBasename("messages");
return resourceBundleMessageSource;
}
最后在resources/下添加messages.properties文件,並配置內容如下spitter.welcome=welcome!,啟動,顯示welcome!,還可配置message_zh.properties文件,內容配置如下spitter.welcome=china welcome!,啟動,會顯示china wecome!,即會根據本地時區選擇合適的messages文件顯示。
使用Apache Tiles視圖定義布局
前面我們並未關注Web頁面的布局問題,每個jsp完全負責定義自身的布局,假定需要為所有頁面定義一個通用的頭部和底部,這時可使用布局引擎如Apache Tiles,定義適用於所有頁面的通用頁面布局。
配置Tiles視圖解析器
首先需要配置TilesConfigurer的bean,它負責定位和加載Tile定義並協調生成Tiles,再者需要TilesViewResolver的bean將邏輯視圖名稱解析為Tile定義。
@Bean
public TilesConfigurer tilesConfigurer() {
TilesConfigurer tilesConfigurer = new TilesConfigurer();
tilesConfigurer.setDefinitions("/WEB-INF/layout/tiles.xml");
tilesConfigurer.setCheckRefresh(true);
return tilesConfigurer;
}
然后再定義tils.xml文件和對應的文件即可。
使用Thymeleaf
配置Thymeleaf視圖解析器
需要配置如下三個bean。
ThymeleafViewResolver,將邏輯視圖名解析為Thymeleaf模版視圖。SpringTemplateEngine,處理模板並渲染結果。TemplateResolver,加載Thymeleaf模板。
添加bean至WebConfig中如下。
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
@Bean
public SpringTemplateEngine templateEngine(TemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
@Bean
public TemplateResolver templateResolver() {
TemplateResolver templateResolver = new ServletContextTemplateResolver();
templateResolver.setPrefix("/WEB-INF/views/");
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
return templateResolver;
}
總結
Spring的視圖渲染十分靈活,有傳統的jsp方案(InternalResourceViewResolver),還有Tiles(TilesViewResolver)和Thymeleaf(ThymeleafViewResolver)的布局引擎,開發者可根據自身需求選擇合適的視圖解析器。
