85391

Spring MVC handling session expired

Question:

I'm working with Jboss EAP 6.2, Java EE 6 and Spring MVC 4.0.2. When the session expired I want to execute a page redirect.

I have developed a Spring Interceptor

@Component public class SessionExpiredInterceptor extends HandlerInterceptorAdapter { static final Logger logger = Logger.getLogger(SessionExpiredInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { final HttpSession session = request.getSession(false); if ( session == null || session.isNew() ) { ConfigurationProperties confProp = ConfigurationProperties.getInstance(); logger.info("Sessione scaduta, redirect home page"); request.getSession(true); response.sendRedirect(request.getContextPath() + "/" + confProp.getInstance().getProperty("session.expired.redirect")); } return true; } }

but I have the following exeception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.navigator': Scope 'session' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: JBWEB000043: Cannot create a session after the response has been committed org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:676) org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:627) it.lispa.sire.finanziamentionline.web.mvc.model.Navigator$$EnhancerBySpringCGLIB$$b6b810e.addNavigationMessages(<generated>) it.lispa.sire.finanziamentionline.web.mvc.UserSessionInterceptor.preHandle(UserSessionInterceptor.java:91) org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:130) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) javax.servlet.http.HttpServlet.service(HttpServlet.java:734) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) javax.servlet.http.HttpServlet.service(HttpServlet.java:847) JBWEB000071: root cause java.lang.IllegalStateException: JBWEB000043: Cannot create a session after the response has been committed org.apache.catalina.connector.Request.doGetSession(Request.java:2627) org.apache.catalina.connector.Request.getSession(Request.java:2361) org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:790) org.springframework.web.context.request.ServletRequestAttributes.getSession(ServletRequestAttributes.java:79) org.springframework.web.context.request.ServletRequestAttributes.getSessionMutex(ServletRequestAttributes.java:212) org.springframework.web.context.request.SessionScope.get(SessionScope.java:91) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:338) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.getTarget(CglibAopProxy.java:676) org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:627) it.lispa.sire.finanziamentionline.web.mvc.model.Navigator$$EnhancerBySpringCGLIB$$b6b810e.addNavigationMessages(<generated>) it.lispa.sire.finanziamentionline.web.mvc.UserSessionInterceptor.preHandle(UserSessionInterceptor.java:91) org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle(HandlerExecutionChain.java:130) org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:939) org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) javax.servlet.http.HttpServlet.service(HttpServlet.java:734) org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) javax.servlet.http.HttpServlet.service(HttpServlet.java:847)

The navigator bean is injected in some @Controller and other Interceptor.

This is a Interceptor that use Navigator bean:

@Component public class UserSessionInterceptor extends HandlerInterceptorAdapter { @Autowired private Navigator navigator; static final Logger logger = Logger.getLogger(UserSessionInterceptor.class.getName()); public static ConfigurationProperties getAuthenticationProps() throws IOException { return ConfigurationProperties.getInstance(); } @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { ...} }

The following is the interceptor configuration in spring.xml

<mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/static/**" /> <mvc:exclude-mapping path="/index.jsp" /> <mvc:exclude-mapping path="/logout" /> <mvc:exclude-mapping path="/ajax-logout" /> <bean class="it.lispa.sire.finanziamentionline.web.mvc.SessionExpiredInterceptor" /> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/home"/> <mvc:exclude-mapping path="/static/**" /> <mvc:exclude-mapping path="/logout" /> <mvc:exclude-mapping path="/ajax-logout" /> <bean class="it.lispa.sire.finanziamentionline.web.mvc.UserSessionInterceptor"/> </mvc:interceptor>

Can you help me? Thanks.

Answer1:

What happens here is that SessionExpiredInterceptor acts before UserSessionInterceptor. If it detects that the session is new, it performs a redirect

response.sendRedirect(request.getContextPath() + "/" + confProp.getInstance().getProperty("session.expired.redirect"));

Once you do a redirect, you've basically stated that you're finished processing the request and have sent a response (301 status code). But instead, in your code, you are returning true from preHandle which indicates to the DispatcherServlet that it should continue handling the request, execute the other interceptors and eventually reach the @Controller.

You don't want this. In the if block, return false after the sendRedirect.

Recommend

  • Linqpad Query Needs Unmanaged Deployment Item
  • WaveOut versus WaveOutEvent
  • Setting a path when creating a new File in Java
  • How to compare same PropertyInfo with different ReflectedType values?
  • Getting the new line character without System.getProperty(“line.separator”)?
  • Spring roo - how to install spring surf
  • Property file in java
  • Insert null in a database
  • Spring @Transactional - javax.persistence.TransactionRequiredException
  • What is the likely cause of a net::ERR_CONNECTION_ABORTED when uploading a file to Spring
  • BackgroundTransferRequest WP7
  • OpenCV Python: Draw minAreaRect ( RotatedRect not implemented)
  • iOS - Changing frame of a subview of a subclassed UIView (using storyboard with auto layout enabled)
  • Type safe keys with Entity Framework model
  • How to open multiple instances of a program in Linux
  • Not able to display correct data in table -AngularJS
  • include dlls in visual studio c++ 2008
  • conditions for accessors in Coldfusion ORM
  • What is the default HTTP verb in WebApi ? GET or POST?
  • Java Application vs. Java Desktop Application in Netbeans [duplicate]
  • Hash Code in SQL Server?
  • Moving Android View and preventing onDraw to be called over and over again
  • Read a local file using javascript
  • ImageMagick, replace semi-transparent white with opaque white
  • Initializer list vs. initialization method
  • Control modification in presentation layer
  • Cannot connect to cassandra from Spark
  • Sails.js/waterline: Executing waterline queries in toJSON function of a model?
  • Fetching methods from BroadcastReceiver to update UI
  • How to recover from a Spring Social ExpiredAuthorizationException
  • Cross-Platform Protobuf Serialization
  • Alternatives to the OPTIONAL fallback SPARQL pattern?
  • Hits per day in Google Big Query
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • Linking SubReports Without LinkChild/LinkMaster
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • Django query for large number of relationships
  • Why is Django giving me: 'first_name' is an invalid keyword argument for this function?
  • How can I use `wmic` in a Windows PE script?
  • How to push additional view controllers onto NavigationController but keep the TabBar?