1. 程式人生 > 其它 >Springmvc 簡介(03)

Springmvc 簡介(03)

技術標籤:SSMspringmvc

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、

POSTDELETEHypermedia 是應用程式狀態的引擎,資源表示通過超連結互聯。

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過濾器的不同:

  1. 過濾器優先於攔截器

  2. 攔截器是基於java的反射機制,過濾器是基於函式回撥,

  3. 攔截器不依賴與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;