1. Spring MVC 中檢視的實現原理,在Spring MVC 中實現重定向和轉發,以及訪問靜態資源
@
- 1. Spring MVC 中檢視的實現原理,在Spring MVC 中實現重定向和轉發,以及訪問靜態資源
- 1.1 Spring MVC檢視支援可配置
- 1.2 Spring MVC支援的常見檢視
- 1.3 實現檢視機制的核心介面
- 1.4 實現檢視機制的原理描述
- 1.5 邏輯檢視名到物理檢視名的轉換
- 2. Thymeleaf檢視
- 3. JSP檢視(瞭解)
- 4. 轉發與重定向
- 4.1 轉發和重定向區別
- 5. 在 Spring MVC 中 “重定向” 以及 “轉發”
- 5.1 在 Spring MVC 中使用 forward 實現轉發
- 5.2 在 Spring MVC 中使用 redirect 實現重定向
- 6. mvc:view-controller 和 mvc:annotation-driven/ 的配合使用
- 7. Spring MVC 中訪問靜態資源
- 7.1 第一種方案:開啟預設的 Servlet處理
- 7.2 第二種方案:使用 mvc:resources 標籤配置靜態資源
- 8. 總結:
- 9. 最後:
1.1 Spring MVC檢視支援可配置
在Spring MVC中,檢視 View 是支援定製的,例如我們之前在 springmvc.xml 檔案中進行了如下的配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--元件掃描-->
<context:component-scan base-package="com.rainbowsea.springmvc.controller"></context:component-scan>
<!-- 檢視解析器-->
<!-- 檢視解析器-->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<!--作用於檢視渲染的過程中,可以設定檢視渲染後輸出時採用的編碼字符集-->
<property name="characterEncoding" value="UTF-8"/>
<!--如果配置多個檢視解析器,它來決定優先使用哪個檢視解析器,它的值越小優先順序越高-->
<property name="order" value="1"/>
<!--當 ThymeleafViewResolver 渲染模板時,會使用該模板引擎來解析、編譯和渲染模板-->
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<!--用於指定 Thymeleaf 模板引擎使用的模板解析器。模板解析器負責根據模板位置、模板資源名稱、檔案編碼等資訊,載入模板並對其進行解析-->
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<!--設定模板檔案的位置(字首)-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!--設定模板檔案字尾(字尾),Thymeleaf副檔名不一定是html,也可以是其他,例如txt,大部分都是html-->
<property name="suffix" value=".html"/>
<!--設定模板型別,例如:HTML,TEXT,JAVASCRIPT,CSS等-->
<property name="templateMode" value="HTML"/>
<!--用於模板檔案在讀取和解析過程中採用的編碼字符集-->
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
以上的配置表明當前 Spring MVC 框架使用的檢視 View 是 Thymelea 的。
如果你需要換成其他的檢視 View,修改以上的配置即可。這樣就可以非常輕鬆的完成檢視 View 的擴充套件。
這種設計是完成符合 OCP 開閉原則 的。檢視 View 和框架是解耦合的,耦合度低擴充套件能力強。
檢視 View 可以透過配置檔案進行靈活切換。
1.2 Spring MVC支援的常見檢視
Spring MVC支援的常見檢視包括:
- InternalResourceView:內部資源檢視(Spring MVC框架內建的,專門為
JSP模板語法
準備的) - RedirectView:重定向檢視(Spring MVC框架內建的,用來完成重定向效果)
- ThymeleafView:Thymeleaf檢視(第三方的,為
Thymeleaf模板語法
準備的) - FreeMarkerView:FreeMarker檢視(第三方的,為
FreeMarker模板語法
準備的) - VelocityView:Velocity檢視(第三方的,為
Velocity模板語法
準備的) - PDFView:PDF檢視(第三方的,專門用來生成pdf檔案檢視)
- ExcelView:Excel檢視(第三方的,專門用來生成excel檔案檢視)
- ......
1.3 實現檢視機制的核心介面
實現檢視的核心類與介面包括:
DispatcherServlet類(前端控制器):
- 職責:在整個Spring MVC執行流程中,負責中央排程。
- 核心方法:doDispatch
ViewResolver 介面(檢視解析器)
-
職責:負責將
邏輯檢視名
轉換為物理檢視名
,最終建立 View 介面的實現類,即檢視實現類物件。 -
核心方法:resolveViewName
View 介面(檢視):
- 職責:負責將模型資料 Model 渲染為檢視格式(HTML程式碼),並最終將生成的檢視(HTML程式碼)輸出到客戶端。(它負責將模板語言轉換成 HTML程式碼)
- 核心方法:render
ViewResolverRegistry (檢視解析器註冊器):
負責在 web 容器(Tomcat)啟動的時候,完成檢視解析器的註冊。
如果有多個檢視解析器,會將檢視解析器物件按照 order 的配置放入 List 集合。
總結:
實現檢視的核心類和介面包括:ViewResolverRegistry,DispatcherServlet,ViewResolver,View
如果你想定製自己的檢視元件:
- 編寫類實現 ViewResolver 介面,實現 resolveViewName方法,在該方法中完成 邏輯檢視名 轉換為物理檢視名 ,並返回 View 物件。
- 編寫類實現 View 介面,實現 render 方法,在該方法中將模板語言轉換成 HTML程式碼,並將HTML程式碼響應到瀏覽器。
如果 Spring MVC 框架中使用 Thymeleaf 作為檢視技術。那麼相關的類包括:
- ThymeleafView
- ThymeleafViewResolver
1.4 實現檢視機制的原理描述
假設我們Spring MVC 中使用了 Thymeleaf 作為檢視:
- 第一步:瀏覽器傳送請求給 web 伺服器
- 第二步:Spring MVC中的 DispatcherServlet 接收到請求
- 第三步:DispatcherServlet 根據請求路徑分發到對應的 Controller
- 第四步:DispatcherServlet 呼叫 Controller 的方法
- 第五步:Controller 的方法處理業務並返回一個 邏輯檢視名 給 DispatcherServlet
- 第六步:DispatcherServlet 呼叫 ThymeleafViewResovler 的 resolveViewName方法,將邏輯檢視名 轉換為 物理檢視名 ,並建立 ThymeleafView 物件返回給 DispatcherServlet
- 第七步:DispatcherServlet 再呼叫 ThymeleafView 的 render 方法,render 方法將模板語言轉換為 HTML程式碼,響應給瀏覽器,完成最終的渲染。
假設我們 Spring MVC 中使用了JSP作為檢視:
- 第一步:瀏覽器傳送請求給 web 伺服器
- 第二步:Spring MVC 中的DispatcherServlet 接收到請求
- 第三步:DispatcherServlet 根據請求路徑分發到對應的 Controller
- 第四步:DispatcherServlet 呼叫 Controller 的方法
- 第五步:Controller 的方法處理業務並返回一個 邏輯檢視名 給 DispatcherServlet
- 第六步:DispatcherServlet 呼叫 InternalResourceViewResovler 的 resolverViewName 方法,將邏輯檢視 轉換為 物理檢視名 ,並建立 InternalResourceView 物件返回給 DispathcerServlet 。
- 第七步:DispatcherServlet 再呼叫 InternalResourceView 的 render 方法,render 方法將模板語言轉換為 HTML 程式碼,響應給瀏覽器,完成最終的渲染。
1.5 邏輯檢視名到物理檢視名的轉換
邏輯檢視名最終轉換的物理檢視名是什麼,取決再 springmvc.xml 檔案中檢視解析器的配置: 假如檢視解析器配置的是 ThymeleafViewResolver,如下:
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="order" value="1"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
以下程式返回邏輯檢視名:index
package com.rainbowsea.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 交給 Spring IOC 容器管理起來
public class IndexController {
@RequestMapping("/")
public String index() {
return "index";
}
}
最終邏輯檢視名 "index" 轉換為物理檢視名: /WEB-INF/templates/index.html
假如檢視解析器配置的是 InternalResourceViewResolver,如下:
<!-- jsp檢視解析器-->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
以下程式返回邏輯檢視名:index
package com.rainbowsea.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 交給 Spring IOC 容器管理起來
public class IndexController {
@RequestMapping("/")
public String index() {
return "index";
}
}
最終邏輯檢視名 "index" 轉換為物理檢視名:/ WEB-INF/templates/index.jsp
2. Thymeleaf檢視
我們在學習前面內容的時候,採用的都是 Thymeleaf檢視。我們再來測試一下,看看底層建立的檢視物件是不是ThymeleafView
springmvc.xml 配置內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--元件掃描-->
<context:component-scan base-package="com.powernode.springmvc.controller"/>
<!--檢視解析器-->
<bean id="thymeleafViewResolver" class="org.thymeleaf.spring6.view.ThymeleafViewResolver">
<property name="characterEncoding" value="UTF-8"/>
<property name="order" value="1"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring6.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring6.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/thymeleaf/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
</beans>
Controller程式碼如下:
package com.rainbowsea.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 交給 Spring IOC 容器管理起來
public class IndexController {
@RequestMapping("/")
public String index() {
return "index";
}
}
檢視頁面:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>index page</title>
</head>
<body>
<h1>index page</h1>
</body>
</html>
新增斷點:在 DispatcherServlet 的 doDispatch( )方法的下圖位置新增斷點。
啟動Tomcat,在瀏覽器位址列上傳送請求:http://localhost:8080/springmvc/index
程式走到以上位置,這行程式碼是呼叫對應的Controller,並且Controller最終會返回 ModelAndView物件:mv 按照我們之前所講,返回 mv 之後,接下來就是檢視處理與渲染,接著往下走,走到下圖這一行:
這個方法的作用是處理分發結果,就是在這個方法當中進行了檢視的處理與渲染,進入該方法:
進去之後走到上圖位置:這個方法就是用來渲染頁面的方法,再進入該方法:
走到上圖位置就可以看到底層建立的是 ThymeleafView 物件。
3. JSP檢視(瞭解)
我們再來跟一下原始碼,看看 JSP 檢視底層建立的是不是 InternalResourceView物件。
我們前面說過 InternalResourceView是SpringMVC框架內建的,翻譯為內部資源檢視,SpringMVC把JSP看做是內部資源。可見JSP在之前的技術棧中有很高的地位。
不過,當下流行的開發中JSP使用較少,這裡不再詳細講解。只是測試一下。
springmvc.xml配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--元件掃描-->
<context:component-scan base-package="com.powernode.springmvc.controller"/>
<!--檢視解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
Controller程式碼如下:
package com.powernode.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
@RequestMapping("/index")
public String toIndex(){
return "index";
}
}
檢視頁面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>index jsp</title>
</head>
<body>
<h1>index jsp!</h1>
</body>
</html>
啟動web容器,新增斷點跟蹤:
透過測試得知:對於JSP 檢視來說,底層建立的檢視物件是 InternalResourceView。
4. 轉發與重定向
4.1 轉發和重定向區別
- 轉發是一次請求,因此瀏覽器位址列上的地址不會發生變化。
- 重定向是兩次請求,因此瀏覽器位址列上的地址會發生變化。
- 轉發的程式碼實現:request.getRequestDispatcher("/index").forward(request, response);
- 重定向的程式碼實現:response.sendRedirect("/webapproot/index");
- 轉發是伺服器內部資源跳轉,由伺服器來控制。不可實現跨域訪問。
- 重定向可以完成內部資源的跳轉,也可以完成跨域跳轉。
- 轉發的方式可以訪問 WEB-INF 目錄下受保護的資源。
- 重定向相當於瀏覽器重新傳送了一次請求,在瀏覽器直接傳送的請求是無法訪問 WEB-INF目錄下受保護的資源的。
- 轉發原理:
- 假設傳送了 /a 請求,執行了 AServlet
- 在 AServlet 中透過
request.getRequestDispatcher("/b").forward(request,response);
轉發到 BServlet- 從AServlet 跳轉到 BServlet 是伺服器內部來控制的。對於瀏覽器而言,瀏覽器只傳送了一個 /a 請求。
- 重定向原理:
- 假設傳送了 /a 請求,執行了 AServlet
- 在 AServlet 中透過
response.sendRedirect("/webapproot/b")
- 此時伺服器會將請求路徑
/webapproot/b
響應給瀏覽器- 瀏覽器會自發的再次傳送
webapproot/b
請求來訪問 BServlet- 因此對於重定向來說,傳送了兩次請求,一次是
/webapproot/a
,另一次是webapproot/b
。
更多關於 Java Web 轉發和重定向的內容,大家可以移步至:✏️✏️✏️ JavaWeb 中 “轉發”與 “重定向”的區別_java 重定向與轉發-CSDN部落格
以上所描述的是使用原生Servlet API來完成轉發和重定向。在Spring MVC中是如何轉發和重定向的呢?
5. 在 Spring MVC 中 “重定向” 以及 “轉發”
5.1 在 Spring MVC 中使用 forward 實現轉發
在Spring MVC中預設就是轉發的方式,我們之前所寫的程式,都是轉發的方式。
在 Spring MVC 中是怎麼透過程式碼完成轉發的?
@RequestMapping("/a")
public String toA() {
// 返回的是一個邏輯檢視名稱
return "a"; // 轉發 ThymeleafView
}
注意,當 return "a"; 的時候,返回一個邏輯檢視名稱,這種方式跳轉到檢視,預設採用的就是 forward 方式跳轉過去的
只不過都是轉發到 Thymeleaf 的模板檔案xxx.html上。
那麼,在Spring MVC中如何轉發到另一個Controller上呢?可以使用Spring MVC的forward
使用格式如下:
return "forward:/b";轉發到 /b ,這是一次請求,底層建立的檢視物件是:internalResourceView物件
注意: "forward:/b" 這個已經不是邏輯檢視名稱了,是以轉發的方式跳轉,是一個資源路徑。
package com.rainbowsea.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 交給 Spring IOC 容器進行管理
public class ForwardController {
@RequestMapping("/a")
public String toA() {
// 返回的是一個邏輯檢視名稱
//return "a";
// 採用SpringMVC的轉發方式跳轉到 /b
// 轉發的時候,格式有特殊要求,return "forward:下一個資源的路徑"
// 這種方式就不是邏輯檢視名稱了
return "forward:/b"; // 建立InternalResourceView物件
// 這個使用較多,重定向,url 中會顯示資源路徑
// return "redirect:/b";
}
@RequestMapping("/b")
public String toB() {
// 返回的是一個邏輯檢視名稱
return "b";
}
}
檢視頁面:
A 檢視頁面編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>page a </title>
</head>
<body>
<h1>Page A !!!</h1>
</body>
</html>
B 檢視頁面編寫:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>page b</title>
</head>
<body>
<h1>Page B !!!</h1>
</body>
</html>
啟動伺服器,瀏覽器位址列上輸入:http://localhost:8080/springmvc/a
透過測試,可以順利的完成轉發,轉發是一次請求,可以看到位址列上的地址沒有發生改變。
我們來跟蹤一下原始碼,看看以上程式執行過程中,建立了幾個檢視物件,分別是什麼?
透過原始碼的跟蹤得知:整個請求處理過程中,一共建立了兩個檢視物件 ?
InternalResourceView
ThymeleafView
這說明轉發底層建立的檢視物件是:InternalResourceView
思考: 既然會建立 InternalResourceView,應該會對應一個檢視解析器(InternalResourceViewResolver) ? 但是,我們在 springmvc.xml
檔案中只配置了 ThymeleafViewResolver ,並沒有配置 InternalResourceViewResolver ,這是為什麼?
這是因為
forward:
後面的不是 邏輯檢視名 ,而是一個 請求路徑 ,因此,轉發是不需要檢視解析器的。另外,轉發使用的是 InternalResourceView ,也說明了轉發是內部資源的跳轉,(Internal 是內部的意思,Resource 是資源的意思。)
5.2 在 Spring MVC 中使用 redirect 實現重定向
redirect
是專門完成重定向效果的。和 forward
語法類似,只需要將之前的 return "forward:/b"
修改為 return "redirect:/b"
即可。
啟動伺服器,瀏覽器位址列上輸入:http://localhost:8080/springmvc/a
可見,重定向是兩次請求,位址列上的地址發生了改變。
可以看一下原始碼,在重定向的時候,Spring MVC建立哪個檢視物件?
透過斷點除錯可以看出,當重定向的時候,SpringMVC會建立一個重定向檢視物件:RedirectView。這個檢視物件也是SpringMVC框架內建的。
另外可以看出重定向之後的第二次請求建立的檢視物件就是ThymeleafView了。
注意:從springmvc應用重定向到springmvc2應用(跨域),語法是:
@RequestMapping("/a")
public String a(){
return "redirect:http://localhost:8080/springmvc2/b";
}
可以自行測試一下!!!
總結:
轉發: return "forward:/b" 底層建立的是InternalResourceView物件
重定向: return "redirect:/b" 底層建立的是 RedirectView物件
6. mvc:view-controller 和 mvc:annotation-driven/ 的配合使用
<mcx:view-controller>
配置用於將某個請求對映到特定的檢視上,即指定某一個 URL 請求到一個檢視資源的對映,使得這個檢視資源可以被訪問。它相當於是一個獨立的處理程式,不需要編寫任何 Controller ,只需要指定 URL 和對應的檢視名稱就可以了。注意僅僅只是對應的 Controller 不需要寫,其中對應的 html,jsp 或者是其他的檢視是一定需要編寫的。
一般情況下,<mvc:view-controller>
配置可以替代一些沒有業務邏輯的 Controller,例如:首頁,錯誤頁面等。當使用者訪問配置的 URL時,框架將直接匹配到對應的檢視,而無需再經過其他控制器的處理。
<mvc:view-controller > 配置的格式如下:
<mvc:view-controller path="/如何訪問該頁面" view-name="對應的邏輯檢視名稱" />
其中:
path
:被對映的 URL 路徑。
view-name
:對應的邏輯檢視名稱。
例如,配置首頁的對映:
<mvc:view-controller path="/" view-name="index" />
上述配置將會匹配上訪問應用程式的根路徑,如:http://localhost:8080/springmvc。當使用者在瀏覽器中訪問該根路徑時,就會直接渲染名為 index
的檢視。
重點:
在SpringMVC中,如果在springmvc.xml檔案中配置了
<mvc:view-controller >
,就需要同時在springmvc.xml檔案中新增如下配置:< mvc:annotation-driven />
<mvc:annotation-driven/>
該配置的作用是:啟用Spring MVC的註解。
如果沒有以上的配置,Controller 就無法訪問到。訪問之前的Controller會發生 404 問題。
7. Spring MVC 中訪問靜態資源
一個專案可能會包含大量的靜態資源,比如:css,js,images等。
由於我們 DispatcherServelt 的 url-pattern 的配置是 “/” 。
之前我們說過,這個“/” 代表的是除了jsp
請求之外的所有請求,也就是說訪問應用中的靜態資源,也會走 DispatcherServlet ,這會導致 404 錯誤,無法訪問靜態資源,如何解決,兩種方案:
7.1 第一種方案:開啟預設的 Servlet處理
第一種解決方案,開啟預設的 Servlet處理
在Tomcat伺服器中提供了一個預設的Servlet,叫做: org.apache.catalina.servlets.DefaultServlet
在CATALINA_HOME/conf/web.xml檔案中,有這個預設的 Servlet的相關配置
不過,這個預設的Servlet預設情況下是不開啟的
你需要在springmvc.xml檔案中使用以下配置進行開啟
<mvc:default-servlet-handler/>
<mvc:annotation-driven> 開啟註解驅動
// 注意:上面這兩個配置是一起的,不可以分開來使用。
> 開啟之後的作用是:當你訪問: http://localhost:8080/springmvc/static/img/touxiang.jpeg 的時候。
> 預設先走:DispatcherServlet,如果發生 404 錯誤的話,會自動走DefaultServlet,然後 DefaultServlet 幫你定位
> 靜態資源
首先需要在 springmvc.xml 檔案中新增以下配置,開啟 預設Servlet處理靜態資源
功能:
注意:下面兩個配置是一起的,不可以分開來(就是,這兩個配置都要有才行,不可以缺少其中的任意一個) 。
<!-- 開啟註解驅動 -->
<mvc:annotation-driven />
<!--開啟預設Servlet處理-->
<mvc:default-servlet-handler>
然後在 web.xml 檔案中指定什麼樣的路徑走其他 Servlet:
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
以上配置 url-pattern 使用的也是 “/”,和 DispatcherServlet 一樣。表示的含義是:同一個請求路徑,先走 DispatcherServlet,如果找不到則走預設的Servlet。
預設的 Servlet 類中的程式碼已經由 Tomcat 伺服器提供了實現了,一般不需要開發者自己編寫。
上面的示例中,我們指定了 org.apache.catalina.servlets.DefaultServlet
,則 Tomcat 伺服器會自動將請求轉發到該類處理,再處理時,該類會根據請求的 URL 去查詢 Web 應用的靜態資源(如 HTML,CSS,JavaScript 和圖片等),並將其返回給使用者。
告訴大家一個好訊息,以上在 web.xml 檔案中的配置,我們也可以省略了,因為在 Tomcat 伺服器中已經為我們提前配置好了,在 CATALINA_HOME/conf/web.xml 檔案中,如下:
因此我們只需要在springmvc.xml檔案中啟用這個預設的Servlet即可:<mvc:default-servlet-handler>
7.2 第二種方案:使用 mvc:resources 標籤配置靜態資源
第二種解決方案:配置靜態資源處理,在springmvc.xml檔案中新增如下配置
<mvc:resources mapping="/static/**" location="/static/"></mvc:resources>
<mvc:annotaiton-driven> //開啟註解驅動
同樣這兩個是一起配合使用的,不可以分開來
> 作用:當請求路徑符合 /static/**的時候,去 /static/位置找資源
訪問靜態資源,也可以在springmvc.xml檔案中新增如下的配置:
<!-- 開啟註解驅動 -->
<mvc:annotation-driven />
<!-- 配置靜態資源處理 -->
<mvc:resources mapping="/static/**" location="/static/" />
表示凡是請求路徑是"/static/"開始的,都會去"/static/"目錄下找該資源。
注意:要想使用 <mvc:resources>
配置,必須開啟註解驅動 <mvc:annotation-driven />
8. 總結:
- ViewResolver 介面,檢視解析介面(ThymeleafViewResolver 實現了 ViewResolver 介面,InternalResourceViewResolver 也是實現了
ViewResolver介面...),這個介面作用是將邏輯檢視名稱 轉換為 物理檢視名稱,並且最終返回一個 view 介面物件,核心方法是:View resolveViewName(String viewName,Locale locale) throws Exception;- View 介面,檢視介面(ThymeleafView 實現了介面,InternalResourceView 也實現了 View 介面)這個介面做什麼的?這個介面負責模板語法的字串轉換成 html程式碼,並且將html程式碼響應給瀏覽器。(渲染)核心方法是 void render(@Nullable Map<String,?> model,HttpServletRequest request, HttpServletResponse response) throws Exception;
- 注意:預設的
在 Spring MVC 中是怎麼透過程式碼完成轉發的? @RequestMapping("/a") public String toA() { // 返回的是一個邏輯檢視名稱 return "a"; // 轉發 ThymeleafView } 注意,當 return "a"; 的時候,返回一個邏輯檢視名稱,這種方式跳轉到檢視,預設採用的就是 forward 方式跳轉過去的
forward 的轉發格式:return "forward:/b";轉發到 /b ,這是一次請求,底層建立的檢視物件是:internalResourceView物件。
redirect 重定向格式:return "redirect:/b";轉發到 /b,這是兩次請求,底層建立的檢視物件是:RedirectView物件。注意語法:必須以 : redirect:開始
thymeleaf 模板字串,這個是瀏覽器不認識的。ThymeleafView進行解析將其轉換成html響應給瀏覽器。
mvc:view-controller 和 mvc:annotation-driven/ 的配合使用,不需要編寫任何 Controller ,只需要指定 URL 和對應的檢視名稱就可以了。注意僅僅只是對應的 Controller 不需要寫,其中對應的 html,jsp 或者是其他的檢視是一定需要編寫的。注意:兩個配置都要寫上,缺一不可 。
Spring MVC 中訪問靜態資源:兩種方式:
- 第一種方案:開啟預設的 Servlet處理
<!-- 開啟註解驅動 --> <mvc:annotation-driven /> <!--開啟預設Servlet處理--> <mvc:default-servlet-handler>
- 第二種方案:使用 mvc:resources 標籤配置靜態資源
<!-- 開啟註解驅動 --> <mvc:annotation-driven /> <!-- 配置靜態資源處理 --> <mvc:resources mapping="/static/**" location="/static/" />
9. 最後:
“在這個最後的篇章中,我要表達我對每一位讀者的感激之情。你們的關注和回覆是我創作的動力源泉,我從你們身上吸取了無盡的靈感與勇氣。我會將你們的鼓勵留在心底,繼續在其他的領域奮鬥。感謝你們,我們總會在某個時刻再次相遇。”