关于redis使用Jackson2JsonRedisSerializer序列化,反序列化时权限模块报错的问题
Posted DreamCatcher-qin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于redis使用Jackson2JsonRedisSerializer序列化,反序列化时权限模块报错的问题相关的知识,希望对你有一定的参考价值。
报错内容:
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 ,只能导入全局的,否则其他位置不生效
其他没有空参够够也会出现该问题,也需要注意
java Redis 关于订阅的使用
代码实现
@OnOpen
public void open(Session session, @PathParam(value = "liveid") String liveid,
@PathParam(value = "userid") String userid, @PathParam(value = "name") String name)
this.session = session;
logger.error("进入 " + userid);
socketServers.forEach(client ->
if (client.getUserid().equals(userid))
try
logger.error("重复进入断开 " + userid);
client.getSession().close();
socketServers.remove(new Client(liveid, userid, name, session));
socketServers.add(new Client(liveid, userid, name, session));
return;
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
);
socketServers.add(new Client(liveid, userid, name, session));
subscribeListener = new SubscribeListener();
subscribeListener.setSession(session);
subscribeListener.setUserid(userid);
subscribeListener.setName(name);
subscribeListener.setStringRedisTemplate(redisTampate);
channeltopic=new ChannelTopic(liveid);
//设置订阅topic
redisMessageListenerContainer.addMessageListener(subscribeListener,channeltopic);
取消某个订阅
if(subscribeListener!=null)
redisMessageListenerContainer.removeMessageListener(subscribeListener);
subscribeListener=null;
以上是关于关于redis使用Jackson2JsonRedisSerializer序列化,反序列化时权限模块报错的问题的主要内容,如果未能解决你的问题,请参考以下文章
关于python语言使用redis时,连接是否需要关闭的问题