Java框架之SpringMVC 03-RequestMapping-請求數據-響應數據

来源:https://www.cnblogs.com/Open-ing/archive/2020/01/19/12185441.html

SpringMVC SpringMVC是一種輕量級的、基於MVC的Web層應用框架。 通過一套 MVC 註解,讓 POJO 成為處理請求的控制器,而無須實現任何介面。 採用了鬆散耦合可插拔組件結構,比其他 MVC 框架更具擴展性和靈活性。 優點: 1、天生與Spring框架集成,如:(IOC,AOP ...


SpringMVC

SpringMVC是一種輕量級的、基於MVC的Web層應用框架。

通過一套 MVC 註解,讓 POJO 成為處理請求的控制器,而無須實現任何介面。

採用了鬆散耦合可插拔組件結構,比其他 MVC 框架更具擴展性和靈活性。

優點:

  1、天生與Spring框架集成,如:(IOC,AOP)

  2、支持Restful風格

  3、支持靈活的URL到頁面控制器的映射

  4、非常容易與其他視圖技術集成,如:Velocity、FreeMarker等等

  5、因為模型數據不存放在特定的API里,而是放在一個Model里(Map數據結構實現,因此很容易被其他框架使用)

  6、非常靈活的數據驗證、格式化和數據綁定機制、能使用任何對象進行數據綁定,

  7、更加簡單、強大的異常處理

  8、對靜態資源的支持

  9、支持靈活的本地化、主題等解析

 常用主要組件

  ① DispatcherServlet:前端控制器
  ② Controller:處理器/頁面控制器,做的是MVC中的C的事情,但控制邏輯轉移到前端控制器了,用於對請求進行處理
  ③ HandlerMapping:請求映射到處理器,找誰來處理,如果映射成功返回一個HandlerExecutionChain對象(包含一個Handler處理器(頁面控制器)對象、多個HandlerInterceptor攔截器對象)
  ④ View Resolver : 視圖解析器,找誰來處理返回的頁面。把邏輯視圖解析為具體的View,進行這種策略模式,很容易更換其他視圖技術;如InternalResourceViewResolver將邏輯視圖名映射為JSP視圖
  ⑤ LocalResolver:本地化、國際化
  ⑥ MultipartResolver:文件上傳解析器
  ⑦ HandlerExceptionResolver:異常處理器

Spring MVC 的配置文件

流程分析

基本步驟:

  ①    客戶端請求提交到DispatcherServlet

  ②    由DispatcherServlet控制器查詢一個或多個HandlerMapping,找到處理請求的Controller

  ③    DispatcherServlet將請求提交到Controller(也稱為Handler)

  ④    Controller調用業務邏輯處理後,返回ModelAndView

  ⑤    DispatcherServlet查詢一個或多個ViewResoler視圖解析器,找到ModelAndView指定的視圖

  ⑥    視圖負責將結果顯示到客戶端

標準的 HTTP 請求報頭

@RequestMapping

1、使用@RequestMapping 註解來映射請求的 URL    

  @RequestMapping可以應用的地方

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {…}

  請求的方式有

public enum RequestMethod {
        GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
    }

  @RequestMapping可以為控制器指定可以處理哪些 URL 請求,將該註解中的 value 屬性值映射成URL,客戶端可以通過該URL請求到指定類中的方法。

    1)在控制器的類定義或方法定義處都可標註 @RequestMapping
      ① 標記在類上:提供初步的請求映射信息。相對於 WEB 應用的根目錄
      ② 標記在方法上:提供進一步的細分映射信息。相對於標記在類上的 URL。
    2)若類上未標註 @RequestMapping,則方法處標記的 URL 相對於 WEB 應用的根目錄 
    3)作用:DispatcherServlet 截獲請求後,就通過控制器上 @RequestMapping 提供的映射信息確定請求所對應的處理方法。

  @RequestMapping屬性

    value:指定URL路徑
    method:指定請求方式 
    params:指定請求參數
    headers:指定請求頭信息

  映射請求參數、請求方式或請求頭

    1)@RequestMapping 除了可以使用請求 URL 映射請求外,還可以使用請求方法、請求參數及請求頭來精確映射對應請求
    2)@RequestMapping 的 value【重點】、method【重點】、params【瞭解】 及 heads【瞭解】 分別表示請求 URL、請求方式、請求參數及請求頭的映射條件,他們之間是與的關係,聯合使用多個條件可讓請求映射更加精確化。即:需滿足所有映射條件才可匹配到對應方法
    3)params 和 headers支持簡單的表達式:
      param1: 表示請求必須包含名為 param1 的請求參數
      !param1: 表示請求不能包含名為 param1 的請求參數
      param1 != value1: 表示請求包含名為 param1 的請求參數,但其值不能為 value1
      {"param1=value1", "param2"}: 請求必須包含名為 param1 和param2 的兩個請求參數,且 param1 參數的值必須為 value1

