spring-mvc默认jackson对象序列化解析问题
Controller层方法使用@ResponseBody时,默认使用jackson解析Bean对象并返回json字符串
案例
实体类
User
public class User {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
User 1
改变get方法
getName ====> getUserName
getAge ====> getUserAge
public class User1 {
private String name;
private Integer age;
public String getUserName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getUserAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
User 2
新增getUserName,getUserAge方法
public class User2 {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getUserName() {
return name;
}
public Integer getUserAge() {
return age;
}
}
Controller层
@RestController
@RequestMapping("/springmvc-json-test")
public class BasicController {
@GetMapping("/user")
public User user() {
User user = new User();
user.setName("guoyg");
user.setAge(666);
return user;
}
@GetMapping("/user1")
public User1 user1() {
User1 user1 = new User1();
user1.setName("guoyg");
user1.setAge(666);
return user1;
}
@GetMapping("/user2")
public User2 user2() {
User2 user2 = new User2();
user2.setName("guoyg");
user2.setAge(666);
return user2;
}
}
访问结果
/user
{
"name": "guoyg",
"age": 666
}
/user1
{
"userName": "guoyg",
"userAge": 666
}
/user2
{
"name": "guoyg",
"age": 666,
"userName": "guoyg",
"userAge": 666
}
相同属性但由于getter方法不同,导致返回json不同
原理
以User1为例
- jackson在解析Bean对象时,com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector#collectAll()方法会收集Bean对象的所有字段和getter,setter方法对应的隐含属性名保存到prop列表中。
prop:[name,age,userName,userAge] - 然后会移除prop列表中没有getter方法对应的字段。
prop:[userName,userAge] - 使用BeanSerializer对Bean对象进行解析,即为prop列表中的字段进行赋值。