第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

Spring MVC 核心組件(下)

1. 前言

上一章節(jié)提到了 Spring MVC 的幾大核心組件,并對(duì)前端控制器、用戶控制器、映射器 3 大組件做了較全方面的講解,相信大家一定對(duì)它們有了更理性的認(rèn)識(shí)。

本節(jié)課繼續(xù)講解適配器、視圖解析器組件。通過(guò)本節(jié)課,你將了解到:

  • 適配器的功能及配置;
  • 視圖解析器的基本功能及配置;
  • 組件之間是如何協(xié)作完成用戶的請(qǐng)求的。這個(gè)是本章節(jié)的重點(diǎn),也是對(duì)各組件的歸納和總結(jié)。

2. 適配器

所謂適配器組件,其本質(zhì)就是運(yùn)用適配器設(shè)計(jì)模式,匹配不兼容的接口規(guī)范。

圖片描述

如上圖,調(diào)用者只能識(shí)別接口 2 類型,但是 A 提供的是接口 1 類型。適配器可以把接口 1 轉(zhuǎn)換成接口 2。這樣使用者就能使用 A 提供的功能了。

為什么要使用適配器組件?

欲解答這個(gè)問(wèn)題,則先要了解如果不使用適配器組件,則如何編寫用戶控制器。既然稱為用戶控制器,則是開發(fā)者根據(jù)需要在框架外部定義的一個(gè)組件,Spring MVC 不可能未卜先知它的存在。

如果要讓 Spring MVC 識(shí)別這個(gè)控制器,有一種方案 :預(yù)先定義好接口,強(qiáng)制性要求開發(fā)者在設(shè)計(jì)控制器時(shí)遵循接口規(guī)范。

比如說(shuō)實(shí)現(xiàn) Controller 接口編寫控制器。

@Controller
public class HelloAction implements org.springframework.web.servlet.mvc.Controller {
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
	return null;
}
}

除此之外,Spriing MVC 提供有更靈活的用戶控制器設(shè)計(jì)方案,可使用 “ 普通 JAVA 類” 充當(dāng)控制器,控制器中的方法也可由開發(fā)者隨性命名。

此時(shí),就需要適配器組件把這些不符合規(guī)范的控制器以統(tǒng)一的接口方式告訴給 Spring MVC 。

Spring MVC 提供了 3 個(gè)默認(rèn)適配器:

org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter

這些適配對(duì)象都實(shí)現(xiàn)了 HandlerAdapter 接口,此接口就有一個(gè)統(tǒng)一的內(nèi)部調(diào)用方法。

@Nullable
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

簡(jiǎn)要描述 3 個(gè)適配器的應(yīng)用場(chǎng)景:

  • SimpleControllerHandlerAdapter: 簡(jiǎn)單的控制器處理器適配器,支持實(shí)現(xiàn)了 Controller 接口的控制器;
  • HttpRequestHandlerAdapter: http 請(qǐng)求處理器適配器,要求編寫的控制器時(shí)實(shí)現(xiàn) HttpRequestHandler 接口。此類控制器可以很方便的獲取請(qǐng)求包中的相關(guān)信息。但,真正使用的并不多;
  • RequestMappingHandlerAdapter: 注解處理器適配器,適配使用了注解的用戶控制器。本課程中的就是使用了此適配器,此適配器的實(shí)現(xiàn)比前兩個(gè)都復(fù)雜。

因?yàn)橛羞m配器的存在,可以讓控制器的設(shè)計(jì)變得靈活。

Tips: 這 3 類適配器都是 Spring MVC 默認(rèn)提供的,可以不用顯示配置,除非有定制需求。

3. 視圖解析器

3.1 視圖解析器的功能

要講解視圖解析器,則需要回溯到用戶控制器上。

@RequestMapping("/hello")
public String hello() {
	return "hello";
}

用戶控制器中的方法的返回值可以是字符串,如果沒有視圖解析器的解析,這個(gè)字符串就是一個(gè)字符串。如果有了視圖解析器,則會(huì)把這個(gè)字符串當(dāng)成一個(gè)視圖的邏輯名,并映射到真正的物理視圖。

Tips:視圖解析器和映射器的有相似之處,映射器是入口時(shí)根據(jù)請(qǐng)求控制器邏輯名找到物理控制器,視圖解析器是出口時(shí)根據(jù)視圖邏輯名找到物理視圖

Spring MVC 默認(rèn)使用的 InternalResourceViewResolver 作為視圖解析器, 提供對(duì) JSP 視圖的支持。

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

無(wú)論是 Spring MVC 默認(rèn)提供的、還是開發(fā)者自行定義的視圖解析器,都必須實(shí)現(xiàn) ViewResolver 接口:

public interface ViewResolver {
    @Nullable
    View resolveViewName(String viewName, Locale locale) throws Exception;
}

為什么不在用戶控制器的方法中直接返回物理視圖(完整資源路徑描述),而是使用視圖解析映射物理位置?

答案很簡(jiǎn)單:

  • 控制器中的響應(yīng)代碼不需要知道視圖的具體物理位置,通過(guò)視圖解析器解耦控制器對(duì)視圖物理位置的依賴;
  • 通過(guò)獨(dú)立的視圖解組件可以擴(kuò)展 Spring MVC 對(duì)各種不同視圖技術(shù)的支持。Spring MVC 就支持多達(dá) 13 種視圖技術(shù);
  • 簡(jiǎn)化控制器中的響應(yīng)代碼;

3.2 配置視圖解析器

