SpringMVC ViewResolver視圖解析器組件
Spring MVC的視圖解析器 ViewResolver 是框架中一個(gè)重要的組件,用于將控制器返回的邏輯視圖名稱(chēng)解析為具體的視圖實(shí)現(xiàn)對(duì)象,最終呈現(xiàn)給用戶的是具體的視圖實(shí)現(xiàn),例如 JSP、FreeMarker 模板、Thymeleaf 模板、JSON 等等。本文將介紹 Spring MVC 的視圖解析器的作用、類(lèi)型、以及源碼實(shí)現(xiàn)。
作用
在 Spring MVC 中,控制器處理完請(qǐng)求之后需要將生成的模型數(shù)據(jù)和視圖名稱(chēng)返回給 DispatcherServlet,DispatcherServlet 會(huì)將模型數(shù)據(jù)和視圖名稱(chēng)交給 ViewResolver 進(jìn)行解析,ViewResolver 將對(duì)應(yīng)的視圖解析出來(lái),并返回給 DispatcherServlet,由 DispatcherServlet 進(jìn)行渲染,最終將渲染后的結(jié)果返回給客戶端。因此,ViewResolver 的作用是將控制器返回的邏輯視圖名稱(chēng)解析為具體的視圖實(shí)現(xiàn)對(duì)象。
類(lèi)型
Spring MVC 中提供了多種 ViewResolver 類(lèi)型,不同類(lèi)型的 ViewResolver 會(huì)使用不同的解析策略和算法,下面介紹幾種常見(jiàn)的 ViewResolver 類(lèi)型。
InternalResourceViewResolver
InternalResourceViewResolver 是 Spring MVC 中最常用的視圖解析器,它用于解析 JS P或 HTML 等資源文件。該解析器會(huì)將邏輯視圖名稱(chēng)加上前綴和后綴,例如將邏輯視圖名稱(chēng) “hello” 解析為 “/WEB-INF/views/hello.jsp”。
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public InternalResourceViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } }
FreeMarkerViewResolver
FreeMarkerViewResolver 用于解析FreeMarker 模板,它會(huì)將邏輯視圖名稱(chēng)加上前綴和后綴,例如將邏輯視圖名稱(chēng) “hello” 解析為 “/WEB-INF/views/hello.ftl”。
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public FreeMarkerViewResolver viewResolver() { FreeMarkerViewResolver viewResolver = new FreeMarkerViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".ftl"); return viewResolver; } }
TilesViewResolver
TilesViewResolver 用于解析 Tiles 布局,它會(huì)將邏輯視圖名稱(chēng)解析為 Tiles 布局,并返回給 DispatcherServlet 進(jìn)行渲染。Tiles 是一個(gè)基于模板的布局框架,可以將頁(yè)面分成多個(gè)部分,每個(gè)部分都是一個(gè)獨(dú)立的模板,最終組合成一個(gè)完整的頁(yè)面。
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public TilesConfigurer tilesConfigurer() { TilesConfigurer tilesConfigurer = new TilesConfigurer(); tilesConfigurer.setDefinitions(new String[] { "/WEB-INF/tiles.xml" }); return tilesConfigurer; } @Bean public TilesViewResolver viewResolver() { TilesViewResolver viewResolver = new TilesViewResolver(); return viewResolver; } }
ContentNegotiatingViewResolver
ContentNegotiatingViewResolver 是一個(gè)復(fù)合視圖解析器,它可以根據(jù)請(qǐng)求的 Accept 頭信息來(lái)判斷客戶端需要的數(shù)據(jù)類(lèi)型,并選擇對(duì)應(yīng)的視圖解析器進(jìn)行解析。例如客戶端請(qǐng)求的 Accept 頭信息為 “application/json”,則選擇使用 MappingJackson2JsonView 解析器將模型數(shù)據(jù)渲染成 JSON 格式返回給客戶端。
@Configuration @EnableWebMvc @ComponentScan(basePackages = "com.example.controller") public class AppConfig { @Bean public ContentNegotiatingViewResolver viewResolver() { ContentNegotiatingViewResolver viewResolver = new ContentNegotiatingViewResolver(); List<ViewResolver> viewResolvers = new ArrayList<>(); viewResolvers.add(jsonViewResolver()); viewResolver.setViewResolvers(viewResolvers); return viewResolver; } @Bean public MappingJackson2JsonViewResolver jsonViewResolver() { MappingJackson2JsonViewResolver jsonViewResolver = new MappingJackson2JsonViewResolver(); return jsonViewResolver; } }
源碼實(shí)現(xiàn)
Spring MVC 中的視圖解析器是通過(guò) ViewResolver 接口來(lái)實(shí)現(xiàn)的,該接口定義了兩個(gè)方法:
public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; String REDIRECT_URL_PREFIX = "redirect:"; String FORWARD_URL_PREFIX = "forward:"; }
其中,resolveViewName 方法接收一個(gè)邏輯視圖名稱(chēng)和一個(gè) Locale 對(duì)象作為參數(shù),返回一個(gè) View 對(duì)象。如果找不到對(duì)應(yīng)的 View 對(duì)象,則返回 null。
對(duì)于 InternalResourceViewResolver 而言,它的 resolveViewName 方法實(shí)現(xiàn)如下:
@Override public View resolveViewName(String viewName, Locale locale) throws Exception { String prefix = getPrefix(); String suffix = getSuffix(); if (viewName.startsWith(REDIRECT_URL_PREFIX)) { String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length()); RedirectView redirectView = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible()); String[] hosts = StringUtils.toStringArray(getRedirectHosts()); if (hosts.length > 0) { redirectView.setHosts(hosts); } return redirectView; } if (viewName.startsWith(FORWARD_URL_PREFIX)) { String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length()); InternalResourceView forwardView = new InternalResourceView(forwardUrl); forwardView.setApplicationContext(getApplicationContext()); forwardView.setServletContext(getServletContext()); forwardView.setAttributesMap(getAttributesMap()); return forwardView; } if (!viewName.startsWith(prefix) && !viewName.endsWith(suffix)) { viewName = prefix + viewName + suffix; } return buildView(viewName); }
在上面的代碼中
首先判斷邏輯視圖名稱(chēng)是否以 redirect: 或 forward: 開(kāi)頭,如果是就返回 RedirectView 或 InternalResourceView 對(duì)象。
如果不是,則根據(jù) prefix 和 suffix 屬性將邏輯視圖名稱(chēng)轉(zhuǎn)換為物理視圖名稱(chēng)。
總結(jié)
Spring MVC 的視圖解析器 ViewResolver 是一個(gè)重要的組件,它將控制器返回的邏輯視圖名稱(chēng)解析為具體的視圖實(shí)現(xiàn)對(duì)象,最終呈現(xiàn)給用戶的是具體的視圖實(shí)現(xiàn)。
Spring MVC提供了多種 ViewResolver 類(lèi)型,不同類(lèi)型的ViewResolver會(huì)使用不同的解析策略和算法,例如 InternalResourceViewResolver 用于解析JSP或HTML等資源文件,F(xiàn)reeMarkerViewResolver 用于解析 FreeMarker 模板,TilesViewResolver 用于解析 Tiles 布局,ContentNegotiatingViewResolver 則是一個(gè)復(fù)合視圖解析器,可以根據(jù)請(qǐng)求的 Accept 頭信息來(lái)選擇對(duì)應(yīng)的視圖解析器進(jìn)行解析。
ViewResolver 的源碼實(shí)現(xiàn)遵循了 ViewResolver 接口的規(guī)范,即將邏輯視圖名稱(chēng)解析為具體的視圖實(shí)現(xiàn)對(duì)象。
到此這篇關(guān)于SpringMVC ViewResolver視圖解析器組件的文章就介紹到這了,更多相關(guān)SpringMVC ViewResolver內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)從方法返回多個(gè)值功能示例
這篇文章主要介紹了java實(shí)現(xiàn)從方法返回多個(gè)值功能,結(jié)合實(shí)例形式分析了集合類(lèi)、封裝對(duì)象、引用傳遞三種實(shí)現(xiàn)方法,需要的朋友可以參考下2017-10-10spring中使用mybatis實(shí)現(xiàn)批量插入的示例代碼
這篇文章主要介紹了spring中使用mybatis實(shí)現(xiàn)批量插入的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06springboot整合quartz實(shí)現(xiàn)定時(shí)任務(wù)示例
spring支持多種定時(shí)任務(wù)的實(shí)現(xiàn)。我們來(lái)介紹下使用spring的定時(shí)器和使用quartz定時(shí)器,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04idea運(yùn)行程序報(bào)錯(cuò)java程序包org.junit不存在解決辦法
這篇文章主要給大家介紹了關(guān)于idea運(yùn)行程序報(bào)錯(cuò)java程序包org.junit不存在的解決辦法, 當(dāng)出現(xiàn)程序包org.junit不存在的問(wèn)題時(shí),可以通過(guò)使用適當(dāng)?shù)腏Unit版本、添加依賴(lài)或重新下載程序包等方式進(jìn)行解決,需要的朋友可以參考下2024-02-02java使用短信設(shè)備發(fā)送sms短信的示例(java發(fā)送短信)
這篇文章主要介紹了java使用短信設(shè)備發(fā)送sms短信的示例(java發(fā)送短信),需要的朋友可以參考下2014-04-04Java同學(xué)找工作最懵圈的問(wèn)題:到底啥是分布式系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)?(推薦)
這篇文章主要介紹了分布式系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04