Spring-session clears attributes from session after pageContext.include -



Spring-session clears attributes from session after pageContext.include -

i think have come across bug in spring-session want inquire here if bug. before forget

https://github.com/paranoiabla/spring-session-issue.git

here's github repository reproduces problem. have 2 controllers , 2 jsps, flow goes this:

user opens http://localhost:8080/ , flow goes through homepagecontroller, puts 1 attribute in spring-session , returns homepage.jsp renders session id , number of attributes (1) the homepage.jsp has line within it: ${pagecontext.include("/include")} calls includecontroller invoked. the includecontroller finds session session repository , logs number of attributes (now absolutely weird logged 0) , returns include.jsp renders both session id , number of session attributes (0). session id in both jsps same, somehow after pagecontext.include phone call attributes reset empty map!!! can please confirm if bug.

thank you.

problem

the problem when using mapsessionrepository sessionrepositoryfilter automatically sync httpsession spring session overrides explicit utilize of apis. next happening:

sessionrepositoryfilter obtaining current spring session. caches in httpservletrequest ensure every invocation of httpservletrequest.getsession() not create database call. cached version of spring session has no attributes associated it. the homepagecontroller obtains own re-create of spring session, modifies it, , saves it. the jsp flushes response commits httpservletresponse. means must write out session cookie prior flush beingness set. need ensure session persisted @ point because afterwards client may have access session id , able create request. means spring session #1 saved no attributes overrides session saved in #2. the includecontroller obtains spring session saved #3 (which has no attributes) solution

there 2 options see solving this.

use httpsession apis

so how solve this. easiest approach stop using spring session apis directly. preferred anyways since not want tie ourselves spring session apis if possible. example, instead of using following:

@controller public class homepagecontroller { @resource(name = "sessionrepository") private sessionrepository<expiringsession> sessionrepository; @resource(name = "sessionstrategy") private httpsessionstrategy sessionstrategy; @requestmapping(value = "/", method = requestmethod.get) public string home(final model model) { httpservletrequest request = ((servletrequestattributes) requestcontextholder.currentrequestattributes()).getrequest(); final string sessionids = sessionstrategy.getrequestedsessionid(request); if (sessionids != null) { final expiringsession session = sessionrepository.getsession(sessionids); if (session != null) { session.setattribute("attr", "value"); sessionrepository.save(session); model.addattribute("session", session); } } homecoming "homepage"; } } @controller public class includecontroller { private final static logger log = logmanager.getlogger(includecontroller.class); @resource(name = "sessionrepository") private sessionrepository<expiringsession> sessionrepository; @resource(name = "sessionstrategy") private httpsessionstrategy sessionstrategy; @requestmapping(value = "/include", method = requestmethod.get) public string home(final model model) { httpservletrequest request = ((servletrequestattributes) requestcontextholder.currentrequestattributes()).getrequest(); final string sessionids = sessionstrategy.getrequestedsessionid(request); if (sessionids != null) { final expiringsession session = sessionrepository.getsession(sessionids); if (session != null) { log.error(session.getattributenames().size()); model.addattribute("session", session); } } homecoming "include"; } }

you can simplify using following:

@controller public class homepagecontroller { @requestmapping(value = "/", method = requestmethod.get) public string home(httpservletrequest request, model model) { string sessionids = request.getrequestedsessionid(); if (sessionids != null) { final httpsession session = request.getsession(false); if (session != null) { session.setattribute("attr", "value"); model.addattribute("session", session); } } homecoming "homepage"; } } @controller public class includecontroller { @requestmapping(value = "/include", method = requestmethod.get) public string home(httpservletrequest request, final model model) { final string sessionids = request.getrequestedsessionid(); if (sessionids != null) { final httpsession session = request.getsession(false); if (session != null) { model.addattribute("session", session); } } homecoming "include"; } } use redisoperationssessionrepository

of course of study may problematic in event cannot utilize httpsession api directly. handle this, need utilize different implementation of sessionrepository. example, prepare utilize redisoperationssessionrepository. works because smart plenty update attributes have been changed.

this means in step #3 above, redis implementation update lastly accessed time since no other attributes updated. when includecontroller requests spring session still see attribute saved in homepagecontroller.

so why doesn't mapsessionrepository this? because mapsessionrepository based on map or nil thing. when value placed in map single set (we cannot break multiple operations).

spring-session

Comments

Popular posts from this blog

java - How to set log4j.defaultInitOverride property to false in jboss server 6 -

c - GStreamer 1.0 1.4.5 RTSP Example Server sends 503 Service unavailable -

Using ajax with sonata admin list view pagination -