日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

后端学习 - SpringMVC

發布時間:2023/12/4 javascript 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 后端学习 - 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 項目

目錄結構如下

  • 配置 maven 依賴,這里遇到了一個奇怪的版本問題
  • <dependencies><!-- SpringMVC --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.9</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.11.RELEASE</version></dependency></dependencies>
  • 配置 web.xml 的 Servlet 及 mapping
  • <!--注冊springMVC的前端控制器,對瀏覽器所發送的請求統一進行處理在此配置下,springMVC的配置文件具有默認的位置和名稱默認的位置:WEB-INF默認的名稱:<servlet-name>-servlet.xml若要為springMVC的配置文件設置自定義的位置和名稱(推薦)需要在servlet標簽中添加init-param<init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springMVC.xml</param-value></init-param>--><servlet><servlet-name>springMVC</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> <!--對應resources目錄下的文件--></init-param><load-on-startup>1</load-on-startup> <!--服務器啟動時初始化DispatcherServlet--></servlet><servlet-mapping><servlet-name>springMVC</servlet-name><url-pattern>/</url-pattern></servlet-mapping>
  • 在 resources 目錄下,配置 SpringMVC 的 xml:開啟組件掃描、加入 thymeleaf 的名稱空間并配置視圖解析器(Thymeleaf 是服務器端的模板引擎,在服務器端獲取模板和數據,生成結果輸出給瀏覽器呈現結果)
  • <?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.atguigu.mvc.controller"></context:component-scan><!-- 配置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> </beans>
  • 定義 Controller 類,并用注解標注類和方法;在 templates 中定義 index.html, target.html
  • @Controller public class HelloController {/* 通過@RequestMapping注解,可以通過請求路徑匹配要處理的具體的請求/表示的當前工程的上下文路徑 http://localhost:8080/project_context/返回字符串即可,thymeleaf自動為返回值配置前后綴方法名可以隨意,根據注解進行解析*/@RequestMapping("/")public String index(){return "index";}@RequestMapping("/target")public String toTarget(){return "target";} }

    總結:

    • 瀏覽器發送請求,若請求地址符合前端控制器的url-pattern,該請求就會被前端控制器 DispatcherServlet 處理
    • 前端控制器會讀取 SpringMVC 的核心配置文件,通過掃描組件找到控制器,將請求地址和控制器中@RequestMapping 注解的 value 屬性值進行匹配(要求每個方法的 value 值唯一)
    • 若匹配成功,該注解所標識的控制器方法就是處理請求的方法,處理請求的方法需要返回一個字符串類型的視圖名稱
    • 該視圖名稱會被視圖解析器解析,加上前綴和后綴組成視圖的路徑,通過 Thymeleaf 對視圖進行渲染,最終轉發到視圖所對應頁面

    二 @RequestMapping

    作用是關聯 請求 和 處理請求的控制器方法。SpringMVC 接收到指定的請求,就會來找到在映射關系中對應的控制器方法來處理這個請求。

    1 注解類與方法的區別

    • @RequestMapping標識一個類:設置映射請求的請求路徑的初始信息
    • @RequestMapping標識一個方法:設置映射請求請求路徑的具體信息
    @Controller @RequestMapping("/test") public class RequestMappingController {//此時請求映射所映射的請求的請求路徑為:/test/testRequestMapping@RequestMapping("/testRequestMapping")public String testRequestMapping(){return "success";} }

    2 value 屬性

    • 通過請求的請求地址匹配請求映射
    • 是一個字符串類型的數組,和其中任意字符串匹配則選擇該方法,滿足其中一個即可
    • @RequestMapping 必須設置的屬性
    <!--以下均能匹配 testRequestMapping()--> <a th:href="@{/testRequestMapping}"> value1 </a> <a th:href="@{/test}"> value2 </a>@RequestMapping( value = {"/testRequestMapping", "/test"} ) public String testRequestMapping(){return "success"; }

    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
    <a th:href="@{/test(username='admin',password=123456)">測試</a>@RequestMapping(value = {"/testRequestMapping", "/test"},method = {RequestMethod.GET, RequestMethod.POST},params = {"username","password!=123456"} ) public String testRequestMapping(){return "success"; }

    5 headers 屬性

    • 根據請求的請求頭信息匹配請求映射
    • 類似 params 屬性,是一個字符串類型的數組,需要同時滿足所有條件,可以通過四種表達式設置請求參數和請求映射的匹配關系:
      “header”:要求請求映射所匹配的請求必須攜帶 header 請求頭信息
      “!header”:要求請求映射所匹配的請求必須不能攜帶 header 請求頭信息
      “header=value”:要求請求映射所匹配的請求必須攜帶 header 請求頭信息且 header=value
      “header!=value”:要求請求映射所匹配的請求必須攜帶 header 請求頭信息且 header!=value

    6 SpringMVC 支持路徑中的占位符

    • 將請求攜帶的參數以請求路徑的形式,向服務器傳遞參數
    • 如果 @RequestMapping 的 value 屬性中有路徑的占位符,則請求時必須有占位符對應的參數,否則出現404
    <a th:href="@{/goods/123}">訪問goods,參數123</a>@Controller public class MyController {@RequestMapping("/goods/{id}")public String goodsPage(@PathVariable("id") int param_id) {System.out.println(param_id);return "goods";} }

    三 獲取 Request 的一系列參數

    1 通過控制器方法的形參

    • 將形參名和 Request 參數名對應即可(如果不同名,則需要使用 @RequestParam),如此只能獲取 Request 參數,而不能獲得請求頭信息等
    • 如果有多個同名的參數,則將形參類型設置為字符串數組
    <a th:href="@{/testParam(username='admin',password=123456)}">測試</a>@RequestMapping("/testParam") public String testParam(String username, String password){System.out.println("username:"+username+",password:"+password);return "success"; }

    2 控制器方法形參 映射 Request 參數 - @RequestParam

    • value:Request 中的參數的 name 屬性
    • required:標明該參數是否必須,如果是必須且未設置 defaultValue,則必須由 Request 傳入
    • defaultValue:默認值
    @Controller public class MyController {@RequestMapping("/goods/diff")// request 傳遞參數為 name, passwdpublic String diff(@RequestParam(value = "name") String n,@RequestParam(value = "passwd", required = false) String pwd) {System.out.println(n + pwd);return "goods";} }

    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
    <!--配置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、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 類型
    @Controller public class TestController {@RequestMapping("/modelandview")public ModelAndView m2() {ModelAndView modelAndView = new ModelAndView();// 設置鍵值對modelAndView.addObject("k", "v");// 設置視圖名稱modelAndView.setViewName("index");return modelAndView;} }

    3 使用 Model 向 request 域對象共享數據

    • 類似于 ServletAPI
    @Controller public class TestController {@RequestMapping("/model")public String m3(Model model) {model.addAttribute("k", "v");return "index";} }

    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
    @Controller public class TestController {@RequestMapping("/modelmap")public String m5(ModelMap modelMap) {modelMap.addAttribute("k", "v");return "index";} }

    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 配置文件中所配置的視圖解析器解析,視圖名稱拼接視圖前綴和視圖后綴所得到的最終路徑,會通過轉發的方式實現跳轉
    @RequestMapping("/testHello") public String testHello(){return "hello"; // 沒有任何前綴 }

    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:"去掉,剩余部分作為最終路徑通過轉發的方式實現跳轉
    @RequestMapping("/testForward") public String testForward(){return "forward:/testHello"; // 先創建 InternalResourceView 再創建 Thymeleaf View }

    3 重定向視圖

    • SpringMVC 中默認的重定向視圖是 RedirectView
    • 當控制器方法中所設置的視圖名稱以"redirect:"為前綴時,創建 RedirectView 視圖,此時的視圖名稱不會被 SpringMVC 配置文件中所配置的視圖解析器解析,而是會將前綴"redirect:"去掉,剩余部分作為最終路徑通過重定向的方式實現跳轉
    • 重定向視圖在解析時,會先將 redirect: 前綴去掉,然后會判斷剩余部分是否以 / 開頭,若是,則自動拼接上下文路徑
    @RequestMapping("/testRedirect") public String testRedirect(){return "redirect:/testHello"; }

    4 使用 view-controller 代替 控制器方法

    • 當控制器方法中,僅僅用來實現頁面跳轉,即只需要設置視圖名稱時,可以將處理器方法用 view-controller 標簽表示
    • 當SpringMVC 中設置任何一個 view-controller 時,其他控制器中的請求映射將全部失效,可以使用標簽<mvc:annotation-driven />開啟
    <mvc:view-controller path="/testView" view-name="success"></mvc:view-controller>

    六 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 轉為對象
    @RequestMapping("/testRequestBody") public String testRequestBody(@RequestBody String requestBody){System.out.println(requestBody);return "success"; }// 輸出 requestBody:username=admin&password=123456 @Override @PostMapping("/add") public CmsPageResult add(@RequestBody CmsPage cmsPage) { // @RequestBody將json轉為對象return this.pageService.add(cmsPage); }

    2 RequestEntity

    • RequestEntity 封裝 HTTP 請求報文,需要在控制器方法的形參中的 泛型位置 設置要將報文轉換的目標類型,當前請求的請求報文就會賦值給該形參
    • 通過 getHeaders() 獲取請求頭信息,通過 getBody() 獲取請求體信息
    @RequestMapping("/request_entity") public String requestEntityTest(RequestEntity<String> entity) {System.out.println(entity.getHeaders());System.out.println(entity.getBody());return "success"; }

    3 @ResponseBody

    • @ResponseBody 用于標識一個 控制器方法,可以將該方法的 返回值 直接作為響應報文的 響應體 響應到瀏覽器
    @RequestMapping("/response_body") @ResponseBody public String responseBodyTest() {return "TIGER YEAR"; }
    • 如果需要以 json 格式,打印 Java對象的響應體,需要導入 jackson 依賴并開啟 mvc 注解驅動
    pom.xml:<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.1</version></dependency>mvc核心配置文件: <mvc:annotation-driven /> @RequestMapping("/response_body_json") @ResponseBody public User responseBodyJsonTest() {return new User("my_name", "my_passwd"); }

    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 的核心配置文件中:

  • 設置異常類型與視圖名稱的映射
  • 保存異常信息到 request 域(可選)
  • <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"><property name="exceptionMappings"> <!--properties類型,鍵值對的結構--><props><!--1. key表示處理器方法執行過程中出現的異常,全類名value(寫在雙標簽之內)表示若出現指定異常時,設置一個新的視圖名稱,跳轉到指定頁面--><prop key="java.lang.ArithmeticException">error</prop></props></property><!--2. exceptionAttribute:將出現的異常信息在請求域中進行共享,value屬性是信息的key--><property name="exceptionAttribute" value="info_key"></property> </bean>

    出現異常后,跳轉到 error.html 訪問異常信息:

    <body><p th:text="${info_key}"></p> </body>

    2 基于注解

    • 使用 @ControllerAdvice 注解異常處理類
    • 使用 @ExceptionHandler(異常類的class對象) 注解異常處理方法
    // 標識為異常處理組件 @ControllerAdvice public class AnnotationExceptionController {// 處理的異常類型,處理多種異常時 @ExceptionHandler(value = {...})@ExceptionHandler(ArithmeticException.class)public String divide0(Exception exception, Model model) {// 向 request 域中寫入鍵值對model.addAttribute("info_key", exception);// 交由 thymeleaf 解析return "fail";} }

    十 使用注解配置 SpringMVC

    • 目的是使用配置類和注解代替 web.xml 和 SpringMVC 配置文件的功能

    1 初始化類:代替 web.xml

    • 繼承自 AbstractAnnotationConfigDispatcherServletInitializer
    /* * 需要完成的功能: * 1.servlet * 2.servlet-mapping * 3.過濾器 * 4.Spring配置類 * 5.SpringMVC配置類*/ public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {// 指定 Spring 配置類@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[]{MySpringConfig.class}; // 創建長度為1的Class數組,放入MySpringConfig.class}// 指定SpringMVC的配置類@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{MyWebConfig.class}; // 同上}// 指定DispatcherServlet的映射規則,即url-pattern@Overrideprotected String[] getServletMappings() {return new String[]{"/"}; // 設置servlet-mapping}// 過濾器@Overrideprotected Filter[] getServletFilters() {// 過濾器1CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();encodingFilter.setEncoding("UTF-8");encodingFilter.setForceRequestEncoding(true);// 過濾器2HiddenHttpMethodFilter hiddenHttpMethodFilter = newHiddenHttpMethodFilter();return new Filter[]{encodingFilter, hiddenHttpMethodFilter};} }

    2 SpringConfig 類:代替 Spring 配置文件(略)

    @Configuration public class MySpringConfig {// ... }

    3 WebConfig 類:代替 SpringMVC 配置文件

    • @Bean 的作用是,將方法返回值(Java 對象)交給 IOC 容器
    /* * 需要完成的功能: * 1.組件掃描 * 2.thymeleaf視圖解析器 * 3.視圖控制器 * 4.mvc注解驅動 * 5.攔截器 * 6.異常處理器 * 7.default-servlet-handler * 8.文件上傳解析器*/@Configuration // 標注當前類為配置類 @ComponentScan(value = {"config", "controller", "interceptor"}) // 開啟組件掃描 @EnableWebMvc // 開啟注解驅動 public class MyWebConfig implements WebMvcConfigurer {/*************************** 重寫WebMvcConfigurer類的方法 ***************************/// 使用默認的servlet處理靜態資源@Overridepublic void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {configurer.enable();}// 攔截器@Overridepublic void addInterceptors(InterceptorRegistry registry) {MyInterceptor myInterceptor = new MyInterceptor();registry.addInterceptor(myInterceptor).addPathPatterns("/**");}// 視圖控制器@Overridepublic void addViewControllers(ViewControllerRegistry registry) {registry.addViewController("/").setViewName("index");}// 異常處理器,一種實現方式,也可以配置為 @bean@Overridepublic void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {// 寫法參考之前的 SpringMVC 配置文件Properties properties = new Properties();properties.setProperty("java.lang.ArithmeticException", "fail"); // (異常全類名,跳轉視圖名稱)SimpleMappingExceptionResolver simpleMappingExceptionResolver = new SimpleMappingExceptionResolver();simpleMappingExceptionResolver.setExceptionMappings(properties); // 設置異常映射simpleMappingExceptionResolver.setExceptionAttribute("info_key"); // 設置異常信息的keyresolvers.add(simpleMappingExceptionResolver);}/************************* 配置 thymeleaf 視圖解析器 *******************************/// 1.配置生成模板解析器@Bean // @Bean的返回值放入IOC容器public ITemplateResolver templateResolver() {WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();// ServletContextTemplateResolver需要一個ServletContext作為構造參數,可通過WebApplicationContext 的方法獲得ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(webApplicationContext.getServletContext());templateResolver.setPrefix("/templates/");templateResolver.setSuffix(".html");templateResolver.setCharacterEncoding("UTF-8");templateResolver.setTemplateMode(TemplateMode.HTML);return templateResolver;}// 2.生成模板引擎并為其注入模板解析器@Beanpublic SpringTemplateEngine templateEngine(ITemplateResolver templateResolver) { // !!!參數進行了自動裝配SpringTemplateEngine templateEngine = new SpringTemplateEngine();templateEngine.setTemplateResolver(templateResolver);return templateEngine;}// 3.生成視圖解析器并為其注入模板引擎@Beanpublic ViewResolver viewResolver(SpringTemplateEngine templateEngine) {ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();viewResolver.setCharacterEncoding("UTF-8");viewResolver.setTemplateEngine(templateEngine);return viewResolver;}/************************* 其它插件 *******************************/// 配置文件上傳解析器 // @Bean // public CommonsMultipartResolver multipartResolver(){ // return new CommonsMultipartResolver(); // }}

    十一 SpringMVC 執行流程

    1 常用組件

    • DispatcherServlet:前端控制器,不需要工程師開發,由框架提供
      作用:統一處理請求和響應,整個流程控制的中心,由它調用其它組件處理用戶的請求

    • HandlerMapping:處理器映射器,不需要工程師開發,由框架提供
      作用:根據請求的url、method等信息查找Handler,即控制器方法

    • Handler:處理器
      作用:在DispatcherServlet的控制下Handler對具體的用戶請求進行處理

    • HandlerAdapter:處理器適配器,不需要工程師開發,由框架提供
      作用:通過HandlerAdapter對處理器(控制器方法)進行執行

    • ViewResolver:視圖解析器,不需要工程師開發,由框架提供
      作用:進行視圖解析,得到相應的視圖,例如:ThymeleafView、InternalResourceView、RedirectView

    • View:視圖
      作用:將模型數據通過頁面展示給用戶

    2 流程總結

  • 用戶向服務器發送請求,被 SpringMVC 前端控制器 DispatcherServlet 捕獲
  • DispatcherServlet 解析 URL(統一資源定位器),得到URI(請求資源標識符),并與配置的 servlet-mapping 進行匹配,判斷請求 URI 對應的映射:
    (1) 可以匹配,則交給具體的 Servlet,前往步驟3
    (2) 不能匹配,如果配置了 mvc:default-servlet-handler ,訪問目標資源(一般為靜態資源,如:JS, CSS, HTML),找不到展示404錯誤
    (3) 不能匹配,沒有配置 mvc:default-servlet-handler,展示404錯誤
  • 根據 URI,調用 HandlerMapping 獲得該 Handler 配置的所有相關的對象(包括 Handler 對象以及Handler 對象對應的攔截器),最后以 HandlerExecutionChain 執行鏈對象的形式返回
  • DispatcherServlet 根據獲得的 Handler,選擇一個合適的 HandlerAdapter(Handler 執行需要依賴HandlerAdapter)
  • 如果成功獲得 HandlerAdapter,此時將開始執行攔截器的 preHandler() 方法
  • 向控制器方法傳遞客戶端請求 Request 攜帶的參數,執行控制器方法,此處可以配置一些額外操作:
    (1) HttpMessageConveter: 將請求消息(如Json、xml等數據)轉換成一個對象,將對象轉換為指定的響應信息
    (2) 數據格式化、數據驗證…
  • 控制器方法執行完成后,向 DispatcherServlet 返回一個 ModelAndView 對象
  • 執行攔截器的 postHandle() 方法
  • DispatcherServlet 根據返回的 ModelAndView(首先判斷是否存在異常:如果存在異常,則執行HandlerExceptionResolver 進行異常處理)選擇一個適合的 ViewResolver 進行視圖解析,根據 Model 和 View,渲染視圖
  • 執行攔截器的 afterCompletion() 方法
  • 將渲染結果返回給客戶端
  • 總結

    以上是生活随笔為你收集整理的后端学习 - SpringMVC的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。