Spring MVC handling session expired

java, session, session-timeout, spring, spring-mvc

Solution

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`.

Problem

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.

Original source