spring - Spring HttpMessageConverter 如何将请求正文解析为我定义的模型
问题描述
我有点好奇spring是如何处理这个问题的,我做了一些实验。这是我的请求处理方法:
@PostMapping(value = "/testRequestBody")
public String testRequestBody(@RequestBody MyRequestBody requestBody) {
System.out.println(requestBody);
return "Success";
}
我尝试了三种类型的MyRequestBody
.
类型 1:
public class MyRequestBody {
private int id;
private String name;
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "MyRequestBody(id="+id+",name="+name+")";
}}
类型 2:
public class MyRequestBody {
private int id;
private String name;
public MyRequestBody(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "MyRequestBody(id="+id+",name="+name+")";
}}
类型 3:
public class MyRequestBody {
private int id;
private String name;
public String toString() {
return "MyRequestBody(id="+id+",name="+name+")";
}}
Type 1 和 Type 2 我都可以MyRequestBody(id=1,name=test name)
在控制台中输入{"id": 1,"name": "test name"}
,Type 3 给我MyRequestBody(id=0,name=null)
。似乎 Spring 能够根据如何为我的模型定义 setter 和构造函数来选择不同的方式来解析我的模型。我想知道Spring是如何实现的?
解决方案
MappingJackson2HttpMessageConverter委托给 Jackson,将 json 转换为 java 对象的工作。因此,您所看到的行为可以用杰克逊遵循的规则来解释。
以下是 Jackson 执行的操作的简化序列,它解释了您在三个MyRequestBody
定义中看到的行为。
类的对象是通过调用构造函数来创建的。如果构造函数接受参数,则参数的值取自 json 字符串。以下是决定应该调用哪个构造函数的规则。
如果有一个用 注释的
@JsonCreator
构造函数,则调用该构造函数。如果没有注释的构造函数
@JsonCreator
- 如果只有一个构造函数,则调用该构造函数。这可以是参数化构造函数或默认构造函数。
- 如果有多个构造函数,包括默认构造函数,则调用默认构造函数。
- 在其他情况下,会引发异常。
- 通过调用 setX() 方法设置字段值。
Java 反射用于检查构造函数/方法并调用它们。
所以,在你的情况下
- 对于第一个 RequestBody 定义,调用默认构造函数并调用 setX() 方法。
- 对于第二个 RequestBody 定义,调用参数化构造函数(没有默认构造函数)
- 调用默认构造函数。
推荐阅读
- php - ErrorException 未定义变量 $k1
- java - VideoView 自定义媒体控制器
- snowflake-cloud-data-platform - 雪花时间旅行数据不可用
- python - Pyomo:在每一步之后打印目标值
- python - Shopify API 订单在几次 POST 请求后抛出 429 状态代码(请求过多)
- reactjs - ReactJS:如何切换开关以更改 Web App 的背景?
- typescript - vue typescript emit - 在父级中获取值
- angular - 发出事件后如何更改可观察对象的值?
- node.js - 不能在前端 hbs 或 html 文件中包含 node_modules 文件
- python - 当在 done_callback 中引发异常时,任务不会从异步循环中删除