javascript
后端学习 - SpringMVC
文章目錄
- 一 SpringMVC 簡介
- 1 MVC
- 2 SpringMVC
- 3 創建第一個 SpringMVC 項目
- 二 @RequestMapping
- 1 注解類與方法的區別
- 2 value 屬性
- 3 method 屬性
- 4 params 屬性
- 5 headers 屬性
- 6 SpringMVC 支持路徑中的占位符
- 三 獲取 Request 的一系列參數
- 1 通過控制器方法的形參
- 2 控制器方法形參 映射 Request 參數 - @RequestParam
- 3 控制器方法形參 映射 Request 請求頭 - @RequestHeader
- 4 控制器方法形參 映射 cookie數據 - @CookieValue
- 5 通過 POJO 獲取 Request 參數
- 6 解決獲取參數的亂碼問題
- 四 域對象共享數據
- 1 使用 ServletAPI 向 request 域對象共享數據(不建議)
- 2 使用 ModelAndView 向 request 域對象共享數據
- 3 使用 Model 向 request 域對象共享數據
- 4 使用 Map 向 request 域對象共享數據
- 5 使用 ModelMap 向 request 域對象共享數據
- 6 使用 ServletAPI 向 Session 域對象共享數據
- 7 使用 ServletAPI 向 Application 域對象共享數據
- 五 SpringMVC 視圖
- 1 Thymeleaf 視圖
- 2 轉發視圖
- 3 重定向視圖
- 4 使用 view-controller 代替 控制器方法
- 六 RESTful
- 七 HttpMessageConverter
- 1 @RequestBody
- 2 RequestEntity
- 3 @ResponseBody
- 4 ResponseEntity
- 5 RestController
- 八 攔截器
- 1 配置方法
- 2 HandlerInterceptor 接口的三個方法
- 3 多個攔截器的執行順序
- 九 異常處理器
- 1 基于配置
- 2 基于注解
- 十 使用注解配置 SpringMVC
- 1 初始化類:代替 web.xml
- 2 SpringConfig 類:代替 Spring 配置文件(略)
- 3 WebConfig 類:代替 SpringMVC 配置文件
- 十一 SpringMVC 執行流程
- 1 常用組件
- 2 流程總結
一 SpringMVC 簡介
1 MVC
- Model 模型層:工程中的 JavaBean,包含實體 Bean(Customer、Student…) 和 業務處理 Bean(Service、DAO)
- View 視圖層:指工程中的 html 或 jsp 等頁面,與用戶進行交互,展示數據
- Controller 控制層:指工程中的 servlet,作用是接收請求和響應瀏覽器
- MVC 的工作流程 View <—> Controller <—> Model :用戶通過視圖層發送請求到服務器,在服務器中請求被Controller接收,Controller 調用相應的 Model 層處理請求,處理完畢將結果返回到 Controller,Controller 再根據請求處理的結果找到相應的 View 視圖,渲染數據后最終響應給瀏覽器
2 SpringMVC
- 是 Spring 的子項目
- 主要作用是在 Spring 項目中進行表述層開發(是三層架構中的概念,三層架構:表述層(或表示層)、業務邏輯層、數據訪問層,表述層表示前臺頁面和后臺 servlet)
3 創建第一個 SpringMVC 項目
目錄結構如下
總結:
- 瀏覽器發送請求,若請求地址符合前端控制器的url-pattern,該請求就會被前端控制器 DispatcherServlet 處理
- 前端控制器會讀取 SpringMVC 的核心配置文件,通過掃描組件找到控制器,將請求地址和控制器中@RequestMapping 注解的 value 屬性值進行匹配(要求每個方法的 value 值唯一)
- 若匹配成功,該注解所標識的控制器方法就是處理請求的方法,處理請求的方法需要返回一個字符串類型的視圖名稱
- 該視圖名稱會被視圖解析器解析,加上前綴和后綴組成視圖的路徑,通過 Thymeleaf 對視圖進行渲染,最終轉發到視圖所對應頁面
二 @RequestMapping
作用是關聯 請求 和 處理請求的控制器方法。SpringMVC 接收到指定的請求,就會來找到在映射關系中對應的控制器方法來處理這個請求。
1 注解類與方法的區別
- @RequestMapping標識一個類:設置映射請求的請求路徑的初始信息
- @RequestMapping標識一個方法:設置映射請求請求路徑的具體信息
2 value 屬性
- 通過請求的請求地址匹配請求映射
- 是一個字符串類型的數組,和其中任意字符串匹配則選擇該方法,滿足其中一個即可
- @RequestMapping 必須設置的屬性
3 method 屬性
- 根據請求方法 GET / POST / PUT / DELETE匹配請求映射
- 默認任意請求方式均可匹配
- 是RequestMethod 枚舉類型的數組,表示該請求映射能夠匹配多種請求方式的請求,滿足其中一個即可
- @RequestMapping(value="/idx", method={RequestMethod.GET}) 等于 @GetMapping(value="/idx"),其它方式同理
- 如果 value 匹配而 method 不匹配,出現405錯誤
4 params 屬性
- 根據請求攜帶的的參數匹配請求映射
- 是一個字符串類型的數組,需要同時滿足所有條件,可以通過四種表達式設置請求參數和請求映射的匹配關系:
“param”:要求請求映射所匹配的請求必須攜帶 param 請求參數
“!param”:要求請求映射所匹配的請求必須不能攜帶 param 請求參數
“param=value”:要求請求映射所匹配的請求必須攜帶 param 請求參數且 param=value
“param!=value”:要求請求映射所匹配的請求必須攜帶 param 請求參數但 param!=value
5 headers 屬性
- 根據請求的請求頭信息匹配請求映射
- 類似 params 屬性,是一個字符串類型的數組,需要同時滿足所有條件,可以通過四種表達式設置請求參數和請求映射的匹配關系:
“header”:要求請求映射所匹配的請求必須攜帶 header 請求頭信息
“!header”:要求請求映射所匹配的請求必須不能攜帶 header 請求頭信息
“header=value”:要求請求映射所匹配的請求必須攜帶 header 請求頭信息且 header=value
“header!=value”:要求請求映射所匹配的請求必須攜帶 header 請求頭信息且 header!=value
6 SpringMVC 支持路徑中的占位符
- 將請求攜帶的參數以請求路徑的形式,向服務器傳遞參數
- 如果 @RequestMapping 的 value 屬性中有路徑的占位符,則請求時必須有占位符對應的參數,否則出現404
三 獲取 Request 的一系列參數
1 通過控制器方法的形參
- 將形參名和 Request 參數名對應即可(如果不同名,則需要使用 @RequestParam),如此只能獲取 Request 參數,而不能獲得請求頭信息等
- 如果有多個同名的參數,則將形參類型設置為字符串數組
2 控制器方法形參 映射 Request 參數 - @RequestParam
- value:Request 中的參數的 name 屬性
- required:標明該參數是否必須,如果是必須且未設置 defaultValue,則必須由 Request 傳入
- defaultValue:默認值
3 控制器方法形參 映射 Request 請求頭 - @RequestHeader
- 同樣具有 value, required, defaultValue,用法相同
4 控制器方法形參 映射 cookie數據 - @CookieValue
- 同樣具有 value, required, defaultValue,用法相同
5 通過 POJO 獲取 Request 參數
將控制器方法形參設置為實體類類型,此時若瀏覽器傳輸的請求參數的參數名,和實體類中的屬性名一致,那么請求參數就會為此屬性賦值
<form th:action="@{/testpojo}" method="post">用戶名:<input type="text" name="username"><br>密碼:<input type="password" name="password"><br>性別:<input type="radio" name="sex" value="男">男<input type="radio"name="sex" value="女">女<br>年齡:<input type="text" name="age"><br>郵箱:<input type="text" name="email"><br><input type="submit"> </form> @RequestMapping("/testpojo") public String testPOJO(User user){ // 根據request參數創建對象,前提是屬性名和請求參數名相同System.out.println(user); return "success"; }6 解決獲取參數的亂碼問題
- GET 請求的亂碼問題可以通過更改 Tomcat 的配置文件 server.xml 解決
- POST 請求的亂碼問題必須在請求參數獲取之前設置編碼,要比 Servlet 啟動更早
- 服務器啟動時,初始化順序是 Listener -> Filter -> Servlet,可以使用 Filter 設置編碼格式(不使用 Listener 是因為監聽器只執行一次,負責初始化 / 銷毀的動作,而 Filter 可以過濾所有符合路徑請求),在 web.xml 中配置,并設置為首個 Filter
四 域對象共享數據
域對象按范圍從小到大分為:Request、Session、Application(ServletContext)
1 使用 ServletAPI 向 request 域對象共享數據(不建議)
@Controller public class TestController {@RequestMapping("/servlet")public String m1(HttpServletRequest httpServletRequest) {httpServletRequest.setAttribute("k", "v");return "index";} } index.html: <p th:text="${k}"></p>2 使用 ModelAndView 向 request 域對象共享數據
- 向 request 域對象共享數據的所有方式,本質是對使用 ModelAndView 進行共享的一種封裝
- 方法的返回值必須是 ModelAndView 類型
3 使用 Model 向 request 域對象共享數據
- 類似于 ServletAPI
4 使用 Map 向 request 域對象共享數據
@Controller public class TestController {@RequestMapping("/map")public String m4(Map<String, Object> map) {map.put("k", "v");return "index";} }5 使用 ModelMap 向 request 域對象共享數據
- 類似于 ServletAPI
6 使用 ServletAPI 向 Session 域對象共享數據
@RequestMapping("/testSession") public String testSession(HttpSession session){session.setAttribute("testSessionScope", "hello,session");return "index"; }7 使用 ServletAPI 向 Application 域對象共享數據
@RequestMapping("/testApplication") public String testApplication(HttpSession session){ServletContext application = session.getServletContext();application.setAttribute("testApplicationScope", "hello,application");return "index"; }五 SpringMVC 視圖
- 默認的有:轉發視圖、重定向視圖
1 Thymeleaf 視圖
- 實現了轉發視圖的功能
- 當控制器方法中所設置的視圖名稱沒有任何前綴時,此時的視圖名稱會被 SpringMVC 配置文件中所配置的視圖解析器解析,視圖名稱拼接視圖前綴和視圖后綴所得到的最終路徑,會通過轉發的方式實現跳轉
Spring 配置文件中的視圖解析器:
<!-- 配置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="/templates/"/><property name="suffix" value=".html"/><property name="templateMode" value="HTML5"/><property name="characterEncoding" value="UTF-8" /></bean></property></bean></property></bean>2 轉發視圖
- SpringMVC中默認的轉發視圖是 InternalResourceView
- 當控制器方法中所設置的視圖名稱以"forward:"為前綴時,創建 InternalResourceView 視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴"forward:"去掉,剩余部分作為最終路徑通過轉發的方式實現跳轉
3 重定向視圖
- SpringMVC 中默認的重定向視圖是 RedirectView
- 當控制器方法中所設置的視圖名稱以"redirect:"為前綴時,創建 RedirectView 視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴"redirect:"去掉,剩余部分作為最終路徑通過重定向的方式實現跳轉
- 重定向視圖在解析時,會先將 redirect: 前綴去掉,然后會判斷剩余部分是否以 / 開頭,若是,則自動拼接上下文路徑
4 使用 view-controller 代替 控制器方法
- 當控制器方法中,僅僅用來實現頁面跳轉,即只需要設置視圖名稱時,可以將處理器方法用 view-controller 標簽表示
- 當SpringMVC 中設置任何一個 view-controller 時,其他控制器中的請求映射將全部失效,可以使用標簽<mvc:annotation-driven />開啟
六 RESTful
- Representational State Transfer,表現層資源狀態轉移
- REST 風格提倡 URL 地址使用統一的風格設計,從前到后各個單詞使用斜杠分開,不使用問號鍵值對方式攜帶請求參數,而是將要發送給服務器的數據作為 URL 地址的一部分,以保證整體風格的一致性
- 對于 HTTP 的四種請求:
| HTTP 請求 | RESTful | |
| 插入 | POST | /user(請求為 POST) |
| 刪除 | DELETE | /user/id(請求為 DELETE) |
| 更新 | PUT | /user(請求為 PUT) |
| 查詢 | GET | /user/id(請求為 GET) |
- SpringMVC 中提供了兩個過濾器:CharacterEncodingFilter 和 HiddenHttpMethodFilter
- 使用 HiddenHttpMethodFilter 模擬 DELETE 和 PUT
- 在 web.xml 中注冊時,必須先注冊 CharacterEncodingFilter,再注冊 HiddenHttpMethodFilter,因為CharacterEncodingFilter要求前面不能有任何獲取請求參數的操作,而 CharacterEncodingFilter 獲取了 request 參數
七 HttpMessageConverter
- 報文信息轉換器,將 請求報文 轉換為Java對象,或將Java對象轉換為 響應報文
- HttpMessageConverter提供了兩個注解和兩個類型:@RequestBody,@ResponseBody,RequestEntity,ResponseEntity
1 @RequestBody
- @RequestBody 可以獲取請求體(僅僅是請求體而非整個 HTTP 報文,POST 具有請求體,而 GET 不具有)
- 需要在控制器方法設置一個形參,使用 @RequestBody 進行標識,當前請求的請求體就會為當前注解所標識的形參賦值
- 可以將前端傳來的 json 轉為對象
2 RequestEntity
- RequestEntity 封裝 HTTP 請求報文,需要在控制器方法的形參中的 泛型位置 設置要將報文轉換的目標類型,當前請求的請求報文就會賦值給該形參
- 通過 getHeaders() 獲取請求頭信息,通過 getBody() 獲取請求體信息
3 @ResponseBody
- @ResponseBody 用于標識一個 控制器方法,可以將該方法的 返回值 直接作為響應報文的 響應體 響應到瀏覽器
- 如果需要以 json 格式,打印 Java對象的響應體,需要導入 jackson 依賴并開啟 mvc 注解驅動
4 ResponseEntity
- 用于控制器方法的返回值類型,該控制器方法的返回值就是響應到瀏覽器的響應報文
- 可以實現文件下載的功能
5 RestController
- 復合注解,標識控制器類,就相當于為類添加了 @Controller 注解,并且為其中的每個方法添加了 @ResponseBody 注解
八 攔截器
- 攔截的是控制器方法執行
- 和過濾器 filter 的主要區別是,filter 作用于瀏覽器到 Servlet 的過程中,而攔截器作用于 Controller 執行前(Servlet 到 Controller 的過程中),以及 Controller 返回后 的過程中
1 配置方法
在 SpringMVC 配置文件中:
<!-- 前兩種對DispatcherServlet所處理的*所有的請求*進行攔截 --><mvc:interceptors><!--方式一:--><bean class="interceptor.MyInterceptor"></bean><!--方式二:--><ref bean="myInterceptor"></ref><!--方式三:可以自定義攔截路徑--><!--可以通過ref或bean標簽設置攔截器,通過mvc:mapping設置需要攔截的請求,通過mvc:exclude-mapping設置需要排除的請求,即不需要攔截的請求--><mvc:interceptor><mvc:mapping path="/**"/><mvc:exclude-mapping path="/testRequestEntity"/><ref bean="myInterceptor"></ref></mvc:interceptor></mvc:interceptors>攔截器類:
@Component public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("pre");return true; // 返回 true 放行}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("post");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("after");} }2 HandlerInterceptor 接口的三個方法
- preHandle:返回值為 bool 類型,返回 true 放行,false 攔截
- postHandle:控制器方法執行之后執行
- afterComplation:渲染視圖完畢之后執行
3 多個攔截器的執行順序
- 如果所有攔截器的 preHandle() 都返回 true,則 preHandle() 按照配置的順序執行,postHandle() 和 afterComplation() 按照配置的反序執行
- 如果某個攔截器的 preHandle() 返回 false,preHandle() 返回 false 的攔截器和它之前的攔截器的 preHandle() 都會執行,postHandle() 都不執行,返回 false 的攔截器之前的攔截器的 afterComplation() 會倒序執行
- 下圖是所有攔截器的 preHandle() 都返回 true 的情況,如果攔截器3返回 false,則方法的執行順序是: 1.prehandle->2.prehandle->3.prehandle->2.afterCompletion->1.afterCompletion
九 異常處理器
1 基于配置
在 SpringMVC 的核心配置文件中:
出現異常后,跳轉到 error.html 訪問異常信息:
<body><p th:text="${info_key}"></p> </body>2 基于注解
- 使用 @ControllerAdvice 注解異常處理類
- 使用 @ExceptionHandler(異常類的class對象) 注解異常處理方法
十 使用注解配置 SpringMVC
- 目的是使用配置類和注解代替 web.xml 和 SpringMVC 配置文件的功能
1 初始化類:代替 web.xml
- 繼承自 AbstractAnnotationConfigDispatcherServletInitializer
2 SpringConfig 類:代替 Spring 配置文件(略)
@Configuration public class MySpringConfig {// ... }3 WebConfig 類:代替 SpringMVC 配置文件
- @Bean 的作用是,將方法返回值(Java 對象)交給 IOC 容器
十一 SpringMVC 執行流程
1 常用組件
-
DispatcherServlet:前端控制器,不需要工程師開發,由框架提供
作用:統一處理請求和響應,整個流程控制的中心,由它調用其它組件處理用戶的請求 -
HandlerMapping:處理器映射器,不需要工程師開發,由框架提供
作用:根據請求的url、method等信息查找Handler,即控制器方法 -
Handler:處理器
作用:在DispatcherServlet的控制下Handler對具體的用戶請求進行處理 -
HandlerAdapter:處理器適配器,不需要工程師開發,由框架提供
作用:通過HandlerAdapter對處理器(控制器方法)進行執行 -
ViewResolver:視圖解析器,不需要工程師開發,由框架提供
作用:進行視圖解析,得到相應的視圖,例如:ThymeleafView、InternalResourceView、RedirectView -
View:視圖
作用:將模型數據通過頁面展示給用戶
2 流程總結
(1) 可以匹配,則交給具體的 Servlet,前往步驟3
(2) 不能匹配,如果配置了 mvc:default-servlet-handler ,訪問目標資源(一般為靜態資源,如:JS, CSS, HTML),找不到展示404錯誤
(3) 不能匹配,沒有配置 mvc:default-servlet-handler,展示404錯誤
(1) HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息
(2) 數據格式化、數據驗證…
總結
以上是生活随笔為你收集整理的后端学习 - SpringMVC的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后端学习 - JavaWeb
- 下一篇: 后端学习 - SpringBoot