All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yuweix.kuafu.session.CacheHttpSession Maven / Gradle / Ivy

The newest version!
package com.yuweix.kuafu.session;


import java.util.*;
import jakarta.servlet.ServletContext;
import jakarta.servlet.http.HttpSession;

import com.yuweix.kuafu.core.json.Json;
import com.yuweix.kuafu.session.cache.SessionCache;
import com.yuweix.kuafu.session.conf.SessionConf;
import org.springframework.util.CollectionUtils;


/**
 * 一个HttpSession的实现,实际的属性会储存在指定的缓存实现中。
 * @author yuwei
 */
public class CacheHttpSession implements HttpSession {
	private final String id;
	/**
	 * session是否已失效
	 */
	private boolean invalid = false;
	/**
	 * 存入cache的session的key
	 */
	private final String fullSessionId;
	/**
	 * 如果要避免重复登录,后登录的覆盖之前登录的,如果sessionIdKey为空,表明不需要处理重复登录的问题。
	 * sessionIdKey用于记录存入cache的session的key。
	 * 如用户编号为1001,登录成功后在cache中存入两条数据:
	 * 1、cache.kuafu.session.008c203973554062b2b04cd3535661f1={......},
	 * 2、cache.kuafu.session.current.1001=cache.kuafu.session.008c203973554062b2b04cd3535661f1
	 * 其中cache.kuafu.session.current.1001即为sessionIdKey
	 */
	private String sessionIdKey;
	private final String sessionIdKeyPre;
	private SessionAttribute sessionAttribute;



	/**
	 * 初始化时必须指定一个id字符串和缓存引擎实现。
	 * @param id id字符串。
	 */
	public CacheHttpSession(String id) {
		SessionConf sessionConf = SessionConf.getInstance();
		this.id = id;
		this.sessionIdKeyPre = SessionConstant.SESSION_ID_PRE + sessionConf.getApplicationName() + "." + SessionConstant.SESSION_ID_KEY_CURRENT;
		this.fullSessionId = SessionConstant.SESSION_ID_PRE + sessionConf.getApplicationName() + "." + this.id;
		init();
	}

	/**
	 * 此Session的ID值。
	 * 这里返回存入cache的key值
	 * @return id值。
	 */
	@Override
	public String getId() {
		return fullSessionId;
	}

	/**
	 * 获取此Session的创建时间。
	 * @return 创建时间。
	 */
	@Override
	public long getCreationTime() {
		return sessionAttribute.getCreateTime().getTime();
	}

	/**
	 * 获取最后访问时间。
	 * @return 最后访问时间。
	 */
	@Override
	public long getLastAccessedTime() {
		return sessionAttribute.getLastAccessTime().getTime();
	}

	/**
	 * 获取当前的属性键值对。
	 * @return 属性键值对。
	 */
	public SessionAttribute getSessionAttribute() {
		return sessionAttribute;
	}

	/**
	 * 表示此Session被访问。
	 */
	public void access() {
		sessionAttribute.setLastAccessTime(Calendar.getInstance().getTime());
	}

	/**
	 * @param interval           秒
	 */
	@Override
	public void setMaxInactiveInterval(int interval) {
		SessionConf.getInstance().setMaxInactiveInterval(interval / 60);
	}

	@Override
	public int getMaxInactiveInterval() {
		return SessionConf.getInstance().getMaxInactiveInterval() * 60;
	}

	/**
	 * 获取属性值。
	 * @param attributeName 属性名称。
	 * @return 属性值。
	 */
	@Override
	public Object getAttribute(String attributeName) {
		return sessionAttribute.getAttribute(attributeName);
	}

	/**
	 * 更新属性。
	 * @param attributeName 属性名称。
	 * @param attributeValue 属性值。
	 */
	@Override
	public void setAttribute(String attributeName, Object attributeValue) {
		if (attributeValue instanceof RepeatKey) {
			String rVal = ((RepeatKey) attributeValue).getValue();
			sessionAttribute.putAttribute(attributeName, rVal);
			this.sessionIdKey = sessionIdKeyPre + "." + rVal;
			sessionAttribute.setRepeatKey(attributeName);
			sessionAttribute.setRepeatValue(rVal);
		} else {
			sessionAttribute.putAttribute(attributeName, attributeValue);
		}
	}