視圖解析器需要在 Spring MVC 項(xiàng)目中顯示配置,Spring MVC 雖然提供了視圖解析器,但它不可能知道開發(fā)者會(huì)把物理視圖放在哪個(gè)位置,所以,需要通過(guò)配置指定物理視圖的真正位置。

配置 InternalResourceViewResolver 很簡(jiǎn)單。打開 WebConfig 配置類,在配置類中添加如下代碼;

@Bean
public InternalResourceViewResolver viewResolver() {	
	InternalResourceViewResolver inResolver=new InternalResourceViewResolver();	
	inResolver.setPrefix("/WEB-INF/jsp/");
	inResolver.setSuffix(".jsp");
	return inResolver;
}

解釋一下上面的代碼:

  • @Bean 注解表示此對(duì)象由 Spring 容器創(chuàng)建;
  • inResolver.setPrefix ("/WEB-INF/jsp/") 表示 JSP 頁(yè)面視圖所在物理位置;
  • inResolver.setSuffix (".jsp") 表示 JSP 視圖的后綴。

Tips : 如果控制器中返回的是 “hello” 字符串,經(jīng)視圖解析器解析后,則認(rèn)為對(duì)應(yīng)的物理視圖是 “/WEB-INF/jsp/hello.jsp”
需要保證存在這個(gè)文件,否則瀏覽器上就會(huì)出現(xiàn) 404 錯(cuò)誤。

Ok 按要求在項(xiàng)目的 WEB-INF 目錄下創(chuàng)建 jsp 目錄,再在此目錄下創(chuàng)建名為 hello.jsp 文件,并編輯內(nèi)容。

再次在瀏覽器中輸入:http://localhost:8888/sm-demo/hello 。

你會(huì)看到:

圖片描述

Spring MVC 除了支持 JSP 視圖,還支持其它如:freemarker、thymeleaf 等視圖技術(shù)。會(huì)另設(shè)專題講解。

3.3. 靜態(tài)資源

如果瀏覽器中請(qǐng)求的是一個(gè)靜態(tài)資源(瀏覽器能解釋的資源,如 HtmlCss、Js、圖片……),有必要經(jīng)過(guò)前端控制器嗎?

當(dāng)然不需要。

但是,你可以試著在 WEB 項(xiàng)目的 根目錄下創(chuàng)建名為 static.html 的靜態(tài)資源,然后在瀏覽器直接請(qǐng)求一下(http://localhost:8888/sm-demo/static.html)。會(huì)發(fā)現(xiàn)請(qǐng)求不到,那是因?yàn)槟愕恼?qǐng)求還是經(jīng)過(guò)了前端控制器。

所以,咱們要告訴 Spring MVC 靜態(tài)資源還是交回給 Servlet 容器處理吧, 就不勞您大駕了。

  • 打開 WebConfig 配置類,讓其實(shí)現(xiàn) WebMvcConfigurer 接口;
public class WebConfig implements WebMvcConfigurer{ 

}
  • 重寫 configureDefaultServletHandling() 方法,啟動(dòng) Servletdefault Servlet 來(lái)處理靜態(tài)資源;
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
	configurer.enable();
}

圖片描述

4. 組件之間的協(xié)作關(guān)系

通過(guò)對(duì)幾大核心組件的介紹,相信大家對(duì)它們各自的功能有所了解。但是,你知道它們之間是如何協(xié)作一起完成用戶的一次請(qǐng)求的嗎?

當(dāng)用戶在瀏覽器發(fā)出請(qǐng)求的那一刻起,這些組件就緊密地團(tuán)結(jié)在一起,為用戶的請(qǐng)求保駕護(hù)航。

圖片描述
如上圖所述,簡(jiǎn)要描述一下它們是如何協(xié)調(diào)一致完成工作的:

  1. 瀏覽器的請(qǐng)求到達(dá)前端控制器DispatcherServlet);
  2. 前端控制器解析出請(qǐng)求路徑后詢問(wèn)映射器,咱們是否提供的有用戶需要的用戶控制器,映射器把查詢結(jié)果返回給前端控制器;
  3. 適配器的作用就是統(tǒng)一不同類型的用戶控制器(也體現(xiàn)了 Spring MVC 中用戶控制器的多樣性和靈活性);
  4. 用戶控制器開始工作(具體的響應(yīng)邏輯);
  5. 用戶控制器返回視圖邏輯名和視圖中所需要的數(shù)據(jù)ModelAndView);
  6. 前端控制器詢問(wèn)視圖解析器,你能夠根據(jù)邏輯名找到物理視圖嗎?視圖解析器開始工作并找到物理視圖;
  7. 前端控制器渲染物理視圖和數(shù)據(jù),生成瀏覽器能夠識(shí)別的數(shù)據(jù)格式;
  8. 響應(yīng)瀏覽器,并在瀏覽器中顯示最終請(qǐng)求結(jié)果。

Spring MVC 中,用戶的每一次請(qǐng)求都是眾多組件通力合作完成的,它們是相親相愛的一家人。

5. 小結(jié)

每一個(gè)組件都有自己的特點(diǎn),但大家都有一個(gè)共同特點(diǎn),都是為前端控制器服務(wù)的。

用戶的每一次請(qǐng)求、響應(yīng),都是經(jīng)由所有組件一起協(xié)作完成的。組件之間有很好的隔離性,但其內(nèi)部又有其完善的功能,高內(nèi)聚,低耦合是 Spring MVC 組件最大的特色。通過(guò)本章節(jié)內(nèi)容的學(xué)習(xí),務(wù)必記住這些組件及組件的功能。