吃透Shiro源码9----SimpleSession

技术手法

(1)SimpleSession

public class SimpleSession implements ValidatingSession, Serializable {

    private Serializable id;
    private Date startTimestamp;
    private Date lastAccessTime;
    private Date stopTimestamp;
    private long timeout;
    private boolean expired;
    private String host;
    private Map<Object, Object> attributes;


    public SimpleSession() {
        this.timeout = DEFAULT_GLOBAL_SESSION_TIMEOUT;
        this.startTimestamp = new Date();
        this.lastAccessTime = this.startTimestamp;
    }

    public SimpleSession(String host) {
        this();
        this.host = host;
    }

    /**
     * 更新上次访问时间
     *
     * @throws InvalidSessionException
     */
    @Override
    public void touch() throws InvalidSessionException {
        this.lastAccessTime = new Date();
    }

    /**
     * stop方法的本质就是把 stopTimestamp赋值,且只能搞一次
     *
     * @throws InvalidSessionException
     */
    @Override
    public void stop() throws InvalidSessionException {
        if (this.stopTimestamp == null) {
            this.stopTimestamp = new Date();
        }
    }

    /**
     * 是否停止
     *
     * @return
     */
    protected boolean isStopped() {
        return stopTimestamp != null;
    }

    protected void expire() {
        //更新时间戳
        stop();
        this.expired = true;
    }

    /**
     * Determines if this session is expired.
     *
     * @return true if the specified session has expired, false otherwise.
     */
    protected boolean isTimedOut() {
        if (this.expired) {
            return true;
        }
        long timeout = this.timeout;
        if (timeout < 1) {
            //大于01则永不过期
            return false;
        }
        /**
         * 计算会话最后一次访问的时间,以使其在此时终止。
         * 换句话说,从当前时间中减去会话在过期之前可以处于非活动状态的时间。
         * 如果在该时间之前最后一次访问会话,则该会话已过期。
         */
        Date lastAccessTime = getLastAccessTime();
        if (lastAccessTime == null) {
            String msg = "上次访问时间为空";
            throw new IllegalStateException(msg);
        }
        long expireTimeMillis = System.currentTimeMillis() - timeout;
        Date expireTime = new Date(expireTimeMillis);
        return lastAccessTime.before(expireTime);
    }

    @Override
    public boolean isValid() {
        //无停止时间并且没有过期
        return this.stopTimestamp == null && !this.expired;
    }

    @Override
    public void validate() throws InvalidSessionException {
        if (isStopped()) {
            throw new InvalidSessionException("Session已经停止");
        }
        if (isTimedOut()) {
            expire();
            throw new ExpiredSessionException("Session过期");
        }
    }

    @Override
    public Object getAttribute(Object key) {
        Map<Object, Object> attributes = getAttributes();
        if (attributes == null) {
            return null;
        }
        return attributes.get(key);
    }

    @Override
    public void setAttribute(Object key, Object value) {
        if (value == null) {
            removeAttribute(key);
        }
        Map<Object, Object> attributes = getAttributesLazy();
        attributes.put(key, value);
    }

    @Override
    public Object removeAttribute(Object key) {
        Map<Object, Object> attributes = getAttributes();
        if (attributes == null) {
            return null;
        }
        return attributes.remove(key);
    }

    @Override
    public Collection<Object> getAttributeKeys() throws InvalidSessionException {
        Map<Object, Object> attributes = getAttributes();
        if (attributes == null) {
            return Collections.emptySet();
        }
        return attributes.keySet();
    }


    private Map<Object, Object> getAttributesLazy() {
        Map<Object, Object> attributes = this.attributes;
        if (attributes == null) {
            this.attributes = new HashMap<>();
            attributes = this.attributes;
        }
        return attributes;
    }


    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getName()).append(",id=").append(getId());
        return sb.toString();
    }
}
posted @ 2022-07-17 12:14  小大宇  阅读(92)  评论(0编辑  收藏  举报