Ant 路徑風格

  Ant 風格資源地址支持 3 種匹配符:【瞭解】
    ?:匹配文件名中的一個字元
    *:匹配文件名中的任意字元
    **:** 匹配多層路徑

/user/*/**/createUser??
匹配 /user/xxx/多層/createUserXX 

REST

REST是什麼?因為REST的內涵非常豐富,所以很難用一兩句話解釋清楚這個問題。首先,REST是Web自身的架構風格。

參考資料:理解本真的REST架構風格  

  REST:即 Representational State Transfer。(資源)表現層狀態轉化。是目前最流行的一種互聯網軟體架構。它結構清晰、符合標準、易於理解、擴展方便

  資源(Resources):資源是一種看待伺服器的方式。是網路上的一個實體,可以是一段文本、一張圖片,可以用一個URI(統一資源定位符,獨一無二的識別符)指向它,獲取這個資源,訪問它的URI就可以了

  表現層資源的表述(Representation)是一段對於資源在某個特定時刻的狀態的描述,即把資源具體呈現出來的形式, 比如,文本可以用 txt 、JSON 格式表現,甚至可以採用二進位格式。

  狀態轉化(State Transfer):狀態轉移說的是:在客戶端和伺服器端之間轉移(transfer)代表資源狀態的表述。通過轉移和操作資源的表述,來間接實現操作資源的目的。如:每發出一個請求,就代表了客戶端和伺服器的一次交互過程。HTTP協議,是一個無狀態協議,即所有的狀態都保存在伺服器端。因此,如果客戶端想要操作伺服器,必須通過某種手段,讓伺服器端發生“狀態轉化”。而這種轉化是建立在表現層之上的,所以就是 “表現層狀態轉化”。

  統一介面(Uniform Interface)REST要求,必須通過統一的介面來對資源執行各種操作。對於每個資源只能執行一組有限的操作。例如:HTTP/1.1協議定義了一個操作資源的統一介面。REST還要求,對於資源執行的操作,其操作語義必須由HTTP消息體之前的部分完全表達,不能將操作語義封裝在HTTP消息體內部。這樣做是為了提高交互的可見性

  超文本驅動(Hypertext Driven)將Web應用看作是一個由很多狀態(應用狀態)組成的有限狀態機。資源之間通過超鏈接相互關聯,超鏈接既代表資源之間的關係,也代表可執行的狀態遷移。即:客戶端應該依賴的是超媒體的狀態遷移語義,而不應該對於是否存在某個URI或URI的某種特殊構造方式作出假設。一切都有可能變化,只有超媒體的狀態遷移語義能夠長期保持穩定。

  具體對於HTTP來說,就是 HTTP 協議裡面對應的四種常用基本操作:GET 用來獲取資源,POST 用來新建資源,PUT 用來更新資源,DELETE 用來刪除資源。應使用由客戶端定義的請求方式指定對應的某種操作,而不應該通過某種特殊構造方式進行指定

HiddenHttpMethodFilter過濾器

  瀏覽器 form 表單隻支持 GET 與 POST 請求,HiddenHttpMethodFilter 可以將POST請求轉換為標準的 http 方法以達到REST風格

使用步驟

  1. 必須將form表單中的method設置為POST
  2. 提交表單時,必須提交"_method"參數,一般使用隱藏域

    原因:HiddenHttpMethodFilter過濾器將HttpServletRequest中的getMethod()方法,重寫啦。

    <!--    配置處理請求方式-->
    <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>

 

