关于前后端数据交互与HTTP请求的关系
关于前后端数据交互与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){}