我正在使用Jboss EAP 6.2
,Java EE 6
和Spring MVC 4.0.2
。
当会话过期时,我想执行页面重定向。
我开发了一个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;
}
}
但我有以下例外:
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)
导航器bean注入了一些@Controller和其他拦截器。
这是一个使用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 {
...}
}
以下是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>
你能帮帮我吗? 感谢。
答案 0 :(得分:4)
这里发生的是SessionExpiredInterceptor
在UserSessionInterceptor
之前的行为。如果它检测到会话是新的,则执行重定向
response.sendRedirect(request.getContextPath() + "/" +
confProp.getInstance().getProperty("session.expired.redirect"));
完成重定向后,您基本上已声明已完成处理请求并已发送响应(301状态代码)。但是,在您的代码中,您将从true
返回preHandle
,向DispatcherServlet
表明它应继续处理请求,执行其他拦截器并最终到达@Controller
}。
你不想要这个。在if
区块中,在false
之后返回sendRedirect
。