先说结论:
项目中定制了spring 的redisTemplate,而这个template没有使用我自定义的Jackson ObjectMapper。所以不生效。
下面是详细过程:
起因是spring boot项目加入了shiro,我打算使用redis去存储shiro的会话,方便以后横向扩展。
参考了网上的实现后,决定通过扩展org.apache.shiro.session.mgt.eis.AbstractSessionDAO来实现。
以下是实现代码:
1 package com.ceiec.baseplatform.config; 2 3 import com.ceiec.baseplatform.redis.StringKeyRedisTemplate; 4 import org.apache.commons.collections.CollectionUtils; 5 import org.apache.shiro.session.Session; 6 import org.apache.shiro.session.UnknownSessionException; 7 import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; 8 import org.slf4j.Logger; 9 import org.slf4j.LoggerFactory; 10 import org.springframework.beans.factory.annotation.Autowired; 11 import org.springframework.stereotype.Component; 12 13 import java.io.Serializable; 14 import java.util.Collection; 15 import java.util.concurrent.TimeUnit; 16 17 @Component 18 public class RedisSessionDAO extends AbstractSessionDAO { 19 private static Logger logger = LoggerFactory.getLogger(RedisSessionDAO.class); 20 21 @SuppressWarnings("rawtypes") 22 @Autowired 23 private StringKeyRedisTemplate<String, Object> redisTemplate; 24 25 private static final String DEFAULT_SESSION_KEY_PREFIX = "shirosession:"; 26 27 private String keyPrefix = DEFAULT_SESSION_KEY_PREFIX; 28 29 private long expireTime = 120000; 30 31 public RedisSessionDAO() { 32 super(); 33 } 34 35 public RedisSessionDAO(long expireTime) { 36 super(); 37 this.expireTime = expireTime; 38 } 39 40 @Override // 更新session 41 public void update(Session session) throws UnknownSessionException { 42 System.out.println("===============update================"); 43 if (session == null || session.getId() == null) { 44 return; 45 } 46 session.setTimeout(expireTime); 47 String key = getKey(session); 48 redisTemplate.opsForValue().set(key, session, expireTime, TimeUnit.MILLISECONDS); 49 } 50 51 private String getKey(Session session) { 52 return this.keyPrefix + String.valueOf(session.getId()); 53 } 54 private String getSessionIdKey(String sessionId) { 55 return this.keyPrefix + String.valueOf(sessionId); 56 } 57 58 @Override // 删除session 59 public void delete(Session session) { 60 System.out.println("===============delete================"); 61 if (null == session) { 62 return; 63 } 64 redisTemplate.opsForValue().getOperations().delete(getKey(session)); 65 } 66 67 @Override 68 // 获取活跃的session,可以用来统计在线人数,如果要实现这个功能,可以在将session加入redis时指定一个session前缀,统计的时候则使用keys("session-prefix*")的方式来模糊查找redis中所有的session集合 69 public Collection<Session> getActiveSessions() { 70 // System.out.println("==============getActiveSessions================="); 71 // return redisTemplate.keys("*"); 72 return CollectionUtils.EMPTY_COLLECTION; 73 } 74 75 @Override// 加入session 76 protected Serializable doCreate(Session session) { 77 System.out.println("===============doCreate================"); 78 Serializable sessionId = this.generateSessionId(session); 79 this.assignSessionId(session, sessionId); 80 81 redisTemplate.opsForValue().set(getKey(session), session, expireTime, TimeUnit.MILLISECONDS); 82 return sessionId; 83 } 84 85 @Override// 读取session 86 protected Session doReadSession(Serializable sessionId) { 87 System.out.println("==============doReadSession================="); 88 if (sessionId == null) { 89 return null; 90 } 91 return (Session) redisTemplate.opsForValue().get(getSessionIdKey(String.valueOf(sessionId))); 92 } 93 94 public long getExpireTime() { 95 return expireTime; 96 } 97 98 public void setExpireTime(long expireTime) { 99 this.expireTime = expireTime; 100 } 101 102 103 }