前言

介绍SpringBoot请求响应的相关操作。

版本:

  • Maven:3.6.1
  • JDK:17
  • SpringBoot:3.3.2
  • API测试工具:Postman

Controller

首先在项目下建立一个controller.RequestController

编写RequestController请求处理类,在其中编写一个hello()方法:

1
2
3
4
5
6
7
8
//请求处理类
@RestController
public class RequestController {
@RequestMapping("/hello")
public String hello() {
return "收到请求并返回值";
}
}

说明:

  • 注解@RestController标识该类为一个请求处理类(标识该类为 RESTful 风格的控制器组件,专门用于处理 HTTP 请求并返回数据)

    注解@RestController源码中包含@Controller以及@ResponseBody

  • 注解@RequestMapping是一个用来处理请求地址映射的注解,可用于映射一个请求或一个方法,可以用在类或方法上。

访问http://localhost:8080/hello发送请求,收到返回结果:

请求

SpringBoot可以同时处理GET请求和POST请求,以下说明均以POST请求作为说明。

简单参数

编写simpleParams()方法:

1
2
3
4
5
@RequestMapping("/simpleParams")
public String simpleParams(String name, Integer age) {
String result = name + "-" + age;
return "收到请求并返回:\n" + result;
}

注意:建议整型使用Integer而非int,因为使用Integer的默认值是null,使用int的默认值是0(出错时会影响判断)

要求请求参数名与方法形参变量名相同,即可接收参数:

  • POST请求:

说明:

服务器只接收与方法形参变量名相同的参数,如果参数名错误或者数量不匹配,服务器不会报错,但错误的参数均不会被接收。

使用注解@RequestParam可以指定接收的参数名

1
2
3
4
5
@RequestMapping("/simpleParams")
public String simpleParams(@RequestParam(name = "NameStr") String name, @RequestParam(value = "Age") Integer age) {
String result = name + "-" + age;
return "收到请求并返回:\n" + result;
}

注意:

  • @RequestParam中的参数可以使用namevalue
  • @RequestParam中的required属性默认为true,表示该请求参数必须正确传递,否则将报错。
  • POST请求:

  • 错误请求:

实体参数

简单实体参数

SpringBoot可以直接将接收到的参数自动封装为一个对象实体。

