SpringMvc之參數綁定註解詳解

  在 SpringMVC 中,提交請求的數據是經過方法形參來接收的。從客戶端請求的 key/value 數據,通過參數綁定,將 key/value 數據綁定到 Controller 的形參上,而後在 Controller 就能夠直接使用該形參。html

1、類型支持

  一、默認支持類型

  SpringMVC 有支持的默認參數類型,咱們直接在形參上給出這些默認類型的聲明,就能直接使用了。web

HttpServletRequest 對象正則表達式

HttpServletResponse 對象spring

HttpSession 對象json

Model/ModelMap 對象api

@RequestMapping("/defaultParameter")
    public ModelAndView defaultParameter(HttpServletRequest request,HttpServletResponse response, HttpSession session,Model model,ModelMap modelMap) throws Exception{return null;
    }

  二、基本數據類型

一、byte,佔用一個字節,取值範圍爲 -128-127,默認是「\u0000」,表示空
二、short,佔用兩個字節,取值範圍爲 -32768-32767
三、int,佔用四個字節,-2147483648-2147483647
四、long,佔用八個字節,對 long 型變量賦值時必須加上"L"或「l」,不然不認爲是 long五、float,佔用四個字節,對 float 型進行賦值的時候必須加上「F」或「f」,若是不加,會產生編譯錯誤,由於系統自動將其定義爲 double 型變量。double轉換爲float類型數據會損失精度。
float a = 12.23產生編譯錯誤的,float a = 12是正確的 六、double,佔用八個字節,對 double 型變量賦值的時候最好加上「D」或「d」,但加不加不是硬性規定 七、char,佔用兩個字節,在定義字符型變量時,要用單引號括起來 八、boolean,只有兩個值「true」和「false」,默認值爲false,不能用0或非0來代替,這點和C語言不一樣 
@RequestMapping(value = {"/card"}, method = RequestMethod.GET)
public TravelCard getTravelCard(@RequestParam("amount") long amount) {
    return null;
}

  三、包裝數據類型的綁定

  包裝類型如Integer、Long、Byte、Double、Float、Short,(String 類型在這也是適用的)。數組

  建議全部的參數都用包裝類型,別用原始類型,由於沒法將null轉換爲原始類型,入參不傳遞此參數時則會報錯。cookie

@RequestMapping(value = {"/card"}, method = RequestMethod.GET)
public TravelCard getTravelCard(@RequestParam("amount") Integer amount) {
    return null;
}

  四、POJO(實體類)類型的綁定

@RequestMapping(value = {"/passenger"}, method = RequestMethod.POST)
public long insertOne(@RequestBody Passenger passenger) {
    LOGGER.info("Get a request for insertPassenger(POST).");
    return this.passengerService.insertOne(passenger);
}

2、@RequestMapping註解屬性

  RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的全部響應請求的方法都是以該地址做爲父路徑。RequestMapping註解有六個屬性,下面咱們把她分紅三類進行說明。session

  一、value, method;  

  value:指定請求的實際地址,指定的地址能夠是URI Template 模式(後面將會說明);當只設置value一個屬性時,value能夠省略不寫,當有其餘屬性時則須要加上進行區分。
  method:指定請求的method類型, GET、POST、PUT、DELETE等;app

@RequestMapping("/v1/metro") public class PassengerController {
}

@RequestMapping(value = {"/travel"}, method = RequestMethod.POST) public Map travel(@RequestParam long passengerId,
                   @RequestParam long startStation,
                   @RequestParam long endStation,
                   @RequestParam int cardType) {return null;
}

  value的uri值爲如下三類:

    A) 能夠指定爲普通的具體值;

    B)  能夠指定爲含有某變量的一類值(URI Template Patterns with Path Variables);

    C) 能夠指定爲含正則表達式的一類值( URI Template Patterns with Regular Expressions);

    example B)

@RequestMapping(value = {"/travel/{passengerId}"}, method = RequestMethod.GET)
public List<TravelRecord> queryTravelRecords(@PathVariable("passengerId") long passengerId) {return null;
}

    example C)

@RequestMapping("/spring-web/{symbolicName:[a-z-]+}-{version:\d\.\d\.\d}.{extension:\.[a-z]}")  
public void handle(@PathVariable String version, @PathVariable String extension) {      
    // ...   
}

  二、consumes,produces;

  consumes:指定處理請求的提交內容類型(Content-Type),例如application/json, text/html;

@Controller  
@RequestMapping(value = "/pets", method = RequestMethod.POST, consumes="application/json")  
public void addPet(@RequestBody Pet pet, Model model) {      
    // implementation omitted  
}  

  方法僅處理request的Content-Type爲「application/json」類型的請求。

  produces:指定返回的內容類型,僅當request請求頭中的(Accept)類型中包含該指定類型才返回;

@Controller  
@RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, produces="application/json")  
@ResponseBody  
public Pet getPet(@PathVariable String petId, Model model) {      
    // implementation omitted  
}

  方法僅處理request請求中Accept頭中包含了"application/json"的請求,同時暗示了返回的內容類型爲application/json;

  三、params,headers;

  params:指定request中必須包含某些參數值是,才讓該方法處理。

