1. 程式人生 > >@RequestParam @RequestBody @PathVariable 等引數繫結註解詳解(轉載)

@RequestParam @RequestBody @PathVariable 等引數繫結註解詳解(轉載)

 學習了下,對@RequestBody,@SessionAttributes,@ModelAttribute還不是很瞭解,繼續學習,也望知道的能告訴我一下,謝謝。

簡介: 

handler method 引數繫結常用的註解,我們根據他們處理的Request的不同內容部分分為四類:(主要講解常用型別)

A、處理requet uri 部分(這裡指uri template中variable,不含queryString部分)的註解:   @PathVariable;

B、處理request header部分的註解:   @RequestHeader, @CookieValue;

C、處理request body部分的註解:@RequestParam,  @RequestBody;

D、處理attribute型別是註解: @SessionAttributes, @ModelAttribute;

1、 @PathVariable

當使用@RequestMapping URI template 樣式對映時, 即 someUrl/{paramId}, 這時的paramId可通過 @Pathvariable註解繫結它傳過來的值到方法的引數上。

示例程式碼:

  1. @Controller
  2. @RequestMapping("/owners/{ownerId}"
  3. publicclass RelativePathUriTemplateController { 
  4.   @RequestMapping("/pets/{petId}"
  5.   publicvoid findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {     
  6.     // implementation omitted
  7.   } 
@Controller
@RequestMapping("/owners/{ownerId}")
public class RelativePathUriTemplateController {

  @RequestMapping("/pets/{petId}")
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {    
    // implementation omitted
  }
}

上面程式碼把URI template 中變數 ownerId的值和petId的值,繫結到方法的引數上。若方法引數名稱和需要繫結的uri template中變數名稱不一致,需要在@PathVariable("name")指定uri template中的名稱。

2、 @RequestHeader、@CookieValue

@RequestHeader 註解,可以把Request請求header部分的值繫結到方法的引數上。

示例程式碼:

這是一個Request 的header部分:

  1. Host                    localhost:8080 
  2. Accept                  text/html,application/xhtml+xml,application/xml;q=0.9 
  3. Accept-Language         fr,en-gb;q=0.7,en;q=0.3 
  4. Accept-Encoding         gzip,deflate 
  5. Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7 
  6. Keep-Alive              300 
Host                    localhost:8080
Accept                  text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Language         fr,en-gb;q=0.7,en;q=0.3
Accept-Encoding         gzip,deflate
Accept-Charset          ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive              300
  1. @RequestMapping("/displayHeaderInfo.do"
  2. publicvoid displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding, 
  3.                               @RequestHeader("Keep-Alive"long keepAlive)  { 
  4.   //...
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding,
                              @RequestHeader("Keep-Alive") long keepAlive)  {

  //...

}

上面的程式碼,把request header部分的 Accept-Encoding的值,繫結到引數encoding上了, Keep-Alive header的值繫結到引數keepAlive上。

@CookieValue 可以把Request header中關於cookie的值繫結到方法的引數上。

例如有如下Cookie值:

  1. JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84 
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84

引數繫結的程式碼:

  1. @RequestMapping("/displayHeaderInfo.do"
  2. publicvoid displayHeaderInfo(@CookieValue("JSESSIONID") String cookie)  { 
  3.   //...
@RequestMapping("/displayHeaderInfo.do")
public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie)  {

  //...

}

即把JSESSIONID的值繫結到引數cookie上。

3、@RequestParam, @RequestBody

@RequestParam

A) 常用來處理簡單型別的繫結,通過Request.getParameter() 獲取的String可直接轉換為簡單型別的情況( String--> 簡單型別的轉換操作由ConversionService配置的轉換器來完成);因為使用request.getParameter()方式獲取引數,所以可以處理get 方式中queryString的值,也可以處理post方式中 body data的值;

B)用來處理Content-Type: 為 application/x-www-form-urlencoded編碼的內容,提交方式GET、POST;

C) 該註解有兩個屬性: value、required; value用來指定要傳入值的id名稱,required用來指示引數是否必須繫結;

示例程式碼:

  1. @Controller
  2. @RequestMapping("/pets"
  3. @SessionAttributes("pet"
  4. publicclass EditPetForm { 
  5.     // ...
  6.     @RequestMapping(method = RequestMethod.GET) 
  7.     public String setupForm(@RequestParam("petId"int petId, ModelMap model) { 
  8.         Pet pet = this.clinic.loadPet(petId); 
  9.         model.addAttribute("pet", pet); 
  10.         return"petForm"
  11.     } 
  12.     // ...
@Controller
@RequestMapping("/pets")
@SessionAttributes("pet")
public class EditPetForm {

    // ...

    @RequestMapping(method = RequestMethod.GET)
    public String setupForm(@RequestParam("petId") int petId, ModelMap model) {
        Pet pet = this.clinic.loadPet(petId);
        model.addAttribute("pet", pet);
        return "petForm";
    }

    // ...

@RequestBody

該註解常用來處理Content-Type: 不是application/x-www-form-urlencoded編碼的內容,例如application/json, application/xml等;

它是通過使用HandlerAdapter 配置的HttpMessageConverters來解析post data body,然後繫結到相應的bean上的。

因為配置有FormHttpMessageConverter,所以也可以用來處理 application/x-www-form-urlencoded的內容,處理完的結果放在一個MultiValueMap<String, String>裡,這種情況在某些特殊需求下使用,詳情檢視FormHttpMessageConverter api;

示例程式碼:

  1. @RequestMapping(value = "/something", method = RequestMethod.PUT) 
  2. publicvoid handle(@RequestBody String body, Writer writer) throws IOException { 
  3.   writer.write(body); 
@RequestMapping(value = "/something", method = RequestMethod.PUT)
public void handle(@RequestBody String body, Writer writer) throws IOException {
  writer.write(body);
}

4、@SessionAttributes, @ModelAttribute

@SessionAttributes:

該註解用來繫結HttpSession中的attribute物件的值,便於在方法中的引數裡使用。

該註解有value、types兩個屬性,可以通過名字和型別指定要使用的attribute 物件;

示例程式碼:

  1. @Controller
  2. @RequestMapping("/editPet.do"
  3. @SessionAttributes("pet"
  4. publicclass EditPetForm { 
  5.     // ...
@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
    // ...
}

@ModelAttribute

該註解有兩個用法,一個是用於方法上,一個是用於引數上;

用於方法上時:  通常用來在處理@RequestMapping之前,為請求繫結需要從後臺查詢的model;

用於引數上時: 用來通過名稱對應,把相應名稱的值繫結到註解的引數bean上;要繫結的值來源於:

A) @SessionAttributes 啟用的attribute 物件上;

B) @ModelAttribute 用於方法上時指定的model物件;

C) 上述兩種情況都沒有時,new一個需要繫結的bean物件,然後把request中按名稱對應的方式把值繫結到bean中。

用到方法上@ModelAttribute的示例程式碼:

  1. // Add one attribute
  2. // The return value of the method is added to the model under the name "account"
  3. // You can customize the name via @ModelAttribute("myAccount")
  4. @ModelAttribute
  5. public Account addAccount(@RequestParam String number) { 
  6.     return accountManager.findAccount(number); 
// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount")

@ModelAttribute
public Account addAccount(@RequestParam String number) {
    return accountManager.findAccount(number);
}

這種方式實際的效果就是在呼叫@RequestMapping的方法之前,為request物件的model裡put(“account”, Account);

用在引數上的@ModelAttribute示例程式碼:

  1. @RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST) 
  2. public String processSubmit(@ModelAttribute Pet pet) { 
@RequestMapping(value="/owners/{ownerId}/pets/{petId}/edit", method = RequestMethod.POST)
public String processSubmit(@ModelAttribute Pet pet) {
   
}

首先查詢 @SessionAttributes有無繫結的Pet物件,若沒有則查詢@ModelAttribute方法層面上是否綁定了Pet物件,若沒有則將URI template中的值按對應的名稱繫結到Pet物件的各屬性上。

補充講解:

問題: 在不給定註解的情況下,引數是怎樣繫結的?

通過分析AnnotationMethodHandlerAdapter和RequestMappingHandlerAdapter的原始碼發現,方法的引數在不給定引數的情況下:

若要繫結的物件時簡單型別:  呼叫@RequestParam來處理的。 

若要繫結的物件時複雜型別:  呼叫@ModelAttribute來處理的。

這裡的簡單型別指java的原始型別(boolean, int 等)、原始型別物件(Boolean, Int等)、String、Date等ConversionService裡可以直接String轉換成目標物件的型別;

下面貼出AnnotationMethodHandlerAdapter中繫結引數的部分原始碼:

  1. private Object[] resolveHandlerArguments(Method handlerMethod, Object handler, 
  2.             NativeWebRequest webRequest, ExtendedModelMap implicitModel) throws Exception { 
  3.         Class[] paramTypes = handlerMethod.getParameterTypes(); 
  4.         Object[] args = new Object[paramTypes.length]; 
  5.         for (int i = 0; i < args.length; i++) { 
  6.             MethodParameter methodParam = new MethodParameter(handlerMethod, i); 
  7.             methodParam.initParameterNameDiscovery(this.parameterNameDiscoverer); 
  8.             GenericTypeResolver.resolveParameterType(methodParam, handler.getClass()); 
  9.             String paramName = null
  10.             String headerName = null
  11.             boolean requestBodyFound = false
  12. 相關推薦

    @RequestParam @RequestBody @PathVariable 引數註解轉載

     學習了下,對@RequestBody,@SessionAttributes,@ModelAttribute還不是很瞭解,繼續學習,也望知道的能告訴我一下,謝謝。 簡介:  handler method 引數繫結常用的註解,我們根據他們處理的Reque

    @RequestParam @RequestBody @PathVariable 引數註解

    引言: 接上一篇文章,對@RequestMapping進行地址對映講解之後,該篇主要講解request 資料到handler method 引數資料的繫結所用到的註解和什麼情形下使用; 簡介: handler method 引數繫結常用的註解,我們根據他們處理的

    SpringMVC中的引數註解及其使用場景

    我認為只有深刻地研究過人,才能創造出人物,如同只有認真地學習了一種語言才能講它一樣。——《茶花女》 0、引言 最近在寫一個介面的時候,採用put請求,接收引數時採用了兩個@requestparam接收。前端通過application/json傳來兩個引數,測

    springmvc 引數註解

    簡介   Handler method引數繫結常用的註解,我們根據它們處理request的不同內容部分來看主要分為四類:   A. 處理requesr uri部分的註解,@PathVariable   B. 處理 request header部分的註解,@RequestH

    Spring註解轉載

    概述 註釋配置相對於 XML 配置具有很多的優勢: 它可以充分利用 Java 的反射機制獲取類結構資訊,這些資訊可以有效減少配置的工作。如使用 JPA 註釋配置 ORM 對映時,我們就不需要指定 PO 的屬性名、型別等資訊,如果關係表字段和 PO 屬性名、型別都一致,

    理解Javascript中的事件與事件委託轉載

    最近在深入實踐js中,遇到了一些問題,比如我需要為動態建立的DOM元素繫結事件,那麼普通的事件繫結就不行了,於是通過上網查資料瞭解到事件委託,因此想總結一下js中的事件繫結與事件委託。 事件繫結 最直接的事件繫結:HTML事件處理程式 如下示例程式碼,通過節點屬性顯式宣

    Spring MVC @RequestMapping註解2

    並不是 value get ecif 使用 .com java代碼 處理方法 分開 @RequestMapping 參數說明   value:定義處理方法的請求的 URL 地址。(重點)   method:定義處理方法的 http method 類型,如 GET、POST

    Rsync命令引數轉載

    在對rsync伺服器配置結束以後,下一步就需要在客戶端發出rsync命令來實現將伺服器端的檔案備份到客戶端來。rsync是一個功能非常強大的工具,其命令也有很多功能特色選項,我們下面就對它的選項一一進行分析說明。 Rsync的命令格式可以為以下六種: 1 rsync

    MySQL配置檔案my.cnf引數優化和中文

    原文地址:http://www.jb51.net/article/48082.htm 這篇文章主要介紹了MySQL配置檔案my.cnf引數優化和中文詳解,非常詳細的用中文註釋了各個引數的作用以及建議值,需要的朋友可以參考下 Mysql引數優化對於新手來講,是比較難懂的東

    @RequestParam @RequestBody @PathVariable 參數綁定註解

    erro 後綁定 false zip ons type() eba veh manager 引言: 接上一篇文章,對@RequestMapping進行地址映射講解之後,該篇主要講解request 數據到handler method 參數數據的綁定所用到的註解和什麽情形下使用

    SpringMVC引數註解

    以下文章轉自“開濤的部落格”在SpringMVC 的控制器中提供了很多請求資料繫結的註解,以及功能處理方法支援的引數型別:請求引數繫結註解:@RequestParam繫結單個請求引數值;@PathVariable繫結URI模板變數值;@CookieValue繫結Cookie資

    SpringMVC 引數相關注

    @RequestParams 作用:把請求中指定名稱的引數給控制器中的形參賦值。 屬性: // <a href="account/save3.do?id=100&username=jack"> 儲存 2</a>

    vue 雙向資料的實現學習- 監聽器的實現

    廢話:上一篇https://www.cnblogs.com/adouwt/p/9928278.html  提到了vue實現的基本實現原理:Object.defineProperty() -資料劫持 和 釋出訂閱者模式(觀察者),下面講的就是資料劫持在程式碼中的具體實現。 1.先看如何呼

    亞馬遜美國站如何收款?亞馬遜派安盈Payoneer收款教程!

    亞馬遜將Payoneer作為亞馬遜賣家平臺裡的推薦收款方式。24個不同國家的賣家能夠使用亞馬遜賣家中心唯一推薦的收款方式——Payoneer來收款,令接收、使用亞馬遜貨款變得前所未有地簡便。如果您已經開通了亞馬遜店鋪、只需新增您的美元收款賬號用於收款。 收款的前期設定非常簡

    每日質量NPM包事件_bindme(React的this)

    一、bindme 官方定義: is a helper to bind a list of methods to an object reference 理解: 因為不推薦在render()裡構建函式,作者就用了6行程式碼封裝了函式繫結事件的程式碼. bindme的npm包實際上由6行ES5程式碼組成,但是確實

    Cdiscount如何收款?Cdiscount派安盈Payoneer收款歐元教程!

    Cdiscount是法國人購物首選的網站之一,日均獨立訪問量為90萬人,每10秒鐘就賣出19個訂單。Cdiscount還將網站上的優質商品精選出來,建立線下實體店,並通過智慧匹配倉庫和消費者的地理距離呈現最快的物流。 您知道嗎?除了大家熟知的亞馬遜,用Payoneer從Cd

    wpf全域性靜態變數mvvm

    原文 wpf繫結全域性靜態變數(mvvm) 在實際的開發中,有一些集合或者屬性可能是全域性的,比如當你做一個oa的時候,可能需要展示所有的人員,這時這個所有的人員列表顯然可以作為全域性引數,比如這裡有一個全域性的靜態屬性UserList。而你在使用mvvm做wpf開發的時候,一般每個view都已經

    七種網絡卡模式

    概覽: 目前網絡卡繫結mode共有七種(0~6)bond0、bond1、bond2、bond3、bond4、bond5、bond6 常用的有三種: mode=0:平衡負載模式,有自動備援,但需要”Switch”支援及設定。 mode=1:自動備援模式,其中一條線若斷線,其他線路將會自動備援。 mod

    centos 6.4系統雙網絡卡配置

    文章出處:http://blog.chinaunix.net/uid-29179844-id-4214001.html Linux雙網絡卡繫結實現就是使用兩塊網絡卡虛擬成為一塊網絡卡(需要交換機支援),這個聚合起來的裝置看起來是一個單獨的乙太網介面裝置,通俗點講就是兩

    VMware虛擬機器Linux雙網絡卡配置

    一、VMware虛擬機器新增一個網路介面卡。 選擇自己需要的模式型別 二、啟動虛擬機器,配置網絡卡 按原先配置網絡卡的方式配置完(ip地址及預設閘道器還有網絡卡名不能跟原先的一樣) 重啟所有網絡卡(service network restart)後檢查網絡卡 三、測試新增網絡卡環境