报错内容:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `org.springframework.security.core.authority.SimpleGrantedAuthority` from Array value (token `JsonToken.START_ARRAY`)
redis里存的对应的json格式:
"authorities": [
"java.util.ArrayList",
[
[
"org.springframework.security.core.authority.SimpleGrantedAuthority",
{
"role": "admin",
"authority": "admin"
}
],
[
"org.springframework.security.core.authority.SimpleGrantedAuthority",
{
"role": "common",
"authority": "common"
}
]
]
],
原因: 字符串反序列化是,需要对应的对象有空参构造函数
而SimpleGrantedAuthority是只有有参构造,并且被final修饰不能继承重写
解决办法:
需要对该类进行手动进行反序列化
步骤:
第一步:自定义的反序列化器
public class SimpleGrantedAuthorityDeserializer extends StdDeserializer<SimpleGrantedAuthority> {
public SimpleGrantedAuthorityDeserializer() {
super(SimpleGrantedAuthority.class);
}
@Override
public SimpleGrantedAuthority deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
JsonNode jsonNode = p.getCodec().readTree(p);
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
JsonNode next = elements.next();
JsonNode authority = next.get("authority");
if(ObjectUtils.isEmpty(authority)){
continue;
}
return new SimpleGrantedAuthority(authority.asText());
}
return null;
}
}
第二步:将构造器加入到ObjectMapper 中
@Bean
@ConditionalOnMissingBean(RedisSerializer.class)
@SuppressWarnings("all")
public RedisSerializer<Object> serializer( ObjectMapper objectMapper) {
// 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
//解决jackson2无法反序列化SimpleGrantedAuthority问题(原因是没有空参构造)
objectMapper.registerModule(new SimpleModule().addDeserializer(
SimpleGrantedAuthority.class, new SimpleGrantedAuthorityDeserializer()));
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
return jackson2JsonRedisSerializer;
}
注意: ObjectMapper 不能new ,只能导入全局的,否则其他位置不生效
其他没有空参够够也会出现该问题,也需要注意