處理請求數據

  Spring MVC 框架會將 HTTP 請求的信息綁定到相應的方法入參中,並根據方法的返回值類型做出相應的後續處理。

  可以對方法及方法入參標註相應的註解( @PathVariable 、@RequestParam、@RequestHeader 等)

@PathVariable請求占位符

  是 Spring3.0 新增的功能,通過 @PathVariable 可以將 URL 中占位符參數綁定到控制器處理方法的入參中

//@PathVariable 註解可以將請求URL路徑中的請求參數,傳遞到處理請求方法的入參中
// 瀏覽器的請求為:  testPathVariable/1001
@RequestMapping(value="/testPathVariable/{id}",method=RequestMethod.DELET)
public String testPathVariable(@PathVariable("id") Integer id) {}

@RequestParam請求參數

  如果請求參數與形參不一致時,可以使用@RequestParam註解實現獲取參數值

  書寫位置:標註在方法的參數中,springMVC預設會將請求參數註入(綁定)到方法形參中(兩個參數名一致)

  一旦使用該註解,必須為相應參數傳參數。如果未傳參,會報錯:400,因為required預設為 true,

  value:用於映射請求參數名稱

  required:是否必須。預設為 true, 表示請求參數中必須包含對應的參數,若不存在,將拋出異常

  defaultValue: 預設值,當沒有傳遞參數時使用該值作為預設值,不設預設為 null

 @RequestMapping(value="/testRequestParam?username=guigu&age=10")
    public String testRequestParam(
            @RequestParam(value="username") String username,
            @RequestParam(value="age",required=false,defaultValue="0") int age){
        return "success";
    }

 

@RequestHeader 請求頭

  獲取請求頭信息,請求頭包含了若幹個屬性,伺服器可據此獲知客戶端的信息,通過 @RequestHeader 即可將請求頭中的屬性值綁定到處理方法的入參中 

@CookieValue 

  獲取指定的Cookie信息,可讓處理方法入參綁定某個 Cookie 值

使用POJO作為參數

  Spring MVC 會按請求參數名和 POJO 屬性名進行自動匹配,自動為該對象填充屬性值支持級聯屬性

    @RequestMapping(value = "/emps",method = RequestMethod.PUT)
    public String updateEmp(Employee employee){
        employeeDao.save(employee);
        return "redirect:/emps";
    }
   //Spring MVC 會按請求參數名和 Employee 屬性名進行自動匹配, 自動為該對象填充屬性值。支持級聯屬性

 

配置字元編碼過濾器

    <!--    處理POST請求和響應亂碼-->
    <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>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

GET請求亂碼

  • GET請求參數是在地址後面的。我們需要修改tomcat的配置文件。需要在server.xml文件修改Connector標簽,添加URIEncoding="utf-8"屬性。

使用Servlet原生API

    /**
     * 可以使用 Serlvet 原生的 API 作為目標方法的參數 具體支持以下類型
     * HttpServletRequest 
     * HttpServletResponse 
     * HttpSession
     * java.security.Principal 
     * Locale 
   * InputStream * OutputStream * Reader * Writer
*/ @RequestMapping("/testServletAPI") public void testServletAPI(HttpServletRequest request,HttpServletResponse response, Writer out) throws IOException { System.out.println("testServletAPI, " + request + ", " + response); out.write("hello springmvc"); }

 

處理響應數據

2、返回值會通過視圖解析器解析為實際的物理視圖

輸出模型數據類型

  1)    ModelAndView: 作為返回值類型,響應數據:處理方法返回值類型為 ModelAndView 時, 方法體即可通過該對象添加模型數據

  2)  String: 作為返回值類型,即為視圖信息直接找字元串映射 URL 路徑,轉發或重定向

  3)    Map 或 Model: 作為參數,響應數據:入參為 Model、ModelMap 或  Map,處理方法返回時,Map 中的數據會自動添加到模型中。

