shiro 不完全学习笔记-----------4

shiro过滤器及会话管理

一.shiro过滤器

  anon   不需要任何的认证就可以访问                             user        当前存在用户才可以访问

  authc   需要认证后才可以访问                                       logout    退出

  authBasic (http认证?  说太快了 听不清啊)

和授权 相关的过滤器

  perms[  ]   拥有某些权限才可以访问                     roles[  ]  具有某些角色才可以访问

  ssl              要求协议是什么                                   port      要求访问的端口号


二。会话管理将session交给redis管理

 思路 重写sessionDao  在sessionDao中对session进行增删改查操作   ----redis

sessionDao

public class RedisSession extends AbstractSessionDAO {

    @Autowired
    private JedisUtil jedisUtil;

    private final String SHIRO_SESSION_PREFIX = "redis_session:";

    private byte[] getKey (String key) {
        return (SHIRO_SESSION_PREFIX + key).getBytes();
    }

    private void savaSession(Session session) {
        if (session != null && session.getId() != null) {
            byte[] key = getKey(session.getId().toString());
            byte[] value = SerializationUtils.serialize(session);
            jedisUtil.set(key, value);
            jedisUtil.expire(key, 600);
        }
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        savaSession(session);
        return sessionId;
    }

    @Override
    protected Session doReadSession(Serializable serializable) {
        System.out.println("read session");
        if (serializable == null) {
            return null;
        }
        byte[] key = getKey(serializable.toString());
        byte[] value = jedisUtil.get(key);
        return (Session) SerializationUtils.deserialize(value);
    }

    @Override
    public void update(Session session) throws UnknownSessionException {
        savaSession(session);
    }

    @Override
    public void delete(Session session) {
        if (session == null || session.getId() == null) {
            return;
        }
        byte[] key = getKey(session.getId().toString());
        jedisUtil.del(key);
    }

    @Override
    public Collection<Session> getActiveSessions() {
        Set<byte[]> keys = jedisUtil.keys(SHIRO_SESSION_PREFIX);
        Set<Session> sessions = new HashSet<Session>();
        if (CollectionUtils.isEmpty(keys)) {
            return sessions;
        }
        for (byte[] key : keys) {
            Session session = (Session) SerializationUtils.deserialize(jedisUtil.get(key));
            sessions.add(session);
        }
        return sessions;
    }
}

redis工具类

@Component
public class JedisUtil{

    @Autowired
    private JedisPool jedisPool;

    private Jedis getResource() {
        return jedisPool.getResource();
    }

    public byte[] set(byte[] key, byte[] value) {
        Jedis jedis = getResource();
        try {
            jedis.set(key, value);
            return value;
        } finally {
            jedis.close();
        }
    }

    public void expire(byte[] key, int i) {
        Jedis jedis = getResource();
        try {
            jedis.expire(key, i);
        } finally {
            jedis.close();
        }
    }

    public byte[] get(byte[] key) {
        Jedis jedis = getResource();
        try {
            return jedis.get(key);
        } finally {
            jedis.close();
        }
    }

    public void del(byte[] key) {
        Jedis jedis = getResource();
        try {
            jedis.del(key);
        } finally {
            jedis.close();
        }
    }

    public Set<byte[]> keys(String shiro_session_prefix) {
        Jedis jedis = getResource();
        try {
            return jedis.keys((shiro_session_prefix + "*").getBytes());
        } finally {
            jedis.close();
        }
    }

配置:  sessionDao  给 sessionManager    sessionManager给securityManager

<!--sessionManagger对象-->
<bean class="com.zhuoshi.session.CustomSessionManager" name="defaultSessionManager">
    <property name="sessionDAO" ref="sessionDao"/>
</bean>
<!--自定义的sessionDao-->
<bean name="sessionDao" class="com.imooc.session.RedisSession"/>
<!--创建securitymanager对象-->
<bean name="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
    <property name="realm" ref="customRealm"/>
    <property name="sessionManager" ref="defaultSessionManager"/>
</bean>

  存在的问题: 多次读取redis中session数据  浪费系统资源:解决办法

源代码           

      可以看到每次调用sessionDao 中的read方法   造成读取次数过多  我们来重写这个方法   将session第一次读                             取之后放在request中   之后读取从request中拿出session对象就可以完美的解决这问题。          

protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
    Serializable sessionId = getSessionId(sessionKey);
    if (sessionId == null) {
        log.debug("Unable to resolve session ID from SessionKey [{}].  Returning null to indicate a " +
                "session could not be found.", sessionKey);
        return null;
    }
    Session s = retrieveSessionFromDataSource(sessionId);
    if (s == null) {
        //session ID was provided, meaning one is expected to be found, but we couldn't find one:
        String msg = "Could not find session with ID [" + sessionId + "]";
        throw new UnknownSessionException(msg);
    }
    return s;
}
protected Session retrieveSessionFromDataSource(Serializable sessionId) throws UnknownSessionException {
    return sessionDAO.readSession(sessionId);
}


  重写sessionManager  后的代码

@Override
protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {

    Serializable sessionId = getSessionId(sessionKey);
    ServletRequest request = null;
    if (sessionKey instanceof WebSessionKey) {
        request = ((WebSessionKey) sessionKey).getServletRequest();
    }

    //判断request中是否有session 有的话从session中拿出session
    if (request != null && sessionId != null) {
        Session session = (Session) request.getAttribute(sessionId.toString());
        if (session != null) {
            return session;
        }
    }
    //request 中没有session    redis中读取session  然后放在request    Session session = super.retrieveSession(sessionKey);
    if (request != null && sessionId != null) {
        request.setAttribute(sessionId.toString(), session);
    }
    return session;
}

 配置:当然要使用我们自定义的sessionManager

<!--sessionManagger对象-->
<bean class="com.zhuoshi.session.CustomSessionManager" name="defaultSessionManager">
    <property name="sessionDAO" ref="sessionDao"/>
</bean>







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值