HttpMessageConverter - @RequestBody 和 @ResponseBody 是如何简化开发的

使用 SpringMVC 提供 @RequestBody@ResponseBody 注解可以简化开发。

@RequestBody 简化了哪些流程

Html 标签

1
2
3
<div id="app">
<button @click="jsonRequestBody">发送 JSON 请求体</button>
</div>

Vue + axios 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
new Vue({
el: "#app",
methods: {
jsonRequestBody: function () {
axios({
"method": "post",
"url": "/demo/AjaxServlet",
"data": {
"username": "root",
"password": "123456"
}
}).then(function (response) {
console.log(response.data);
}).catch(function (error) {
console.log(error)
})
},
}
});

Bean 对象代码:

1
2
3
4
5
6
7
8
9
10
11
public class User {

private String username;
private String password;

// no args constructor
// full args constructor
// getter and setter
// toString
}

Servlet 代码:

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
public class AjaxServlet extends HttpServlet {

// ...

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 获取请求的输入流
BufferedReader reader = request.getReader();
// 2. 创建 StringBuilder 对象来累加地存储从请求体中读取到的每一行
StringBuilder builder = new StringBuilder();
// 3. 声明临时变量
String bufferStr = null;
// 4. 循环读取
while((bufferStr = reader.readLine()) != null) {
builder.append(bufferStr);
}
// 5. 关闭流
reader.close();
// 6. 累加的结果就是整个请求体
String requestBody = builder.toString();
// 7. 创建 Gson 对象用于解析 JSON 字符串
Gson gson = new Gson();
// 8. 将 JSON 字符串解析为 Java 对象
User user = gson.fromJson(requestBody, User.class);

System.out.println(user);
}
}

通过以上 1-8 步,我们将请求体中的 JSON 字符串成功转换为了 Java 对象!

在 SpringMVC 中,完成固定的配置(见文末)以后,使用 @RequestBody 注解可以将以上步骤简化到极致:

1
2
3
4
5
6
7
8
@Controller
public class AjaxController {

@RequestMapping(value = "/AjaxServlet")
public void getUser(@RequestBody User user) {
System.out.println(user);
}
}

原生 Servlet API 中的 1-8 步全部不用我们来做了,直接在控制器方法中将 JavaBean 作为形参,并加上 @RequestBody 即可!

@ResponseBody 简化了哪些流程

Html 标签

1
2
3
<div id="app">
<button @click="jsonResponseBody">接收 JSON 响应体</button>
</div>

Vue + axios 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
new Vue({
el: "#app",
methods: {
jsonResponseBody: function () {
axios({
"method": "get",
"url": "/demo/AjaxServlet"
}).then(function (response) {
// response.data 应该是 json 响应体转换后的 js 对象
console.log(response.data);
}).catch(function (error) {
console.log(error)
})
},
}
});

Bean 对象代码:

1
2
3
4
5
6
7
8
9
10
11
public class User {

private String username;
private String password;

// no args constructor
// full args constructor
// getter and setter
// toString
}

Servlet 代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class AjaxServlet extends HttpServlet {

// ...

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1. 准备数据对象
User user = new User();
user.setUsername("root");
user.setPassword("123456");
// 2. 创建 Gson 对象
Gson gson = new Gson();
// 3. 将 Java 对象转换为 JSON 字符串
String json = gson.toJson(user);
// 4. 设置响应体的内容类型
response.setContentType("application/json;charset=UTF-8");
// 5. 将 JSON 字符串写到响应流中
response.getWriter().write(json);
}
}

通过以上 2-5 步,我们将 Java 对象成功转换为了 JSON 字符串,并输出到响应体中。

在 SpringMVC 中,完成固定的配置(见文末)以后,使用 @ResponseBody 注解可以将以上步骤简化到极致:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Controller
public class AjaxController {

@RequestMapping(value = "/AjaxServlet")
@ResponseBody
public User getUser() {
// 1. 准备数据对象
User user = new User();
user.setUsername("root");
user.setPassword("123456");

return user;
}
}

原生 Servlet API 中的 2-5 步全部不用我们来做了,直接在控制器方法中将 JavaBean 对象返回,并在控制器方法上加上 @ResponseBody 即可!

SpringMVC 中 JSON 字符串与 JavaBean 互相转换所需要的固定配置

固定配置包括以下两步,且只需配置一次:

导入 jackson 的依赖

1
2
3
4
5
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>

在 SpringMVC 的核心配置文件中开启 mvc 的注解驱动,此时在 HandlerAdaptor 中会自动装配一个消息转换器:MappingJackson2HttpMessageConverter,可以浏览器的请求过来的 Json 格式的字符串转换为服务器中的 Java 对象

1
<mvc:annotation-driven />