ModelAndView

  控制器處理方法的返回值如果為 ModelAndView, 則其包含視圖信息包含模型數據信息

  1)  兩個重要的成員變數:

    private Object view;                       【視圖信息】

    private ModelMap model;              【模型數據】

  2)添加模型數據:

    MoelAndView addObject(String attributeName, Object attributeValue)   【設置模型數據】

    ModelAndView addAllObject(Map<String, ?> modelMap)

  4)設置視圖:

    void setView(View view)                         【設置視圖對象】

    void setViewName(String viewName)            【設置視圖名字】

  5)獲取模型數據

    protected Map<String, Object> getModelInternal()   【獲取模型數據】

    public ModelMap getModelMap()

    public Map<String, Object> getModel()

    @RequestMapping("/testModelAndView")
    public ModelAndView testModelAndView(){
        String viewName = "success";
        ModelAndView mv = new ModelAndView(viewName);
        mv.addObject("time",new Date().toString()); //實質上存放到request域中 
        return mv;
    }

ModelAndView 底層工作原理,不論控制器返回一個String,ModelAndView,View都會轉換為ModelAndView對象,將數據放到request域中,再通過轉發實現頁面跳轉

Map   Model

  Spring MVC 在內部使用了一個 org.springframework.ui.Model 介面存儲模型數據

  Spring MVC 在調用方法前會創建一個隱含的模型對象作為模型數據的存儲容器

  如果方法的入參為 Map 或 Model 類型,Spring MVC 會將隱含模型的引用傳遞給這些入參。

  在方法體內,開發者可以通過這個入參對象訪問到模型中的所有數據,也可以向模型中添加新的屬性數據

    //目標方法的返回類型也可以是一個Map類型參數(也可以是Model,或ModelMap類型)
    @RequestMapping("/testMap")
    public String testMap(Map<String, Object> map) { //【重點】
        System.out.println(map.getClass().getName());
    //org.springframework.validation.support.BindingAwareModelMap
        map.put("names", Arrays.asList("Tom", "Jerry", "Kite"));
        return "success";
    }

 

註意問題:Map集合的泛型,key為String,Value為Object,而不是String

由源碼可知:不論用那個類型作為數據模型,其內部都會轉化為BindingAwareModelMap類型使其指向同一map對象

BindingAwareModelMap底層支持兩種介面(Map&Model)推薦使用 Map 便於框架移植


您的分享是我們最大的動力!

