1、說明
springboot 是國內最常用的web框架,因為它的http server功能是最重要的。本文列舉了一些現在通用的restful形式的接口所需要的注解
2、@RequestMapping
@RequestMapping 注解用於請求地址的解析,是最常用的一種注解
源碼如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
- @Target 表示,此注解可以用在類和方法上;
- @Retention(RetentionPolicy.RUNTIME) 表示,測注解保留到程序運行時,即程序運行時此注解有效;
該注解的參數如下:
2.1、name
為映射設置名稱
2.2、path和value
-
path ,顧名思義,運行時,它能夠得到地址;
-
該屬性是一個字符串數組,表示,可以同時映射多個地址;
而之所以把path和value寫在一起,是因為這兩個屬性的作用的相同的。可以看到,這兩個屬性都使用spring的注解 @AliasFor 互相修飾,表示這兩個屬性互為別名
這里之所以使用 value 屬性,是因為,java注解中,如果有多個屬性,而使用時,又不指定參數名,則默認傳遞給 value 熟悉。所以,這里使用別名的作用是,使用時可以不使用屬性名,直接使用值來表示地址
spring框架中的注解都會有value屬性
@RequestMapping("/index")
public String index(){
return "hello";
}
如上例,表示,“/index” 以為沒有指定屬性名,屬於傳遞給了value屬性,也就是path屬性
2.2.1、@pathVariable
使用path映射url的path,但是對於同一個類型的url,只是path不同,但是處理方式不一樣,如果各自寫一個方法的話,就顯得很多余了,所以可以使用path變量
-
變量使用中括號修飾,配合注解 @PathVariable 一起使用,可以得到傳入的path;
-
這里還可以使用正則表達式對變量允許的值進行過濾;
示例:
@RequestMapping(value="/index/{name}")
public String index(){
return "bbb";
}
上例中,可以映射path為 /index/xxxx 等的url
@RequestMapping(value="/index/{name:[a-z]}")
public String index(){
return "bbb";
}
上例中,使用了正則表達式,[a-z] 表示a-z的一個字符,所以,只能映射/index/a等,二級目錄只是一個字母的url
2.3、method
故名思議,表示,http請求使用的方法,它的類型是 RequestMethod 數組,RequestMethod 是一個枚舉,源碼如下:
public enum RequestMethod {
GET,
HEAD,
POST,
PUT,
PATCH,
DELETE,
OPTIONS,
TRACE;
private RequestMethod() {
}
}
可以看到,它是包含一系列HTTP方法的枚舉類型
而類型是數組表示,它可以指定該接口/類可以監聽多種方法
2.4、params和header
params 參數用於過濾請求,根據該參數值,只將符合條件的請求傳遞到該方法/類中
如果有多個參數,則參數之間是 與 的關系
示例:
@RequestMapping(value="/index", params = "age=12")
public String index(){
return "bbb";
}
@RequestMapping(value="/index", params = {"age=13,name=ab"})
public String index2(){
return "ccc";
}
上例中,index() 映射請求中,參數age為12的請求
index2() 方法映射請求中,參數age為13且name為ab的請求
headers 參數的效果和 params 類似,區別是header 過濾的是HTTP協議中的header參數
示例:
@RequestMapping(value="/index", headers="content-type=text/html")
public String index2(){
return "aaa";
}
2.5、consumes和produces
consumes 用於過濾請求內容類型(Content-Type 值)
produces 用於指定返回值類型
Content-Type 在HTTP協議的消息頭中用於表示資源的媒體類型,consumes 的作用就是根據參數過濾
@RequestMapping(value = "/index", consumes = "application/json")
public String index3(){
return "aaa";
}
3、@PathVariable
@PathVariable 用於接口的參數獲取
在上文的2.2.1中,path變量配合此注解,可以得到傳入的path
@PathVariable 只有name和value兩個參數,互為別名,使用時需要傳入一個name
示例:
@RequestMapping(value="/index/{name}")
public String index(@PathVariable("name") String myName){
return "bbb";
}
@PathVariable 的參數 name 的要和 @RequestMapping 的 path 參數中的path變量一致
上例中,myName 參數的值為url的二級path
4、@RequestParam
@RequestParam 用於 通過接受表單形式的參數,即傳入的參數必須可以是拼接在URL后面的key-value,也可以是body里面的表單形式的key-value
源碼如下:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default true;
String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
可見,@RequestParam 特性如下:
- 需要傳三個參數:name/value、required和defaultValue,name表示參數名,reuqired表示此參數是否必須傳入,defaultValue表示默認值;
- 若不指定默認值,則未傳的參數會設為nul;
示例1:url 傳參
@RequestMapping(value="/index")
public String index(@RequestParam("name") Integer name){
return "bbb";
}
需要注意的是,如果參數類型設置為基本的數據類型,而請求又沒有傳參的話,會報錯,因為基本數據類型沒有null類型,所以使用Java包裝類即可
示例2:body中form形式的傳參
需要注意的是,HTTP協議body中傳參的形式有多種,這里需要分別處理
默認接受以文本的形式傳遞的參數,也有的軟件叫 raw
若傳參的形式不同,接口需要設置 HTTP 協議頭的 Content-Type 的值來接受參數,即,spring 中使用 @RequestMapping 的 consumes 屬性
@RequestMapping(value="/index2",
consumes="application/x-www-form-urlencoded")
public String index2(
@RequestParam("name") String myName,
@RequestParam("age") Integer age){
return "bbb";
}
這里使用了 key-value 鍵值對的表單形式,@RequestParam 可以忽略,簡化成如下代碼,效果相同
@RequestMapping(value="/index2",
consumes="application/x-www-form-urlencoded")
public String index2(String name, Integer age){
return "bbb";
}
但是,如果參數過多,則函數的參數列表就會很長,所以這里可以封裝成一個類
public class People {
private Integer id;
private String name;
private Integer age;
//忽略getter和setter
}
@RequestMapping(value="/index2",
consumes="application/x-www-form-urlencoded")
public String index2(People people){
return "bbb";
}
並且,此時無需使用注解,spring 會自動拼裝類
5、@RequestBody
@RequestBody 接受的body內的單一參數,即非表單形式的參數,因為,其也就不能接收GET方法的傳參了
其源碼如下:
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
boolean required() default true;
}
@RequestBody 有一個屬性 required,默認true,表示單一參數是否必須傳入
示例1:
raw 的方式
@RequestMapping(value="/index")
public String index(@RequestBody String requestParam){
return "bbb";
}
上例中,可以接受到以raw方式傳遞的參數
示例2:
x-www-form-urlencoded 的方式
x-www-form-urlencoded 是一種把表單數據編碼成單一數據的格式,所以可以使用 @RequestBody 來獲取
@RequestMapping(value="/index2", consumes="application/x-www-form-urlencoded")
public String index2(@RequestBody String requestParam){
return "bbb";
}
示例3:
@RequestBody 能夠將單一形式的參數轉換成Java類,這需要參數的key和java類的屬性一對一相同,不同的屬性則設置為null
@RequestMapping(value="/index")
public String index(@RequestBody Product product){
return "aaa";
}
如上,執行后,controller 內的參數能夠自動解析raw方式的傳參
6、@ResponseBody
@ResponseBody 注解的作用是將 java 對象轉換位 json 格式的數據
聲明如下:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
由此可知
- 該注解可以用在類和方法上;
- 程序運行時有效;
- 無參數屬性;
@ResponseBody 注解可以將 controller 方法返回的 java 對象通過適當的轉換器轉換成指定的格式,並返回到 http response 的 body 區內,通常返回 json 和 xml
使用該注解后,不會走視圖處理器,而是直接將數據寫入到流中,效果等同於使用 response 對象輸出指定格式的數據