ACWING 368 銀河
一、簡介
(一)MVC的概念
MVC是一種軟體架構思想,將軟體劃分為『模型』、『檢視』、『控制器』
M:Model,模型層
指工程中的『 JavaBean 』,作用是處理資料
JavaBean有兩種:
❶實體類Bean:指pojo物件,儲存業務資料
❷業務處理Bean:指Service或Dao物件,處理業務邏輯和資料訪問
V:View,檢視層
指工程中的『 頁面 』,作用是與使用者進行互動,展示資料
C:Controller,控制層
指工程中的『 Servlet 』,作用是接收請求和響應瀏覽器
(二)SpringMVC的概念
SpringMVC是Spring的一個後續產品,是Spring的一個子專案
SpringMVC是Spring為 表述層 開發提供的一整套的完備的解決方案
注:三層架構分別為表述層、業務邏輯層、資料訪問層。表述層包含前臺頁面和後臺servlet
(三)SpringMVC的特點
- Spring家族原生產品,與IOC容器等基礎設施無縫對接
- 基於原生的Servlet,通過了功能強大的的前端控制器DispathcherServlet,對請求和響應進行統一處理
- 表述層各細分領域需要解決的問題全方位覆蓋,提供全面解決方案
- 程式碼清新簡潔,大幅度提升開發效率
- 內部元件化程度高,可插拔式元件即插即用
- 效能卓著,尤其適用現代大型、超大型網際網路專案要求
二、開發流程
(一)引入依賴
<dependencies> <!-- SpringMVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.3.1</version> </dependency> <!-- 日誌 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- ServletAPI --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- Spring5和Thymeleaf整合包 --> <dependency> <groupId>org.thymeleaf</groupId> <artifactId>thymeleaf-spring5</artifactId> <version>3.0.12.RELEASE</version> </dependency> </dependencies>
(二)配置web.xml
註冊SpringMVC的前端控制器DispatcherServlet
1、預設配置方式
位置預設,位於WEB-INF下
名稱預設,<servlet-name>-servlet.xml
<!-- 配置SpringMVC的前端控制器 -->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<!-- / 不匹配.jsp請求路徑的請求 -->
<!-- /* 匹配所有請求路徑的請求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
2、擴充套件配置方式
<init-param>,設定配置檔案的『位置』和『名稱』
<load-on-startup>,設定初始化時間
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 通過初始化引數指定SpringMVC配置檔案的位置和名稱 -->
<init-param>
<!-- contextConfigLocation為固定值 -->
<param-name>contextConfigLocation</param-name>
<!-- 配置檔案的存放路徑 src/main/resources -->
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!-- DispatcherServlet的初始化時間提前到伺服器啟動時 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
(三)建立請求控制器
@Controller
public class HelloController {
@RequestMapping("/") //設定訪問路徑
public String index() {
return "index"; //返回檢視名稱
}
}
(四)建立MVC配置檔案
<!-- 自動掃描包 -->
<context:component-scan base-package="com.atguigu.mvc.controller"/>
<!-- 配置Thymeleaf檢視解析器 -->
<bean id="viewResolver" class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 檢視字首 -->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 檢視字尾 -->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8" />
</bean>
</property>
</bean>
</property>
</bean>
<!-- 開啟mvc註解驅動 -->
<mvc:annotation-driven>
<mvc:message-converters>
<!-- 處理響應中文內容亂碼 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
<property name="supportedMediaTypes">
<list>
<value>text/html</value>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
三、@RequestMapping
(一)概述
功能作用:將 請求 和 處理請求的控制器方法 關聯起來,建立對映關係
註解位置:
❶標識一個類:設定對映請求的 請求路徑的 初識資訊
❷標識一個方法:設定對映請求的 請求路徑的 具體資訊
(二)屬性
1、value屬性
該屬性必須設定
註解的value屬性 通過請求的 請求地址 匹配請求對映
註解的value屬性 是一個字串型別的陣列,可以對映多個請求地址
2、method屬性
註解的method屬性 通過請求的 請求方式 匹配請求對映
註解的method屬性 是一個RequestMethod型別的陣列,可以匹配多個
1、請求地址滿足value屬性,不滿足method屬性,405錯誤:Request method ‘POST’ not support
2、對於處理指定請求的控制器方法,SpringMVC中提供了@RequestMapping的派生註解
@GetMapping、@PostMapping、@PutMapping、@DeleteMapping
3、params屬性
註解的params屬性 通過請求的 請求引數 匹配請求對映
註解的params屬性 是一個字串型別的陣列,有四種設定表示式
❶『 param 』:請求必須攜帶param引數
❷『 !param 』:請求必須不能攜帶param引數
❸『 param=value 』:請求必須攜帶param引數,且值為value
❹『 param!=value 』:請求必須不能攜帶param引數,且值不為value
請求地址滿足value和method屬性,不滿足params屬性,400錯誤,Parameter conditions ... not met for actual request parameters
4、headers屬性
註解的headers屬性 通過請求的 請求頭資訊 匹配請求對映
註解的headers屬性 是一個字串型別的陣列,有四種設定表示式
❶『 header 』:請求必須攜帶header請求頭資訊
❷『 !header 』:請求必須不能攜帶header請求頭資訊
❸『 header=value 』:請求必須攜帶header請求頭資訊,且值為value
❹『 header!=value 』:請求必須不能攜帶header請求頭資訊,且值不為value
請求地址滿足value和method屬性,不滿足headers屬性,404錯誤,資源未找到
(三)value屬性補充
1、支援ant風格的路徑
即 模糊匹配
『 ? 』:表示任意的單個字元
『 * 』 :表示任意的0個或多個字元
『 ** 』:表示任意的0層或多層目錄【只能使用 /**/xxx 的方式】
2、支援路徑中的佔位符
SpringMVC路徑中的佔位符常用於RESTful風格中,當請求路徑中將某些資料通過路徑的方式傳輸到伺服器中
就可以在相應的@RequestMapping註解的value屬性中通過佔位符{xxx}表示傳輸的資料
再通過@PathVariable註解,將佔位符所表示的資料賦值給控制器方法的形參
//請求路徑:/testRest/1/admin
@RequestMapping("/testRest/{id}/{username}")
public String testRest(@PathVariable("id")Integer id, @PathVariable("username")String username) {
System.out.println("id = " + id);
System.out.println("username = " + username);
return "success";
}
四、獲取引數
1、通過ServletAPI獲取
前提:將HttpServletRequest作為控制器的形參,就可以從中獲取引數
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request) {
String username = request.getParameter("username");
System.out.println("username = " + username);
return "success";
}
+++
2、通過控制器方法的形參獲取
前提:在控制器方法的形參位置,設定和請求引數同名的形參,可以自動匹配引數和賦值
//請求地址:/testParam?username=admin&hobby=a&hobby=b
@RequestMapping("/testParam")
public String testParam(String username, String[] hobby) {
System.out.println("username = " + username);
System.out.println("hobby = " + Arrays.toString(hobby));
return "success";
}
若請求中有多個同名的請求引數,形參可以設定為字串型別或字串陣列型別
字串型別:使用逗號進行拼接
3、@RequestParam
作用:將請求引數和控制器方法的形參建立對映關係
註解有三個屬性:
❶『value』:指定請求引數中的引數名
❷『required』:設定是否必須傳輸,預設為true
❸『defaultValue』:設定沒有傳入或傳入""時的預設值
@RequestMapping("/testParam")
public String testParam(
@RequestParam(value = "user_name", required = false, defaultValue = "he")
String username) {
System.out.println("username = " + username);
return "success";
}
4、@RequestHeader
作用:將請求頭資訊和控制器方法的形參建立對映關係
@RequestMapping("/testParam")
public String testParam(@RequestHeader(value = "Host") String host) {
System.out.println("host = " + host);
return "success";
}
5、@CookieValue
作用:將cookie資料和控制器方法的形參建立對映關係
@RequestMapping("/testParam")
public String testParam(@CookieValue("JSESSIONID") String JSESSIONID) {
System.out.println("JSESSIONID = " + JSESSIONID);
return "success";
}
6、通過POJO獲取
前提:當瀏覽器傳輸的請求引數的引數名和實體類中的屬性名一致,那麼請求引數就會為此賦值
@RequestMapping("/testBean")
public String testBean(User user) {
System.out.println(user);
return "success";
}
//User{id=null, username='張三', password='123', age=23, sex='男'}
7、解決亂碼問題
Tomcat8中,GET請求的編碼預設為UTF-8
為解決POST請求中亂碼問題,要在web.xml檔案中註冊CharacterEncodingFilter
編碼過濾器一定要配置到其他過濾器之前,否則無效
<!-- 配置springMVC的編碼過濾器 -->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true
</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
五、域物件共享資料
(一)Request域物件
1、使用ServletAPI
@RequestMapping("/testServletAPI")
public String testRequestByServletAPI(HttpServletRequest request) {
request.setAttribute("testRequestScope", "Hello ServletAPI");
return "success";
}
2、使用ModelAndView
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView mav = new ModelAndView();
//共享資料
mav.addObject("testRequestScope", "Hello ModelAndView");
//設定檢視,實現頁面跳轉
mav.setViewName("success");
return mav;
}
3、使用Model
@RequestMapping("/testModel")
public String testModel(Model model) {
model.addAttribute("testRequestScope", "Hello Model");
return "success";
}
4、使用Map
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) {
map.put("testRequestScope", "Hello Map");
return "success";
}
5、使用ModelMap
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap modelMap) {
modelMap.addAttribute("testRequestScope", "Hello ModelMap");
return "success";
}
6、補充
- 以上5種共享資料的方法,返回值最後都被DispatcherServlet封裝成了ModelAndView物件
- Model、ModelMap、Map的關係
(二)Session域物件
@RequestMapping("/testSession")
public String testSession(HttpSession session) {
session.setAttribute("testSessionScope", "Hello Session");
return "success";
}
(三)Application域物件
@RequestMapping("/testApplication")
public String testApplication(HttpSession session) {
ServletContext application = session.getServletContext();
application.setAttribute("testApplicationScope", "Hello Application");
return "success";
}
六、檢視
檢視的作用:渲染資料,將Model中的資料展示給使用者
SpringMVC中的檢視是view檢視
(一)ThymeleafView
當控制器方法所設定的檢視名稱沒有任何字首時,最終會被處理成ThymeleafView,並轉發
DispatcherServlet --> processDispatchResult
--> render
--> resolveViewName
(二)轉發檢視
SpringMVC中預設的轉發檢視:InternalResourceView
當控制器方法所設定的檢視名稱以“ forward: ”為字首時,建立InternalResourceView檢視,此時的檢視名稱不會被解析,而是會將字首去掉,剩餘部分作為最終路徑通過轉發的方式實現跳轉
(三)重定向檢視
SpringMVC中預設的重定向檢視:RedirectView
當控制器中所設定的檢視名稱以“ redirect: ”為字首時,建立RedirectView檢視,此時的檢視名稱不會被解析,而是會將字首去掉,剩餘部分作為最終路徑通過重定向的方式實現跳轉,若剩餘部分以 / 開頭,則會自動拼接上下文路徑
(四)檢視控制器
當控制器方法中,僅僅用來實現頁面跳轉,可以進行如下設定
<!--
path:設定處理的請求地址
view-name:設定請求地址所對應的檢視名稱
-->
<mvc:view-controller path="/" view-name="index"/>
<mvc:annotation-driven/>
注:
當存在以上設定時,其他控制器中的請求對映將全部失效
此時需要在SpringMVC核心配置檔案中設定開啟mvc註解驅動
<mvc:annotation-driven/>
七、RESTful
(一)簡介
REST:Representational State Transfer,表現層資源狀態轉移
(二)實現
通過HTTP協議裡面的四種請求:GET、POST、PUT、DELETE
它們分別對應四種基本操作:GET—獲取資源,POST—新建資源,PUT—更新資源,DELETE—刪除資源
操作 | 傳統方式 | REST風格 |
---|---|---|
查詢 | getUserById?id=1 | user/1,GET |
儲存 | saveUser | user,POST |
刪除 | deleteUser?id=1 | user/1,DELETE |
更新 | updateUser | user,PUT |
(三)HiddenHTTPMethodFilter
通過HiddenHttpMethodFilter過濾器,可以將POST請求轉換為DELETE請求或PUT請求
轉化條件:
❶當前請求的 請求的方式 必須為post
❷設定請求中的 引數『_method』 (=put/delete)
在web.xml檔案中註冊
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
(四)刪除案例
思路:超連結通過繫結點選事件,控制form表單
<a @click="deleteEmployee" th:href="@{|/employee/${employee.id}|}">delete</a>
<form id="deleteForm" method="post">
<input type="hidden" name="_method" value="delete">
</form>
<script type="text/javascript">
var vue = new Vue({
el: "#dataTable",
methods: {
deleteEmployee: function (event) {
var deleteForm = document.getElementById("deleteForm");
deleteForm.action = event.target.href;
//提交表單
deleteForm.submit();
//阻止超連結的跳轉行為
event.preventDefault();
}
}
});
</script>
八、HttpMessageConverter
HttpMessageConverter,報文資訊轉換器
將請求報文轉換為Java物件,或將Java物件轉換為響應報文
(一)@RequestBody
@RequestBody可以獲取請求體
需要在控制器方法設定一個形參,使用註解標識,當前請求的請求體就會對引數自動賦值
@RequestMapping("/testRequestBody")
public String testRequestBody(@RequestBody String requestBody) {
System.out.println(requestBody);
//username=admin&password=123
return "success";
}
(二)RequestEntity
RequestEntity封裝報文的一種型別
需要在控制器方法的形參中設定該型別的形參,當前請求報文就會賦值給該形參
@RequestMapping("/testRequestEntity")
public String testRequestEntity(RequestEntity<String> requestEntity) {
System.out.println("請求頭 = " + requestEntity.getHeaders());
System.out.println("請求體 = " + requestEntity.getBody());
return "success";
}
(三)@ResponseBody
@ResponseBody用於標識一個控制器方法
可以將該方法的返回值直接作為響應報文的響應體響應到瀏覽器
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody() {
return "success";
}
1、處理json
❶匯入依賴
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
❷開啟註解驅動
<mvc:annotation-driven />
❸註解標識控制器
//將java物件直接返回,會自動轉換為json格式的字串
@RequestMapping("/testResponseUser")
@ResponseBody
public User testResponseUser() {
return new User(1001, "admin", "123", 15, "male");
}
2、處理ajax
❶請求超連結
<div id="app">
<a th:href="@{/testAjax}" @click="testAjax">SpringMVC處理ajax</a>
</div>
❷vue和axios處理點選事件
<script type="text/javascript">
var vue = new Vue({
el:"#app",
methods:{
testAjax:function (event) {
axios({
method:"post",
url:event.target.href,
params:{
username:"admin",
password:"12345"
}
}).then(function (response) {
alert(response.data);
});
event.preventDefault();
}
}
});
</script>
❸控制器方法
@RequestMapping("/testAjax")
@ResponseBody
public String testAjax(String username, String password) {
System.out.println("username = " + username);
System.out.println("password = " + password);
return "Hello Ajax";
}
(四)@RestController
@RestController註解是一個複合註解,可以作用在控制器中
作用:相當於給控制器添加了@Controller註解,並且為其中的所有方法添加了@ResponseBod註解
(五)ResponseEntity
用於控制器方法的返回值型別,該方法的返回值就是響應到瀏覽器的響應報文
1、檔案下載
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testDown(HttpSession session) throws IOException {
//獲取ServletContext物件
ServletContext servletContext = session.getServletContext();
//獲取伺服器中檔案的真實路徑
String realPath = servletContext.getRealPath("/static/img/1.png");
//建立輸入流
FileInputStream is = new FileInputStream(realPath);
//建立位元組陣列
byte[] bytes = new byte[is.available()];
//讀取資料到位元組陣列中
is.read(bytes);
//建立HttpHeader物件設定響應頭資訊
MultiValueMap<String, String> headers = new HttpHeaders();
//設定下載方式和檔名字
headers.add("Content-Disposition", "attachment;filename=1.png");
//設定響應狀態碼
HttpStatus statusCode = HttpStatus.OK;
//建立ResponseEntity物件
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
is.close();
return responseEntity;
}
2、檔案上傳
❶新增依賴
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
❷註冊檔案解析器
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
❸頁面表單
<form th:action="@{/testUp}" method="post" enctype="multipart/form-data">
<input type="file" name="photo">
<input type="submit" value="上傳">
</form>
❹控制器方法
@RequestMapping("/testUp")
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//獲取上傳的檔名
String fileName = photo.getOriginalFilename();
//獲取檔案字尾名
String suffixName = fileName.substring(fileName.lastIndexOf("."));
//處理檔案重名問題
fileName = UUID.randomUUID().toString() + suffixName;
//獲取伺服器中photo目錄的路徑
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if (!file.exists()) {
file.mkdir();
}
String finalPath = photoPath + File.separator + fileName;
//實現上傳
photo.transferTo(new File(finalPath));
return "success";
}
九、攔截器
作用:攔截控制器方法的執行
(一)配置
❶建立一個類,實現HandlerInterceptor介面,重寫三個方法
❷在SpringMVC配置檔案中進行配置
<mvc:interceptors>
<!-- 對DispatcherServlet所處理的所有請求進行攔截 -->
<ref bean="firstInterceptor"/>
<bean class="com.atguigu.mvc.interceptors.FirstInterceptor"/>
<!--
mvc:mapping 設定需要攔截的請求
mvc:exclude-mapping 設定不需要攔截的請求
-->
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<ref bean="firstInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
(二)三個抽象方法
❶preHandle
執行時間:控制器執行之前
說明:返回true,放行;返回false,攔截
❷postHandle
執行時間:控制器執行之後
❸afterCompletion
執行時間:渲染檢視完畢之後
(三)執行順序
❶若每個攔截器的preHandle都返回true
preHandle:按照配置的 順序 執行
postHandler:按照配置順序的 反序 執行
afterCompletion:按照配置順序的 反序 執行
❷若某個攔截器(A)的preHandle返回了false
preHandler:攔截器A之前,包括A,都會執行
postHandler:一個都不會執行
afterCompletion:攔截器A之前,不包括A,都會執行
十、異常處理器
SpringMVC提供了一個處理控制器方法執行過程中所出現的異常介面:HandlerExceptionResolver
HandlerExceptionrResolver
介面的實現類有DefaultHandlerExceptionResolver
和SimpleMappingExceptionResolver
SpringMVC提供了自定義的異常處理器SimpleMappingExceptionResolver
(一)基於配置
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!--
property的鍵表示處理的異常
property的值表示出現異常時,跳轉的檢視名稱
-->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!-- 將異常資訊共享在請求域中 -->
<property name="exceptionAttribute" value="ex"/>
</bean>
(二)基於註解
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
public String testException(Exception exception, Model model) {
model.addAttribute("ex", exception);
return "error";
}
}
十一、完全註解配置
使用配置類和註解代替web.xml和SpringMVC配置檔案的功能
(一)代替web.xml
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//指定spring的配置類
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//指定springMVC的配置類
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//指定DispatcherServlet的對映規則,即url-pattern
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//新增過濾器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceResponseEncoding(true);
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
}
}
(二)代替MVC配置檔案
/**
* 代替SpringMVC的配置檔案
* 1、掃描元件 2、檢視解析器 3、view-controller 4、default-servlet-handler
* 5、mvc註解驅動 6、檔案上傳解析器 7、異常處理 8、攔截器
*/
@Configuration
//1、掃描元件
@ComponentScan("com.atguigu.mvc.controller")
//5、mvc註解驅動
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
//3、view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/hello").setViewName("hello");
}
//4、default-servlet-handler
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//6、檔案上傳解析器
@Bean
public CommonsMultipartResolver multipartResolver() {
return new CommonsMultipartResolver();
}
//7、異常處理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties prop = new Properties();
prop.setProperty("java.lang.ArithmeticException", "error");
exceptionResolver.setExceptionMappings(prop);
exceptionResolver.setExceptionAttribute("ex");
resolvers.add(exceptionResolver);
}
//8、攔截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
FirstInterceptor firstInterceptor = new FirstInterceptor();
registry.addInterceptor(firstInterceptor).addPathPatterns("/**");
}
//2、檢視解析器
//2.1、配置生成模板解析器
@Bean
public ITemplateResolver templateResolver() {
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//2.2、生成模板引擎併為模板引擎引入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//2.3、生成檢視解析器併為解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
}
十二、MVC執行流程
(一)常用元件
-
DispatcherServlet:前端控制器(框架提供)
作用:統一處理請求和響應,整個流程控制的中心,由它呼叫其他元件處理使用者請求
-
HandlerMapping:處理器對映器(框架提供)
作用:根據請求的url、method等資訊查詢Handler
-
Handler:處理器
作用:在DispatcherServlet的控制下,對具體的使用者請求進行處理
-
HandlerAdapter:處理器介面卡(框架提供)
作用:對處理器(控制器方法)進行執行
-
ViewResolver:檢視解析器(框架提供)
作用:進行檢視解析,得到相應的檢視,例如ThymeleafView、InternalResourceView、
RedirectView
-
View:檢視
作用:將模型資料通過頁面展示給使用者