首先在项目下建立一个pojo.user实体类(JavaBean),在其中创建nameage变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class User {
private String name;
private Integer age;

public User() {
}

public User(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String toString() {
return "User{name = " + name + ", age = " + age + "}";
}
}

编写simplePojo()方法:

1
2
3
4
@RequestMapping("/simplePojo")
public String simplePojo(User user) {
return "收到请求并返回:\n" + user;
}

该方法可以直接写User类型的参数,请求参数名需要与User类中的属性名相同,该方法可以自动将其封装为一个user对象。

  • POST请求:

复杂实体参数

首先在项目下建立一个pojo.Address实体类(JavaBean),在其中创建provincecity属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
public class Address {
private String province;
private String city;

public Address() {
}

public Address(String province, String city) {
this.province = province;
this.city = city;
}

public String getProvince() {
return province;
}

public void setProvince(String province) {
this.province = province;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String toString() {
return "Address{province = " + province + ", city = " + city + "}";
}
}

修改User类,使其增加一个Address类型的变量:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class User {
private String name;
private Integer age;
private Address address;


public User() {
}

public User(String name, int age, Address address) {
this.name = name;
this.age = age;
this.address = address;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Address getAddress() {
return address;
}

public void setAddress(Address address) {
this.address = address;
}

public String toString() {
return "User{name = " + name + ", age = " + age + ", address = " + address + "}";
}
}

编写complexPojo()方法:

1
2
3
4
@RequestMapping("/complexPojo")
public String complexPojo(User user) {
return "收到请求并返回:\n" + user;
}

此时的请求参数可按照对象层次结构关系构建,例如:address.province

  • POST请求:

数组集合参数

数组参数

例如多选表单的场景,一个参数名可以有多个值,此时可以在方法中用数组类型的参数进行接收。

编写arrayParams()方法:

1
2
3
4
@RequestMapping("/arrayParams")
public String arrayParams(String[] hobby) {
return "收到请求并返回:\n" + Arrays.toString(hobby);
}

多个请求参数名需与方法形参变量名相同

  • POST请求:

集合参数

SpringBoot还可以将多个同名参数封装到一个集合对象中去。

编写listParams()方法:

1
2
3
4
@RequestMapping("/listParams")
public String listParams(@RequestParam List<String> hobby) {
return "收到请求并返回:\n" + hobby;
}

说明:

需要在方法参数前添加注解@RequestParam绑定参数关系,否则默认将多个同名参数添加到数组中。

多个请求参数名需与方法形参变量名相同

  • POST请求:

日期参数

可以直接将日期时间参数封装到LocalDateTime类的对象中。

编写dateParams()方法:

1
2
3
4
@RequestMapping("/dateParams")
public String dateParams(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")LocalDateTime time) {
return "收到请求并返回:\n" + time;
}

说明:

需要在方法参数前添加注解@DateTimeFormat用于指定接收的日期时间格式

请求参数名需与方法形参变量名相同,请求的时间参数格式需与方法指定的日期时间格式相同

  • POST请求:

JSON参数

SpringBoot可以通过实体对象接收JSON类型的参数,将参数自动封装为对象。

编写jsonParams()方法:

1
2
3
4
@RequestMapping("/jsonParams")
public String jsonParams(@RequestBody User user) {
return "收到请求并返回:\n" + user;
}

说明:

需要在方法参数前添加注解@RequestBody

请求参数中json数据的键名需与方法形参对象中的属性名相同

  • POST请求:

路径参数

通过URL直接传递参数,参数是请求路径本身的一部分。

编写pathParams()方法:

1
2
3
4
@RequestMapping("/path/{id}/{name}")
public String pathParams(@PathVariable Integer id, @PathVariable String name) {
return "收到请求并返回:\n" + id + ":" + name;
}

说明:

  • 此时在@RequestMapping中就不能把路径写死,需要通过{param}语法来标识路径参数
  • 需要在方法参数前添加注解@PathVariable来获取路径参数,参数名需与路径参数名一致

请求参数名需与方法形参变量名相同

  • GET请求:

响应

SpringBoot可以返回任意类型的数据,但是前端分别处理不同类型的数据很麻烦,因此需要一个统一的响应格式。

可以考虑使用一个Result实体对象进行结果响应,其中主要包含:code(响应码)、msg(提示信息)、data(返回的数据),然后将这个Result实体对象进行返回(SpringBoot会自动将实体对象类型转化为JSON数据格式)

首先在项目下建立一个pojo.Result实体类(JavaBean),在其中创建codemsgdata属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Result {
private Integer code;
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 static Result success(Object data) {
return new Result(1, "success", data);
}

public static Result success() {
return new Result(1, "success", null);
}

public static Result error(String msg) {
return new Result(0, msg, null);
}

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 String toString() {
return "Result{code = " + code + ", msg = " + msg + ", data = " + data + "}";
}
}

除了基本的构造方法,还编写了几个静态方法用于快速编写返回对象:

1
2
3
4
5
6
7
8
9
10
11
public static Result success(Object data) {
return new Result(1, "success", data);
}

public static Result success() {
return new Result(1, "success", null);
}

public static Result error(String msg) {
return new Result(0, msg, null);
}

响应示例

编写response1()方法:

1
2
3
4
@RequestMapping("/response1")
public Result response1() {
return Result.success(); //直接调用编写的success()静态方法
}
  • GET请求:

编写response2()方法:

1
2
3
4
5
6
7
8
9
@RequestMapping("/response2")
public Result response2() {
ArrayList<User> list = new ArrayList<>();
User user1 = new User("张三", 18, new Address("四川", "成都"));
User user2 = new User("李四", 20, new Address("浙江", "杭州"));
list.add(user1);
list.add(user2);
return Result.success(list);
}
  • GET请求:

编写response3()方法:

1
2
3
4
@RequestMapping("/response3")
public Result response3() {
return Result.error("请求错误");
}
  • GET请求:


后记

之前一直用python的flask框架,相比之下感觉SpringBoot的响应请求实现更加简单。