@PathVariable
作用:@PathVariable
是spring3.0的一個新功能:接收請求路徑中占位符的值,將URL中占位符參數{xxx}
綁定到處理器類的方法形參中@PathVariable(“xxx“)
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar(@PathVariable("id") Integer id,
@PathVariable("username") String name,
) {
Map<String,Object> map = new HashMap<>();
map.put("id",id);
map.put("name",name);
return map;
}
請求參數示例:http://localhost:8080/car/2/owner/birdy
上面的例子有多個占位符,形參列表需要定義多個參數,不是很方便,可以直接定義一個map集合 @PathVariable Map<String,String> kv
,會自動映射多個參數
@GetMapping("/car/{id}/owner/{username}")
public Map<String,Object> getCar( @PathVariable Map<String,String> kv) {
Map<String,Object> map = new HashMap<>();
String id = kv.get("id");
String name = kv.get("username");
map.put("id",id);
map.put("name",name);
return map;
}
@RequestParam
@RequestParam主要用於將請求參數區域的數據映射到控制層方法的參數上
語法:
@RequestParam(value=”參數名”,required=”true/false”,defaultValue=””)
value
:請求中傳入參數的名稱,即前端傳過來時定義的參數名。如果不設置value值,
則前端定義的參數名必須和后端接口參數名相同required
:該參數是否為必傳項。默認是true,表示請求中一定要傳入對應的參數,否則會報404錯誤;如果設置為false,當請求中沒有此參數,將會默認為null。而對於基本數據類型的變量,則必須有值,這時會拋出空指針異常。如果允許空值,則接口中變量需要使用包裝類來聲明。defaultValue
:參數的默認值,如果請求中沒有同名的參數時,該變量默認為此值。注意默認值可以使用SpEL表達式,如"#{systemProperties['java.vm.version']}"
@GetMapping("/user")
public Map<String,Object> getUser(@RequestParam("age") Integer age,
@RequestParam("inters") List<String> inters,
) {
Map<String, Object> map = new HashMap<>();
map.put("age",age);
map.put("inters",inters);
return map;
}
請求示例:http://localhost:8080/user?age=18&inters=game&inters=music
返回結果:{"inters":["game","music"],"age":18}
@RequestParam
同樣可以定義集合類型參數 @RequestParam Map<String,String> params
來映射多個參數
@RequestBody
作用:@RequestBody主要用來接收前端傳遞給后端的json字符串中的數據的(請求體中的數據的)
注意點:
- GET方式無請求體,所以使用@RequestBody接收數據時,前端不能使用GET方式提交數據,而是用POST方式進行提交
- 在后端的同一個接收方法里,@RequestBody與@RequestParam()可以同時使用,@RequestBody最多只能有一個,而@RequestParam()可以有多個
- 如果參數時放在請求體application/json傳入后台的話,那么后台要用@RequestBody才能接收到
- 如果不是放在請求體中的話,那么后台接收前台傳過來的參數時,要用@RequestParam來接收,或者形參前 什么也不寫也能接收
在實際的工作需求中,寫接口的人會經常遇到對於Bean各種各樣的操作,比如我對數據庫要寫個Bean,返回前台還得有個Vo bean,在另一個需求又用到和這個類似的Bean了,但是就有些字段不一樣啊,字段的有些類型不一樣啊,接收的參數名不一樣啊,反正就是一個小小的需求變動,可能就需要寫好幾個不同的Bean,之前需求沒那么多的時候寫兩個就寫兩個吧,后來寫的多了就煩了,所以認真研究下怎么轉換就迫在眉睫了。
@JsonAlias
作用是在反序列化的時候可以讓Bean的屬性接收多個json字段的名稱。可以加在字段上或者getter和setter方法上。
@Data
public class User implements Serializable{
@JsonAlias({"name","user"})
private String username;
private String password;
private Integer age;
}
實體類需要有get和set方法
@PostMapping("/user")
public User getUserIfo(@RequestBody User user){
return user;
}
路徑
:http://localhost:8080/user
//入參
{
“name” : “小明”,
“password” : “123”,
"age" : 15
}
可以從下面看到json字段是name也成功對應到了Bean的username屬性 ,但是字段名沒變
//postman返回結果
{
"username": "birdy",
"password": "123",
"age": 18
}
@JsonProperty
向流中寫入對象的操作 稱為 序列化
從流中讀取對象的操作 成為 反序列化
這個注解是更改Bean字段的屬性名用的。
- access:是更改邏輯屬性序列化和反序列化的可見性,
Access.WRITE_ONLY:只在序列化時使用修改后的字段
Access.READ_ONLY:只在反序列化時使用,類似於@JsonAlias注解
Access.READ_WRITE:在序列化和反序列化都使用修改后字段
Access.AUTO:自動確定,一般是和第三個一樣,啥情況不一樣我也不清楚,如果不寫access,默認就是這個。
value是邏輯屬性的名稱,如果只有value則省略
- value::更改后的屬性名
示例
@Data
public class User implements Serializable {
//只在序列化寫入操作時使用該屬性名
@JsonProperty(value = "name", access = JsonProperty.Access.WRITE_ONLY)
private String username;
private String password;
private Integer age;
}
@PostMapping("/user")
public User getUserIfo(@RequestBody User user){
System.out.println(user.toString());
return user;
}
入參:
{
"name" : "birdy",
"password" : "123",
"age" : 18
}
結果:
//console
User(username=birdy, password=123, age=18)
//postman沒有獲取到name屬性
{
"password": "123",
"age": 18
}
查看源碼
Access setting that means that the property may only be written (set) as part of deserialization (using "setter" method, or assigning to Field
表示只有在寫入時調用屬性的set方法才會用該屬性名
猜猜若改成@JsonProperty(value = "name", access = JsonProperty.Access.READ_ONLY)
會怎樣?
//控制台
User(username=null, password=123, age=18)
//postman
{
"password": "123",
"age": 18,
"name": null
}
由於寫入時無法調用set方法賦值,所以控制台打印該屬性時沒有值;但是返回結果已經可以調用修改后的屬性get方法,所以username屬性已經被修改為name,只是沒有值
若是access = JsonProperty.Access.AUTO
//控制台
User(username=birdy, password=123, age=18)
//postman
{
"password": "123",
"age": 18,
"name": birdy
}
可以看到控制台打印的屬性名稱都沒有變,access只影響屬性在序列化和反序列化時的名稱