JackSon默认序列化和反序列化public的属性和getter方法
没有定义某个属性,但是定义了一个get开头的方法,也会根据驼峰命名序列化一个字段,名字是get后面的字段
如果该属性是private的
需要有get方法,才可序列化该属性
需要有set方法,才可反序列化该属性
JackSon反序列化时,默认使用无参构造方法创建对象
@Data
public class UserDetailsImpl implements UserDetails {
private User user;
public Collection<? extends GrantedAuthority> getAuthorities() {return null;}
public String getPassword() {return user.getPassword();}
public String getUsername() {return user.getUsername();}
public boolean isAccountNonExpired() {return true;}
public boolean isAccountNonLocked() {return true;}
public boolean isCredentialsNonExpired() {return true;}
public boolean isEnabled() {return true;}
}
序列化后:(可以看到有的属性并没有定义,但是由于定义了get方法,所以也进行了序列化)
{
"user":[
{
"id":1,
"username":"admin",
"pasword":"$2a$10$ePFsvoad6cOWKfI6eYRijus3EnQUqCyzvtwOAJrSUJsUeQCq1.Guq",
"role":"root",
"createTime":"2022-09-09 17:51:51",
"lastLoginTime":"2022-09-09 17:52:01",
"onlineStatus":0,
"avatar":""
}
],
// 并没有定义下列属性,但是也序列化了出来。
"enabled":true,
"pasword":"$2a$10$ePFsvoad6cOWKfI6eYRijus3EnQUqCyzvtwOAJrSUJsUeQCq1.Guq",
"username":"admin",
"accountNonExpired":true,
"credentialsNonExpired":true,
"accountNonLocked":true,
"authorities":null
}
像这样的JSON数据,当再去反序列化为UserDetailsImpl时,就会报错UnrecognizedPropertyException,因为有些字段在POJO中根本没有定义,所以遇到JSON中的有些字段就会不认识,就会抛异常。
解决办法(两种):
// construct and return a new configuration object instance with specified features disabled.
DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig().withoutFeatures(FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.setConfig(deserializationConfig);
// 或者
// 忽略反序列化不了的字段
// changing state of an on/off deserialization feature
objectMapper.configure(FAIL_ON_UNKNOWN_PROPERTIES,false);
ObjectMapper is the main actor class of Jackson library.
ObjectMapper provides functionality for reading and writing JSON, either to and from basic POJOs, or to and from a general-purpose JSON Tree Model (JsonNode), as well as related functionality for performing conversions.
It is also highly customizable to work both with different styles of JSON content, and to support more advanced Object concepts such as polymorphism and Object identity.
ObjectMapper also acts as a factory for more advanced ObjectReader and ObjectWriter classes.
从POJO转JSON
response.setContentType("application/json; charset=utf-8");
result result = new result(-99, "token错误");
response.getWriter().print(new ObjectMapper().writeValueAsString(result));
从JSON转为POJO
POJO pojo = new ObjectMapper().readValue(json字符串,POJO.class);
Java中类型为Long的字段数据为
1404448588146192386
但是传到前端那里就变成了
1404448588146192400
原因:
后端传Long类型给前端,Long类型数据大于17位时。前端拿到的数据: 第16位会四舍五入,17位后的数据自动用0代替
JavaScript无法处理Java的长整型Long,从而导致精度丢失,具体表现为最后两位永远为0
解决办法:
在序列化时,将Long类型数据序列化为String
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 消息转换器对象
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
// 对象转换器
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule()
.addSerializer(Long.class, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
messageConverter.setObjectMapper(objectMapper);
// 追加到转换器集合当中,并放到最前面
converters.add(0,messageConverter);
}