Preamble
I plan to use ehCache as the first session control check if you cannot use an already provided and probably better suitable session. If you use a web container or a full-featured jee server, you really should try this first
Why
Good. You are sure that you will not do it right. Here are some tips why you can use ehCache for sessions.
- Your service is not part of the jee server / web container.
- Your service does not have a status, but from time to time you need states (frame code).
- You cannot distinguish between proxy server calls between you and the distinguished client, for example, you are a kind of middleware for a service / service that does not provide distinguishable data by default, but uses parameters like userId or sessionId, conditionally but not constitutively.
- You just did not do RTFM and want to do it your own way.
For 1, please check if the web container is suitable, for example, a berth. You, of course, use web access for the entire session, which would not appear for you.
For 2, please check if Apache Shiro will not do what you want. If not, ehCache may be your friend.
For 3 ... welcome to the club.
For 4 ... well, I think if you have not read the manual, you will not read it either.
how
If you want to implement session management with ehCache, make sure your data is serializable. This will reduce problems and allow you to use the sensitive features of ehCache. namely, saving to disk, caching nodes, recovering from this, etc.
Use not a cache for each session, but one for all sessions. sessionId
is the key in your cache, and the values ββare Map
. Don't forget about concurrency (think about ajax calls). It is best to use ConcurrentHashMap
from java.util.concurrent
. But perhaps you are Dr Heinz M. Kabutz and find an even colder way to do this.
I found it very useful to use a size other than the number of items to store. You may not know what data / objects will be stored later. Remember to set a conservation strategy. Here I used save in temp folder.
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="java.io.tmpdir"/> <cache name="vocCache" eternal="false" maxElementsInMemory="100MB" maxElementsOnDisk="1GB" timeToIdleSeconds="3600" timeToLiveSeconds="0" memoryStoreEvictionPolicy="LRU" diskExpiryThreadIntervalSeconds="60"> <persistence strategy="localTempSwap" /> </cache>
Since we want to implement a session manager, we are not worried about timeToLiveSeconds
. Sessions time out after a certain downtime. Therefore, we do not limit the element to the maximum ttl, but use timeToIdleSeconds
to allow the element to time out. Don't worry about timeToIdleSeconds
and timeToLiveSeconds
, because you can set specific values ββfor items that need to be added later.
Eviction
One note about expiration time. An item in memory will never be displayed due to the time set. The memory will increase until a certain memory limit is set. Therefore, if you define 100 elements, if 101 element is added, memoryStoreEvictionPolicy
will bet, and one element will be flushed to disk (in this configuration) (ehCache 2.2). For disk storage, the thread will be checked for expiration time ( diskExpiryThreadIntervalSeconds
). See the documentation . Therefore, you should check the extracted item from the cache using isExpired()
so that it does not expire.
So, in the end you will get something like this:
Get
Cache cache = CacheManager.getInstance().getCache(CACHE_NAME); Element elem = cache.get(identifier); if (elem == null) { throw new SessionNotFoundException(identifier); } if (elem.isExpired()) { throw new SessionExpiredException(identifier); } return elem.getObjectValue();
Put
Cache cache = CacheManager.getInstance().getCache(CACHE_NAME); // We use ttl = 0 and tti=<ttlInMinutes>, because session timeout is based on session idle timout. element = new Element(identifier, new SessionElement(), Boolean.FALSE, (int) (timeToLive / VALUE_MS), 0); cache.put(element);