關於前后端數據交互與HTTP請求的關系
寫本篇文章的目的是想讓更多前后端聯調的工作變得更清晰明了
HTTP請求的簡單認識
資源地址
協議://域名或者ip:端口/路徑(protocol://host:port/address)
如 "https://www.cnblogs.com/xiaogblog/"
https默認的端口為443,http默認的端口為80
請求方式
方式:get/post/put/patch/delete/head/options/connect/trace,
根據restful風格,我們一般最多用到get/post/put/patch/delete
- get代表從服務器獲取資源
- post代表為服務器添加資源
- put/patch代表修改服務器資源,put更新資源的全部,patch根據資源的局部
- delete代表刪除服務器資源
請求參數
請求參數我們一般成為parameter(簡稱param),它是url問號后面'?key1=value1&key2=value2'的部分,
一般代表請求資源的條件
請求頭
請求頭我們稱為header,一般是一個map結構,記錄請求的一些信息,如Cookie和User-Agent
請求體
請求體我們稱為body,一般存放的是傳遞給后台的數據,
請求頭中有個content-type字段去標識body中數據的編碼方式
- application/x-www-form-urlencoded是表單key-value編碼方式
- application/json是json字符串編碼方式
- ...
請求方式與param和body之間的關系
本質上來說,請求方式與以何種方式發送數據是沒有必然關系的
GET請求既可以發送param數據也可以發送body數據,同理POST及其他請求方式也都可以
但是,一般來說,GET請求方式,參數是規定要放在param中的。
GET請求在某些HTTP請求客戶端是無法攜帶body的,比如java原生java.net.URLConnection,
OkHttpClient,Apache HttpClient和前端jquery ajax都不支持。
但是Android端AsyncHttpClient包和PostMan工具是可以支持GET請求攜帶body的
怎樣進行前后端數據交互
后端以 SpringMVC/SpringBoot 舉例
//數據模型Person類
@Data//lombok
pulic class Person {
private String id;
private String name;
private String address;
private Integer age;
}
//后端接口,為了直觀,省略狀態,直接返回bean
@RestController
@RequestMapping("/person")
public class PersonController {
//Person的Service
@Autowired
private PersonService personService;
//分頁查詢
@GetMapping("/queryByParam")
public List<Person> getStudent(Person person,
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize){
//根據person中不為null的屬性查詢到的Person列表
// pageNum和pageSize為分頁條件,分別代表第幾頁和一頁條數
List<Person> personList = personService.page(person,pageNum,pageSize);
return personList;
}
//新增數據
@PostMapping("/save")
public Person getStudent(@RequestBody Person person){
//往數據庫中插入一條記錄
personService.insert(person);
return person;
}
}
前端以 JQuery AJAX 舉例
//GET分頁查詢
let pageNum = 1,pageSize = 10;//也可以作為data對象的屬性,這里分開
let data = {name:'張三',address:'上海'};
$.ajax({
type : "GET",
url : `http://host:port/person/queryByBody?pageNum=${pageNum}&pageSize=${pageSize}`,
data : data,
dataType:"json",//返回數據類型
success : function(result) {//成功回調
//成功處理
},
error : function(err){//請求失敗
//失敗處理
}
});
//POST新增數據
let person = {
id:"1001",
name:"李四",
address:"北京",
age:18
};
$.ajax({
type : "POST",
url : "http://host:port/person/save",
data : JSON.stringify(person),
dataType:"json",//返回數據類型
contentType: "application/json",//請求的媒體類型
success : function(result) {//成功回調
//成功處理
},
error : function(err){//請求失敗
//失敗處理
}
});
后端Controller層各注解使用(遵循restful風格)
Controller類注解
- Controller類上使用 @RestController 注解,等價與 @Controller + @ResponseBody
- Controller類上最好加上一個 @RequestMapping("/xxx") 代表父級路徑
Controller方法注解
映射地址注解
- @GetMapping 等價於 @RequestMapping(method=RequestMethod.GET) ,代表GET請求數據
- @PostMapping 等價於 @RequestMapping(method=RequestMethod.POST) ,代表POST新增數據
- @PutMapping 等價於 @RequestMapping(method=RequestMethod.PUT) ,代表PUT修改數據
- @DeleteMapping 等價於 @RequestMapping(method=RequestMethod.DELETE) ,代表DELETE刪除數據
參數注解
- @RequestParam
該注解是用於獲取在GET方式中QueryString/param的值,和Content-Type為application/x-www-form-urlencoded的post方式中body data的值。
等同於 javax.servlet.httpHttpServletRequest的getParameter(String name)方法。其中注解參數name/value代表getParameter中的name,
默認值為參數名;required代表參數是否為必須,默認值為true;defaultValue代表參數的默認值
//使用場景一:url中param的key與方法參數名相同且name不是必須時,可省略
@GetMapping("/get")
public Response get(String name){}
//使用場景二:url中param的key與方法參數名相同,但name是必須時,不可省略
@GetMapping("/get")
public Response get(@RequestParam String name){}
//使用場景三:url中param的key與方法參數名不同且不是必須,不可省略
@GetMapping("/get")
public Response get(@RequestParam(name="username",required=false) String name){}
- @PathVariable
該注解代表參數為路徑上的變量
// url為 '/get/1' 時,id="1"
@GetMapping("/get/{id}")
public Response get(@PathVariable String id){}
@GetMapping("/get/{uid}")
public Response get(@PathVariable("uid") String id){}
- @RequestBody
前端發送body數據且contentType為application/json時使用,一般以一個java bean類型去接收,若以String類型接收,則接收到的是json字符串
// jquery ajax 需要使用 JSON.stringify 序列化數據
@PostMapping("/post")
public Response post(@RequestBody Person person){}