Hi John,
With the exception of the Session's 'attributes' Map, all of the
internal properties of SimpleSession are all 'single value' properties
- Date, long, String, etc. These can be serialized and deserialized
with no interaction on your part with most JSON serializer mechanisms
(Jackson, etc).
The attributes Map might be another story. Of course JSON serializers
can handle maps easily, but there is no telling what is in that map
since its contents are at the mercy of the application developer's
preferences. When SimpleSession is serialized via JVM serialization,
it works fine assuming that the Map contents are all Serializable
(this is a contract between Shiro and application developers - it is
expected that anything you put in the session can be serialized).
That means your JSON serialization mechanism should know how to
serialize the attributes Map as well, e.g.:
{ ...
"attributes": {
"someAttribute": {
"someProp": "someValue",
"anotherProp": "anotherValue"
},
"anotherAttribute": "hello world",
...
}
If this is not possible (or not very feasible), the easiest thing to
do would be to serialize the attributes map via JVM serialization and
store value as a Base64-encoded string:
Serializer<Map> serializer = new org.apache.shiro.io.DefaultSerializer();
byte[] serialized = serializer.serialize(simpleSession.getAttributes());
String base64Attributes =
org.apache.shiro.codec.Base64.encodeToString(serialized);
{ ...
"base64Attributes": base64Attributes
}
you'll of course reverse the process when converting from JSON to SimpleSession:
String base64Attributes = jsonObject['base64Attributes']
byte[] serialized = Base64.decode(base64Attributes);
Map attributes = serializer.deserialize(serialized);
simpleSession.setAttributes(attributes);
then return the simpleSession instance back to Shiro.
You'll probably want a local/in-memory cache to proxy Redis because
Shiro can hit the session cache dozens of times in a single request -
you wouldn't want dozens of network round-trips to Redis during a
request. (Shiro 1.3 will probably reduce this need by storing a
thread-local copy of the Session, but for now that does not occur
because it expects the Cache to work efficiently).
HTH,
--
Les Hazlewood
CTO, Katasoft | http://www.katasoft.com | 888.391.5282
twitter: @lhazlewood | http://twitter.com/lhazlewood
katasoft blog: http://www.katasoft.com/blogs/lhazlewood
personal blog: http://leshazlewood.com
On Mon, Jan 30, 2012 at 6:48 AM, John Moore <[email protected]> wrote:
> I am trying to implement Cache and CacheManager to utilize Redis as a
> session store. Redis is a key/value store in which the keys and values are
> normally strings. I'm actually using Grails, and the inbuilt Grails JSON
> converters make it very straightforward to create a JSON string from a
> SimpleSession object (which is what I need to 'put' with the Cache
> implementation). My problem is implementing 'get'. How do I recreate a
> SimpleSession object from a JSON string? I imagine I could write some code
> to loop through the accessor methods and create one that way, but I was
> hoping there was some other much simpler way which I've overlooked.