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.
In web applications, session holds the information of current logged-in users. So, if the session expires in 20 minutes, then it is redirected to login page. In that case, we need to check if session exists (not null) in every action/ every controller which requires authentication.
By using SecurityContext you can get this info in your controller code. SecurityContext context = SecurityContextHolder. getContext(); Authentication authentication = context. getAuthentication();
Session timeout represents the event occuring when a user does not perform any action on a web site during an interval (defined by a web server). The event, on the server side, changes the status of the user session to 'invalid' (ie.
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With