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

Spring MVC 核心組件(下)

1. 前言

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

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

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

2. 適配器

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

圖片描述

如上圖,調用者只能識別接口 2 類型,但是 A 提供的是接口 1 類型。適配器可以把接口 1 轉換成接口 2。這樣使用者就能使用 A 提供的功能了。

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

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

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

比如說實現 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 提供有更靈活的用戶控制器設計方案,可使用 “ 普通 JAVA 類” 充當控制器,控制器中的方法也可由開發(fā)者隨性命名。

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

Spring MVC 提供了 3 個默認適配器:

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

這些適配對象都實現了 HandlerAdapter 接口,此接口就有一個統一的內部調用方法。

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

簡要描述 3 個適配器的應用場景:

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

因為有適配器的存在,可以讓控制器的設計變得靈活。

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

3. 視圖解析器

3.1 視圖解析器的功能

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

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

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

Tips:視圖解析器和映射器的有相似之處,映射器是入口時根據請求控制器邏輯名找到物理控制器,視圖解析器是出口時根據視圖邏輯名找到物理視圖

Spring MVC 默認使用的 InternalResourceViewResolver 作為視圖解析器, 提供對 JSP 視圖的支持。

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

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

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

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

答案很簡單:

  • 控制器中的響應代碼不需要知道視圖的具體物理位置,通過視圖解析器解耦控制器對視圖物理位置的依賴;
  • 通過獨立的視圖解組件可以擴展 Spring MVC 對各種不同視圖技術的支持。Spring MVC 就支持多達 13 種視圖技術;
  • 簡化控制器中的響應代碼;

3.2 配置視圖解析器

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

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

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

解釋一下上面的代碼:

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

Tips : 如果控制器中返回的是 “hello” 字符串,經視圖解析器解析后,則認為對應的物理視圖是 “/WEB-INF/jsp/hello.jsp”
需要保證存在這個文件,否則瀏覽器上就會出現 404 錯誤。

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

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

你會看到:

圖片描述

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

3.3. 靜態(tài)資源

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

當然不需要。

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

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

  • 打開 WebConfig 配置類,讓其實現 WebMvcConfigurer 接口;
public class WebConfig implements WebMvcConfigurer{ 

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

圖片描述

4. 組件之間的協作關系

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

當用戶在瀏覽器發(fā)出請求的那一刻起,這些組件就緊密地團結在一起,為用戶的請求保駕護航。

圖片描述
如上圖所述,簡要描述一下它們是如何協調一致完成工作的:

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

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

5. 小結

每一個組件都有自己的特點,但大家都有一個共同特點,都是為前端控制器服務的。

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