Springmvc 簡介(03)
Springmvc 簡介(03)
10.Result風格
10.1 Result風格介紹
Restful 一種軟體架構風格、設計風格,而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端和伺服器互動類的軟體。基於這個風格設計的軟體可以更簡潔,更有層次,更易於實現快取等機制。
REST(英文:Representational State Transfer,簡稱REST)描述了一個架構樣式的網路系統,比如 web 應用程式。它首次出現在 2000 年 Roy Fielding 的博士論文中,他是 HTTP 規範的主要編寫者之一。在目前主流的三種Web服務互動方案中,REST相比於SOAP(Simple Object Access protocol,簡單物件訪問協議)以及XML-RPC更加簡單明瞭,無論是對URL的處理還是對Payload的編碼,REST都傾向於用更加簡單輕量的方法設計和實現。值得注意的是REST並沒有一個明確的標準,而更像是一種設計的風格。
原則條件
REST 指的是一組架構約束條件和原則。滿足這些約束條件和原則的應用程式或設計就是 RESTful。
Web 應用程式最重要的 REST 原則是,客戶端和伺服器之間的互動在請求之間是無狀態的。從客戶端到伺服器的每個請求都必須包含理解請求所必需的資訊。如果伺服器在請求之間的任何時間點重啟,客戶端不會得到通知。此外,無狀態請求可以由任何可用伺服器回答,這十分適合雲端計算之類的環境。客戶端可以快取資料以改進效能。
在伺服器端,應用程式狀態和功能可以分為各種資源。資源是一個有趣的概念實體,它向客戶端公開。資源的例子有:應用程式物件、資料庫記錄、演算法等等。每個資源都使用 URI (Universal Resource Identifier) 得到一個唯一的地址。所有資源都共享統一的介面,以便在客戶端和伺服器之間傳輸狀態。使用的是標準的 HTTP 方法,比如 GET、PUT、
POST 和 DELETE。Hypermedia 是應用程式狀態的引擎,資源表示通過超連結互聯。1、把請求引數加入到請求的資源地址中
2、原來的增,刪,改,查。使用HTTP請求方式,POST、DELETE、PUT、GET分別一一對應。
10.2 如何學習Result風格 . 這裡面明確兩點 :
10.2.1、就是把傳統的請求引數加入到請求地址是什麼樣子?
傳統的方式是:
比如:http://ip:port/工程名/資源名?請求引數
舉例:http://127.0.0.1:8080/springmvc/book?action=delete&id=1
restful風格是:
比如:http://ip:port/工程名/資源名/請求引數/請求引數
舉例:http://127.0.0.1:8080/springmvc/book/1
請求的動作刪除由請求方式delete決定
10.2.2、restful風格中請求方式GET、POST、PUT、DELETE分別表示查、增、改、刪。
GET請求 對應 查詢
http://ip:port/工程名/book/1 HTTP請求GET 表示要查詢id為1的圖書
http://ip:port/工程名/book HTTP請求GET 表示查詢全部的圖書
POST請求 對應 新增
http://ip:port/工程名/book HTTP請求POST 表示要新增一個圖書
PUT請求 對應 修改
http://ip:port/工程名/book/1 HTTP請求PUT 表示要修改id為1的圖書資訊
DELETE請求 對應 刪除
http://ip:port/工程名/book/1 HTTP請求DELETE 表示要刪除id為1的圖書資訊
10.2.3、SpringMVC中如何傳送GET請求、POST請求、PUT請求、DELETE請求。
我們知道發起GET請求和POST請求,只需要在表單的form標籤中,設定method=”get” 就是GET請求。
設定form標籤的method=”post”。就會發起POST請求。而PUT請求和DELETE請求。要如何發起呢。
1 .要先有post請求的form表單
2 在form表單中, 新增一個額外的隱藏域_method="PUT"或__method=“DELETE”
3 在web.xml中配置一個Filter過濾器1、org.springframework.web.filter.HiddenHttpMethodFilter(****注意,這個Filter一定要在處理亂碼的Filter後面****)
10.3、Restful風格的crud如何實現
表單:
<%@ page contentType="text/html;charset=UTF-8" language="java" isErrorPage="true" %>
<html>
<head>
<title>來了老弟</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/book/{10}/{abc}">查詢圖書為1圖書資訊</a> <br>
<a href="${pageContext.request.contextPath}/book">查詢所有圖書資訊</a>
<form action="${pageContext.request.contextPath}/book" method="post">
<input type="submit" value="新增圖書">
</form>
<%--
1 先有一個post表單
2 在表單中有一個隱藏域,name值是:_method,value是:PUT( put請求,值是put,delete請求,值是DELETE )
3 在伺服器中,配置一個支援restful風格請求的Filter( 將請求引數_method=put改為put請求 )
--%>
<form action="${pageContext.request.contextPath}/book/3" method="post">
<input type="hidden" name="_method" value="PUT">
<input type="submit" value="修改圖書">
</form>
<form action="${pageContext.request.contextPath}/book/4" method="post">
<input type="hidden" name="_method" value="DELETE">
<input type="submit" value="刪除圖書">
</form>
</body>
</html>
BookController程式碼 :
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class BookController {
@RequestMapping(value = "/book/{id}/{abc}",method = RequestMethod.GET)
public String queryBookById(@PathVariable("id") Integer id,
@PathVariable("abc") String abc){
System.out.println(" 查詢id為"+ id +"的圖書資訊 ");
System.out.println("abc的引數是 " + abc);
return "success";
}
@RequestMapping(value = "/book",method = RequestMethod.GET)
public String queryBook(){
System.out.println(" 查詢所有圖書資訊 ");
return "success";
}
@RequestMapping(value = "/book",method = RequestMethod.POST)
public String addBook(){
System.out.println(" 新增圖書資訊 ");
return "success";
}
@RequestMapping(value = "/book/3",method = RequestMethod.PUT)
public String updateBook(){
System.out.println(" 修改圖書資訊 ");
return "success";
}
@RequestMapping(value = "/book/4",method = RequestMethod.DELETE)
public String delBook(){
System.out.println(" 刪除圖書資訊 ");
return "success";
}
}
web.xml中的配置 :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置支援resultful風格請求的過濾器 -->
<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>
</web-app>
10.4、Restful風格在高版本Tomcat中無法轉發到jsp頁面
在Tomcat8之後的一些高版本,使用restful風格訪問然後轉發到jsp頁面。就會有如下的錯誤提示:
第一種解決方案: 換回低版本的Tomcat(影響效能)
第二種解決方案:isErrorPage="true
10.5、@PathVariable路徑引數獲取
前面我們已經知道如何編寫和配置restful風格的請求和控制器。
那麼 現在的問題是。如何接收restful風格請求的引數。比如前面的id值。
/**
* value = "/book/{id}"在請求地址中,{引數名} 這個引數叫路徑引數 <br/>
* @PathVariable("id") 註解作用是把指定名稱的路徑引數值賦給方法引數id
*/
@Controller
public class BookController {
@RequestMapping(value = "/book/{id}/{abc}",method = RequestMethod.GET)
public String queryBookById(@PathVariable("id") Integer id,
@PathVariable("abc") String abc){
System.out.println(" 查詢id為"+ id +"的圖書資訊 ");
System.out.println("abc的引數是 " + abc);
return "success";
}
}
12、檔案上傳
檔案上傳在SpringMVC中如何實現:
*準備工作前端控制器 , SpringMVC兩個標配*
1、準備一個檔案上傳的表單
2、匯入檔案上傳需要的jar包
commons-fileupload-1.2.1.jar、commons-io-1.4.jar
3、配置檔案上傳解析器 CommonsMultipartResolver
4、配置Controller控制器的程式碼
12.1、準備一個檔案上傳的表單
<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
使用者名稱 : <input type="text" name="username"> <br>
頭像 : <input type="file" name="photo"> <br>
<input type="submit" name="send">
</form>
12.2、匯入檔案上傳需要的jar包
commons-fileupload-1.2.1.jar
commons-io-1.4.jar
spring-aop-5.2.5.RELEASE.jar
spring-beans-5.2.5.RELEASE.jar
spring-context-5.2.5.RELEASE.jar
spring-core-5.2.5.RELEASE.jar
spring-expression-5.2.5.RELEASE.jar
spring-jcl-5.2.5.RELEASE.jar
spring-web-5.2.5.RELEASE.jar
spring-webmvc-5.2.5.RELEASE.jar
12.3、配置檔案上傳解析器
12.4、編寫檔案上傳的Controller控制器中的程式碼:
application 配置 :
<?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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置包掃描 -->
<context:component-scan base-package="com.atguigu"/>
<!-- 配置檢視解析器 -->
<bean id="resourceViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置檔案上傳解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 防止中文亂碼 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<!-- 解決SpringMVC無法支援靜態資源請求的方法: -->
<!-- 配置支援靜態jsp程式碼 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- 配置支援springmvc註解的高階功能 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
web.xml 配置 :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定Springmvc的位置 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!-- 載入因子 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
controller 程式碼 :
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@Controller
public class LastController {
@RequestMapping("/upload")
public String fileupload(
@RequestParam("username") String username,
@RequestParam("photo") MultipartFile multipartFile){
// 上傳的使用者名稱
System.out.println("username ==>" + username);
try {
// 上傳的檔名
String filename = multipartFile.getOriginalFilename();
// 上傳檔案儲存
multipartFile.transferTo(new File("D:/java_class/java_linux_class" + filename));
} catch (IOException e) {
e.printStackTrace();
}
return "success";
}
@RequestMapping("/download")
public ResponseEntity<byte[]> download(HttpSession session) throws IOException {
String fileName = "4.jpg";
// 獲取上下文引數
ServletContext servletContext = session.getServletContext();
// 讀取指定路徑的檔案,以流的形式返回<br/>
InputStream resourceAsStream = servletContext.getResourceAsStream("/file/" + fileName);
// toByteArray()讀取輸入流中所有資料,轉換為byte[]陣列返回
byte[] body = IOUtils.toByteArray(resourceAsStream);
//在響應頭中,我們需要設定兩個內容,分別是返回的資料型別MIME,設定響應頭讓瀏覽器知道收到資料用於下載<br/>
HttpHeaders headers = new HttpHeaders();
//獲取下載的檔案型別
String mimeType = servletContext.getMimeType("/file/" + fileName);
// 設定返回的資料型別
headers.add("Content-Type",mimeType);
// 設定收到的資料型別
headers.add("Content-Disposition","attachment;fileName=" +fileName);
// public ResponseEntity(@Nullable T body, @Nullable MultiValueMap<String, String> headers, HttpStatus status) {
// 1 建立一個ResponseEntity
/**
* 第一個引數是相應體
* 第二個引數是相應頭
* 第三個引數是相應狀態碼
*/
ResponseEntity responseEntity = new ResponseEntity<>(body,headers, HttpStatus.OK);
return responseEntity;
}
}
遇到的bug : NullPointException 空指標異常
原因 : 複製到專案路徑的照片以及檔案,jdk沒有及時的載入到專案路徑下 ,
13、HandlerInterceptor攔截器
13.1、HandlerInterceptor攔截器的介紹
SpringMVC中的攔截器,跟JavaWeb的Filter過濾器都非常接近。
都可以攔截資源的請求,呼叫。
SpringMVC中的攔截器,使用步驟:
1 編寫一個類去實現介面
2 實現其中的方法
3 到springmvc中的配置檔案中去配置
13.2、單個HandlerInterceptor攔截器的示例
1、編寫一個類去實現HandlerInterceptor介面
2、到Spring的容器配置檔案中去配置攔截器,讓SpringMVC知道都攔截哪些目標方法
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.Map;
@Controller
public class HelloController {
@RequestMapping(value = "/hello")
public String hello(Map<String ,String> map){
map.put("laoxu","world");
System.out.println(" 這是hello下的controller ");
return "success";
}
}
FirstHandlerInterceptor 程式碼 :
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstHandlerInterceptor implements HandlerInterceptor {
/**
* preHandle() 目標方法之前執行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("FirstHandlerInterceptor preHandle");
/**
* 返回值決定是否放行==目標資源
* 返回true 表示可以訪問目標資源
* 返回false表示不允許訪問目標資源
*/
return true;
}
/**
* postHandle() 目標方法之後執行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("FirstHandlerInterceptor postHandle");
}
/**
* afterCompletion() 在頁面渲染完成之後
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("FirstHandlerInterceptor afterCompletion");
}
}
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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置包掃描 -->
<context:component-scan base-package="com.atguigu"/>
<!-- 配置檢視解析器 -->
<bean id="resourceViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:interceptors>
<!-- bean 標籤表示當前攔截器攔截所有請求 -->
<!-- <bean class="com.atguigu.Interceptor.FirstHandlerInterceptor"/>-->
<mvc:interceptor>
<!-- 配置攔截器路徑 -->
<mvc:mapping path="/hello"/>
<!-- 配置攔截器類 -->
<bean class="com.atguigu.Interceptor.FirstHandlerInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<!-- 配置檔案上傳解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 防止中文亂碼 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<!-- 解決SpringMVC無法支援靜態資源請求的方法: -->
<!-- 配置支援靜態jsp程式碼 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- 配置支援springmvc註解的高階功能 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
SpringMVC攔截器和JavaWeb過濾器的不同:(面試題)
Filter 過濾器 :
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@WebFilter(value = "/*")
public class FilterTest implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println(" Filter前置 ");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println(" Filter後置 ");
}
@Override
public void destroy() {
}
}
SpringMVC攔截器和JavaWeb過濾器的不同:
過濾器優先於攔截器
攔截器是基於java的反射機制,過濾器是基於函式回撥,
攔截器不依賴與servlet容器 ,過濾器依賴與servlet容器
13.3、單個攔截器異常時的執行順序
一:目標方法前返回false的情況:
1、目標方法前執行 返回false
2、這是目標方法 不執行
3、目標方法之後 不執行
4、這是渲染頁面 不執行
5、頁面渲染完成! 不執行
二:目標方法前返回true的情況,目標方法異常
1、目標方法前執行 返回true
2、這是目標方法 異常
3、目標方法之後 不執行
4、這是渲染頁面 渲染異常頁面
5、頁面渲染完成! 執行
三:目標方法前返回true的情況,目標方法後異常
1、目標方法前執行 返回true
2、這是目標方法 執行
3、目標方法之後 異常
4、這是渲染頁面 渲染異常頁面
5、頁面渲染完成! 執行
四:目標方法前返回true的情況,渲染頁面異常
1、目標方法前執行 返回true
2、這是目標方法 執行
3、目標方法之後 執行
4、這是渲染頁面 異常
5、頁面渲染完成! 執行
多個攔截器的執行介紹:
FirstHandlerInterceptor 程式碼:
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FirstHandlerInterceptor implements HandlerInterceptor {
/**
* preHandle() 目標方法之前執行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("FirstHandlerInterceptor preHandle");
/**
* 返回值決定是否放行==目標資源
* 返回true 表示可以訪問目標資源
* 返回false表示不允許訪問目標資源
*/
return true;
}
/**
* postHandle() 目標方法之後執行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("FirstHandlerInterceptor postHandle");
}
/**
* afterCompletion() 在頁面渲染完成之後
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("FirstHandlerInterceptor afterCompletion");
}
}
SecondHandlerInterceptor 程式碼:
package com.atguigu.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SecondHandlerInterceptor implements HandlerInterceptor {
/**
* preHandle() 目標方法之前執行
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("SecondHandlerInterceptor preHandle");
/**
* 返回值決定是否放行==目標資源
* 返回true 表示可以訪問目標資源
* 返回false表示不允許訪問目標資源
*/
return true;
}
/**
* postHandle() 目標方法之後執行
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("SecondHandlerInterceptor postHandle");
}
/**
* afterCompletion() 在頁面渲染完成之後
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("SecondHandlerInterceptor afterCompletion");
}
}
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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置包掃描 -->
<context:component-scan base-package="com.atguigu"/>
<!-- 配置檢視解析器 -->
<bean id="resourceViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<mvc:interceptors>
<!-- bean 標籤表示當前攔截器攔截所有請求 -->
<!-- <bean class="com.atguigu.Interceptor.FirstHandlerInterceptor"/>-->
<mvc:interceptor>
<!-- 配置攔截器路徑 -->
<mvc:mapping path="/hello"/>
<!-- 配置攔截器類 -->
<bean class="com.atguigu.Interceptor.FirstHandlerInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<!-- 配置攔截器路徑 -->
<mvc:mapping path="/hello"/>
<!-- 配置攔截器類 -->
<bean class="com.atguigu.Interceptor.SecondHandlerInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<!-- 配置檔案上傳解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 防止中文亂碼 -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<!-- 解決SpringMVC無法支援靜態資源請求的方法: -->
<!-- 配置支援靜態jsp程式碼 -->
<mvc:default-servlet-handler></mvc:default-servlet-handler>
<!-- 配置支援springmvc註解的高階功能 -->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
SpringMVC 攔截器執行原始碼解析:
1、執行doDispatcher做請求分發處理
1.1、呼叫getHandler() 獲取請求處理器 Controller控制器中包含請求的方法 和 攔截器資訊
getHandlerInternal() 根據請求地址獲取對應的請求方法反射物件
getHandlerExecutionChain() 獲取請求地址對應的所有攔截器資訊
1.2、呼叫getHandlerAdapter() 獲取用於執行Handler的介面卡物件
1.3、mappedHandler.applyPreHandle(processedRequest, response) 執行所有攔截器 preHandle()方法
1.4、呼叫ha.handle(); 呼叫Controller目標方法,並將結果封裝成為ModelAndView返回
1.5、mappedHandler.applyPostHandle() 執行所有攔截器的postHandler()後置方法
1.6、processDispatchResult(); 處理結果,渲染頁面
1.7、mappedHandler.triggerAfterCompletion(); 執行攔截器 渲染完成方法
檢視原始碼解析:
什麼是檢視?
SpringMVC為了讓整個程式的程式碼有更好的封裝性,把最後程式執行完給使用者的結果,封裝成為一個View介面。這個介面就叫檢視
檢視就是程式執行完之後使用者收到的結果。
渲染檢視是啥?
執行使用者收到的結果的程式碼。就叫渲染。
執行頁面的程式碼(大多數情況下,是請求轉發,重定向。)
View 檢視
獲取檢視的型別
String getContentType();
渲染檢視頁面
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
AbstractView 抽象類實現
具體實現頁面的渲染
protected abstract void renderMergedOutputModel(
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception;
把隱含模型中的資料,同步到Reqeust域中
*protected* *void* exposeModelAsRequestAttributes(Map<String, Object> model, HttpServletRequest request)
ViewResolver 檢視解析器
根據給定的檢視名解析得到相應的檢視View物件
View resolveViewName(String viewName, Locale locale) throws Exception;