	/**
	 * 移除已有的属性。
	 * @param attributeName 属性名称。
	 */
	@Override
	public void removeAttribute(String attributeName) {
		sessionAttribute.removeAttribute(attributeName);
	}

	/**
	 * 让Session过期。
	 */
	@Override
	public void invalidate() {
		this.invalid = true;
	}

	/**
	 * 判断是否已经超过了最大活动时间。
	 * @return true超过,false没有超过。
	 */
	public boolean isInvalid() {
		if (!this.invalid) {
			int mii = SessionConf.getInstance().getMaxInactiveInterval();
			if (mii <= 0) {
				this.invalid = false;
			} else {
				long invalidMillis = mii * 60 * 1000L;
				long lastAccessTime = getLastAccessedTime();
				long now = Calendar.getInstance().getTimeInMillis();
				this.invalid = (now - lastAccessTime) > invalidMillis;
			}
		}
		return this.invalid;
	}

	/**
	 * 判断此Session是否为新的。
	 * @return true 为新的,false为非新的。
	 */
	@Override
	public boolean isNew() {
		return sessionAttribute.isNewBuild();
	}

	@Override
	public int hashCode() {
		return fullSessionId.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof CacheHttpSession)) {
			return false;
		}

		CacheHttpSession other = (CacheHttpSession) obj;
		if (id == null && other.id == null) {
			return true;
		} else if (id != null && other.id != null) {
			return id.equals(other.id);
		}
		return false;
	}

	public void removeSessionFromCache() {
		SessionConf.getInstance().getCache().remove(fullSessionId);
		if (sessionIdKey != null) {
			SessionConf.getInstance().getCache().remove(sessionIdKey);
		}
	}

	/**
	 * 更新当前Session至缓存。如果已经失效,从缓存中删除。
	 * @return sessionId
	 */
	public String sync() {
		if (isInvalid() || sessionAttribute == null || CollectionUtils.isEmpty(sessionAttribute.getAttributes())) {
			removeSessionFromCache();
			return fullSessionId;
		}

		SessionCache sessionCache = SessionConf.getInstance().getCache();
		long timeSec = SessionConf.getInstance().getMaxInactiveInterval() * 60L;

		Json json = SessionConf.getInstance().getJson();
		sessionCache.put(fullSessionId, json.serialize(sessionAttribute), timeSec);
		/**
		 * 如果sessionIdKey不为空,表明需要避免重复登录
		 */
		if (sessionIdKey != null) {
			/**
			 * 把当前账号之前登录的session清除掉,防止重复登录
			 */
			String sessionId = sessionCache.get(sessionIdKey);
			if (sessionId != null && !sessionId.equals(fullSessionId)) {
				sessionCache.remove(sessionId);
			}
			sessionCache.put(sessionIdKey, fullSessionId, timeSec);
		}
		return fullSessionId;
	}

	/**
	 * 初始化方法。
	 * 初始化缓存中的属性容器。
	 * 如果缓存中没有,则新建并设定创建时间和最后访问时间为当前时间和为新的会话。
	 */
	private void init() {
		initSessionAttribute();
		String repeatValue = sessionAttribute.getRepeatValue();
		if (repeatValue != null && !"".equals(repeatValue)) {
			this.sessionIdKey = sessionIdKeyPre + "." + repeatValue;
		}
		this.access();
	}
	private void initSessionAttribute() {
		if (sessionAttribute != null) {
			return;
		}

		Json json = SessionConf.getInstance().getJson();
		sessionAttribute = json.deserialize(SessionConf.getInstance().getCache().get(fullSessionId));
		if (sessionAttribute == null) {
			removeSessionFromCache();
			sessionAttribute = new SessionAttribute();
		} else {
			sessionAttribute.setNewBuild(false);
		}
	}

	@Override
	public Enumeration getAttributeNames() {
		return new SessionEnumeration(sessionAttribute.getAttributes().keySet());
	}
	private static class SessionEnumeration implements Enumeration {
		Iterator iterator;
		public SessionEnumeration (Set _attributeNames) {
			Set attributeNames = new HashSet<>();
			if (_attributeNames != null && _attributeNames.size() > 0) {
				attributeNames.addAll(_attributeNames);
			}
			iterator = attributeNames.iterator();
		}

		@Override
		public boolean hasMoreElements() {
			return iterator.hasNext();
		}

		@Override
		public String nextElement() {
			return iterator.next();
		}
	}


	@Override
	public ServletContext getServletContext() {
		return null;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy