前言
前面學習了編寫
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)
的布局引擎,開發者可根據自身需求選擇合適的視圖解析器。