更多相關文章
  • html方法和text方法 //html:innerHTML text:innerText console.log($("div").html());//<h3>我是標題</h3> console.log($("div").text());//我是標題 $("div").text("<p>我是文本< ...
  • dir同樣可以查找實例的屬性字典 print(dir(p1)) 下麵是增刪改查舉例: class Chinese: country='中國' def __init__(self,name): self.name=name def play_ball(self,ball): print('%s正在打% ...
  • 程式員在轉型架構師的過程中需要建立流程化、結構化、系統化的思維方式,而性能調優是非常難得的契機,它既給了我們壓力,也給了我們動力,跨越它就是突破自己的過程。Y 維度,就是從業務 HTTP 請求的橫向處理流程來看,HTTP 請求會穿越網路、電腦、應用容器(Tomcat)、Spring、ORM(Hib... ...
  • 一、java中八種基本數據類型對應的包裝類型 基本數據類型 包裝類型 byte java.lang.Byte short java.lang.Short int java.lang.Integer long java.lang.Long float java.lang.Float double ja ...
  • 開發環境: Windows操作系統 開發工具: Eclipse+Jdk+Tomcat+MYSQL資料庫 運行效果圖: 源碼及原文鏈接:http://javadao.xyz/forum.php?mod=viewthread&tid=28 ...
  • 慕課網-跳跳虎-圖解+仿寫 新手都能學懂的SpringBoot源碼課-366元 慕課網-跳跳虎-圖解+仿寫 新手都能學懂的SpringBoot源碼課-366元——全方位深入解析最新版SpringBoot源碼當下SpringBoot日漸取代SSM成為新項目首選框架,企業招聘對其要求也不斷提高。掌握Sp ...
  • 概述 ReentrantLock是一個可重入的互斥鎖,也被稱為獨占鎖。它支持公平鎖和非公平鎖兩種模式。 ReentrantLock的使用方法 下麵看一個最初級的例子: 在進入方法後,在需要加鎖的一些操作執行之前需要調用lock方法,在jdk文檔中對lock方法詳細解釋如下: 獲得鎖。 如果鎖沒有被另 ...
  • 相信有不少朋友日常工作會用到 Excel 處理各式表格文件,更有甚者可能要花大把時間來做繁瑣耗時的表格整理工作。最近有朋友問可否編程來減輕表格整理工作量,今兒我們就通過實例來實現 Python 對錶格的自動化整理。 首先我們有這麼一份數據表 source.csv: 我們要做的是從上表中提取數據,來生 ...
一周排行
  • 《ASP.NET MVC 企業級實戰》 [作者] (中) 鄒瓊俊[出版] 清華大學出版社[版次] 2017年04月 第1版[印次] 2019年08月 第6次 印刷[定價] 89.00元 【第01章】 (P021) 只有在 Lambda 有一個輸入參數時,括弧才是可選的,否則括弧是必需的。 使用空括弧 ...
  • 上一篇(https://www.cnblogs.com/meowv/p/12971041.html)使用HtmlAgilityPack抓取壁紙數據成功將圖片存入資料庫,本篇繼續來完成一個全網各大平臺的熱點新聞數據的抓取。 同樣的,可以先預覽一下我個人博客中的成品:https://meowv.com/ ...
  • 前言 請了一天假後回公司,同事跟我說使用Newtonsoft.json序列化TreeView對象的時候出現報錯; 啊!什麼?這個類庫不是能夠序列化所有東西嗎?真的很懵逼,也是我第一次使用這個類庫出現問題! 問題異常 異常信息 : Newtonsoft.Json.JsonSerializationEx ...
  • 簡單瞭解下麵詞語的意思 節點:二叉樹中每個元素都稱為節點 葉子節點(簡稱:葉子):度為0的節點,葉子節點就是樹中最底段的節點,葉子節點沒有子節點,也叫終端結點 分枝節點:度不為0的結點 節點的度:二叉樹的度代表某個節點的孩子或者說直接後繼的個數,簡單說就是一個節點擁有的子樹數 樹的度: 樹中最大的結 ...
  • C# 中的LINQ 提供了兩種操作方式,查詢表達式和查詢操作符,所有的查詢表達式都有對應的查操作符類替代,查詢表達式有點“類” SQL,在代碼中寫SQL,總覺得不夠“優雅”,使用查詢操作符就顯得“優雅”很多, 本系列就來對所有的LINQ 標準操作符進行一個全面的總結,這些操作符和我上篇文章總結的Rx ...
  • 在Startup ConfigureServices 註冊本地化所需要的服務AddLocalization和 Configure<RequestLocalizationOptions> public void ConfigureServices(IServiceCollection services ...
  • 為什麼需要持久化,以及Redis持久化的RDB方式在這篇文章講的已經很透徹了,足以弔打面試官了。而且此篇內容需要RDB文章的內容支持,所以建議先看下:看完這篇還不懂Redis的RDB持久化,你們來打我! 一、什麼是AOF 它也是Redis持久化的重要手段之一,aof->Append Only Fil ...
  • 先上圖: @IT程式猿 微博網友評論: @迢書:前同事的,親眼見過 @AvenGeeker:Bug 404 @科技州:這是要逼死強迫症 @小島一瞥:哈哈哈哈哈我老家的車 最後小編整理了一套技術資料不僅能精準消除技術盲點、累計面試經驗,更可以攻剋JVM、Spring、分散式、微服務等技術難題。 海量電 ...
  • 概括來說,分三步: 1,首先找到是哪個進程的CPU占有率飆到了100%。 2,根據進程號pid,定位到是哪個線程,找到對應線程的tid。 3,導出對應線程的dump日誌文件,分析日誌文件定位具體代碼。 要解決這個問題,你應該具備以下技能: 1,linux的top命令。 2,jvm監控工具jps。 3 ...
  • 寫在最後 程式員為何害怕【別人的代碼】呢?這讓我想起一個段子。 寫這段代碼時 只有上帝和我知道他是幹嘛的 現在 只有上帝知道了 別人的代碼,似乎總意味著冗長、晦澀、凌亂,給人一種不想靠近的感覺。搞笑的是,對於一些程式員而言,即使是自己的代碼,在一段時間之後自己再拿來看,也成了【別人的代碼】... 作 ...