@Controller  
@RequestMapping("/owners/{ownerId}")  
public class RelativePathUriTemplateController {  
  
  @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue")  
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {      
    // implementation omitted  
  }  
}

  僅處理請求中包含了名爲「myParam」,值爲「myValue」的請求;

  headers:指定request中必須包含某些指定的header值,才能讓該方法處理請求。

@Controller  
@RequestMapping("/owners/{ownerId}")  
public class RelativePathUriTemplateController {  
  
@RequestMapping(value = "/pets", method = RequestMethod.GET, headers="Referer=http://www.ifeng.com/")  
  public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {      
    // implementation omitted  
  }  
}

  僅處理request的header中包含了指定「Refer」請求頭和對應值爲「http://www.ifeng.com/」的請求;

3、參數綁定

  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;

  一、 @PathVariable

  當使用@RequestMapping URI template 樣式映射時, 即 someUrl/{paramId}, 這時的paramId可經過 @Pathvariable註解綁定它傳過來的值到方法的參數上。

@RequestMapping(value = {"/travel/{passengerId}"}, method = RequestMethod.GET)
public List<TravelRecord> queryTravelRecords(@PathVariable("passengerId") long passengerId) {
    return null;
}

  若方法參數名稱和須要綁定的uri template中變量名稱不一致,須要在@PathVariable("name")指定uri template中的名稱。

  二、 @RequestHeader、@CookieValue

  @RequestHeader 註解,能夠把Request請求header部分的值綁定到方法的參數上。

  一個Request 的header部分:

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  
@RequestMapping("/displayHeaderInfo.do")  
public void displayHeaderInfo(@RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive") long keepAlive)  {  
  //...  
  
} 

  @CookieValue 能夠把Request header中關於cookie的值綁定到方法的參數上。

  有以下Cookie值:

@RequestMapping("/displayHeaderInfo.do")  
public void displayHeaderInfo(@CookieValue("JSESSIONID") String cookie)  {  
  //...  
} 

  三、@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) 該註解有3個屬性: value、required、defaultValue; value用來指定要傳入值的id名稱(改變參數名字),required用來指示參數是否必須綁定,defaultValue用於對參數設置默認值,required爲true時,若是參數爲空,會報錯,可是當required=true,和defaultValue= 同時出現時,required失效,可傳可不傳;

@RequestMapping(value = {"/travel"}, method = RequestMethod.POST)
public Map travel(@RequestParam(defaultValue = 1) long passengerId, @RequestParam long startStation, @RequestParam long endStation, @RequestParam(value="card") int cardType) {
    return null;
}

  @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;

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

  由於@RequestBody是將post請求中content值轉爲一個總體對象。@RequestBody的解析有兩個條件:
  1. POST請求中content的值必須爲json格式(存儲形式能夠是字符串,也能夠是byte數組);
  2. @RequestBody註解的參數類型必須是徹底能夠接收參數值的類型,好比:Map,JSONObject,或者對應的JavaBean;因此Integer等類型不能做爲@RequestBody註解的參數類型。

  四、@SessionAttributes, @ModelAttribute

  @SessionAttributes:
  該註解用來綁定HttpSession中的attribute對象的值,便於在方法中的參數裏使用。
  該註解有value、types兩個屬性,能夠經過名字和類型指定要使用的attribute 對象;

@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的示例代碼:

// 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示例代碼:

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

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

4、RequestBody、ResponseBody比較

  @RequestBody
  做用:
    i) 該註解用於讀取Request請求的body部分數據,使用系統默認配置的HttpMessageConverter進行解析,而後把相應的數據綁定到要返回的對象上;
    ii) 再把HttpMessageConverter返回的對象數據綁定到 controller中方法的參數上。
  使用時機:
    A) GET、POST方式提時, 根據request header Content-Type的值來判斷:
      application/x-www-form-urlencoded, 可選(即非必須,由於這種狀況的數據@RequestParam, @ModelAttribute也能夠處理,固然@RequestBody也能處理);
      multipart/form-data, 不能處理(即便用@RequestBody不能處理這種格式的數據);
      其餘格式, 必須(其餘格式包括application/json, application/xml等。這些格式的數據,必須使用@RequestBody來處理);
    B) PUT方式提交時, 根據request header Content-Type的值來判斷:
      application/x-www-form-urlencoded, 必須;
      multipart/form-data, 不能處理;
      其餘格式, 必須;
  說明:request的body部分的數據編碼格式由header部分的Content-Type指定;

  @ResponseBody  做用:     該註解用於將Controller的方法返回的對象,經過適當的HttpMessageConverter轉換爲指定格式後,寫入到Response對象的body數據區。  使用時機:     返回的數據不是html標籤的頁面,而是其餘某種格式的數據時(如json、xml等)使用;

相關文章
相關標籤/搜索