一、文章概述
请求方面主要讲,当前端向后端发出请求时,对于不同类型的参数后端都如何接收;对于响应,文章会讲解后端如何向前端响应数据以及如何使返回的数据具有统一的格式。
二、请求
2.1接收简单参数
Controller方法:
启动后端后,我们使用Postman工具来发出请求:
点击send后,后端接收到了我们发送的数据:
上面的案例中,参数名与形参变量名相同,定义同名的形参即可接收参数,那么当我们定义的形参与参数名不同该怎么办呢?我们需要用到注解@RequestParam和它的属性value:
请求参数名我们保持不变,仅对形参名修改:
我们仍可以接受到正确的参数:
2.2实体参数
当传递参数较多时,我们如果还一个一个的接受就会有些繁琐,这时我们可以将形参定义为一个实体类。要想完成数据封装,需要遵守如下规则:请求参数名与实体类的属性名相同
我们需要先定义一个实体类:
public class User {
private String name;
private int age;
private int gender;
public User() {
}
public User(String name, int age, int gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
/**
* 获取
* @return gender
*/
public int getGender() {
return gender;
}
/**
* 设置
* @param gender
*/
public void setGender(int gender) {
this.gender = gender;
}
public String toString() {
return "User{name = " + name + ", age = " + age + ", gender = " + gender + "}";
}
}
Postman请求数据:
Controller方法:
@RestController
public class UserController {
@RequestMapping("/simplePojo")
public String simplePojo(User user) {
System.out.println("name="+user.getName());
System.out.println("age="+user.getAge());
System.out.println("gender="+user.getGender());
return "OK";
}
}
输出结果如下:
当我们遇到复杂参数时又该怎么办呢?复杂实体参数就是实体中的某些属性也是一个实体对象:
我们给User添加一个address属性,address的实体类定义如下:
public class Address {
private String province;
private String city;
public Address() {
}
public Address(String province, String city) {
this.province = province;
this.city = city;
}
/**
* 获取
* @return province
*/
public String getProvince() {
return province;
}
/**
* 设置
* @param province
*/
public void setProvince(String province) {
this.province = province;
}
/**
* 获取
* @return city
*/
public String getCity() {
return city;
}
/**
* 设置
* @param city
*/
public void setCity(String city) {
this.city = city;
}
public String toString() {
return "Address{province = " + province + ", city = " + city + "}";
}
}
Postman测试数据:
Controller方法:
@RestController
public class RequestController {
@RequestMapping("/simpleParam")
public String hello(@RequestParam(value="name") String username, int age) {
System.out.println(username+" : "+age);
return "OK";
}
}
输出结果如下:
2.3数组集合参数
数组参数
Postman测试数据:
方式一(多个参数同名):
方式二(一个参数赋多个值,值之间用逗号隔开):
Controller方法:
@RestController
public class ArrayController {
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby) {
for(int i=0; i<hobby.length; i++) {
System.out.println(hobby[i]+" ");
}
return "success";
}
}
输出结果:
集合参数
Postman中的测试数据与数组参数相同
Controller方法:
@RestController
public class RequestController {
//数组集合参数
@RequestMapping("/listParam")
//@RequestParam也可以写成@RequestParam(value="hobby")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
}
2.4日期参数
因为日期的格式多种多样(如:2022-12-12 10:05:45 、2022/12/12 10:05:45),那么对于日期类型的参数在进行封装的时候,需要通过@DateTimeFormat注解,以及其pattern属性来设置日期的格式。
Postman中测试数据:
Controller方法:
@RestController
public class DataController {
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime) {
System.out.println(updateTime);
return "OK";
}
}
输出结果:
- @DateTimeFormat注解的pattern属性中指定了哪种日期格式,前端的日期参数就必须按照指定的格式传递。
- 后端controller方法中,需要使用Date类型或LocalDateTime类型,来封装传递的参数。
2.5JSON参数
在前后端进行交互时,如果是比较复杂的参数,前后端通常会使用JSON格式的数据进行传输。 (JSON是开发中最常用的前后端数据交互方式)
Postman中的测试数据:
Controller方法:
@RestController
public class RequestController {
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user) {
System.out.println(user);
return "OK";
}
}
输出结果:
2.6路径参数
这种方式传递参数,也是将参数放在URL后面:
http://localhost:8080/user/1
http://localhost:880/user/1/0
- 前端:通过请求URL直接传递参数
- 后端:使用{…}来标识该路径参数,需要使用@PathVariable获取路径参数
传递一个参数
Postman测试数据:
Controller方法:
参数的前面要加上@PathVariable注解
@RestController
public class RequestController {
@RequestMapping("/path/{id}")
public String path(@PathVariable Integer id) {
System.out.println(id);
return "OK";
}
}
输出结果:
传递多个参数
Postman测试数据:
Controller方法:
@RestController
public class RequestController {
@RequestMapping("/path/{id}/{name}")
public String path(@PathVariable Integer id, @PathVariable String name) {
System.out.println("id="+id);
System.out.println("name="+name);
return "OK";
}
}
输出结果:
三、响应
3.1@RespondBody注解
上面的方法中,我们都返回了“OK”,是可以从Postman中看到它的响应数据的:
其实,要想将数据响应给前端那么是需要@RespondBody注解的,那为什么上面我们并没有写这个注解却可以看到响应的数据?这是因为@RequestController中包含了这个注解,即
@RequestController = @RespondBodey + @RequestController
3.2统一返回格式
后端返回的值各种各样,前端就比较难以处理这些数据,所以我们可以给它们设置一个统一的响应格式,前端只需要按照统一格式的返回结果进行解析(仅一种解析方案),就可以拿到数据。
统一的返回结果使用类来描述,在这个结果中包含:
-
响应状态码:当前请求是成功,还是失败
-
状态码信息:给页面的提示信息
-
返回的数据:给前端响应的数据(字符串、对象、集合)
定义在一个实体类Result来包含以上信息。代码如下:
public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应码 描述字符串
private Object data; //返回的数据
public Result() { }
public Result(Integer code, String msg, Object data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
//增删改 成功响应(不需要给前端返回数据)
public static Result success(){
return new Result(1,"success",null);
}
//查询 成功响应(把查询结果做为返回数据响应给前端)
public static Result success(Object data){
return new Result(1,"success",data);
}
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}
那么我们的Controller方法就可以改为:
@RestController
public class RequestController {
@RequestMapping("/path/{id}/{name}")
public Result path(@PathVariable Integer id, @PathVariable String name) {
System.out.println("id="+id);
System.out.println("name="+name);
return Result.success("OK");
}
}
响应数据如下: