java.lang.IllegalStateException: getAttribute: Session already invalidated 非法状态异常:getAttribute:会话已失效

31
我在代码中使portletRequest会话无效后,出现以下异常。
Aug 27, 2013 7:07:13 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet xyzapplication Servlet threw exception java.lang.IllegalStateException: getAttribute: Session already invalidated
    at org.apache.catalina.session.StandardSession.getAttribute(StandardSession.java:1165)
    at org.apache.catalina.session.StandardSessionFacade.getAttribute(StandardSessionFacade.java:122)
    at com.liferay.portal.servlet.SharedSessionWrapper.getAttribute(SharedSessionWrapper.java:75)
    at com.liferay.portlet.PortletSessionImpl.getAttribute(PortletSessionImpl.java:55)
    at org.springframework.web.portlet.context.PortletRequestAttributes.updateAccessedSessionAttributes(PortletRequestAttributes.java:256)
    at org.springframework.web.context.request.AbstractRequestAttributes.requestCompleted(AbstractRequestAttributes.java:48)
    at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:552)
    at org.springframework.web.portlet.FrameworkPortlet.processAction(FrameworkPortlet.java:460)
    at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:70)
    at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:48)
    at com.liferay.portal.kernel.servlet.PortletServlet.service(PortletServlet.java:111)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:72)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.doInclude(ApplicationDispatcher.java:593)
    at org.apache.catalina.core.ApplicationDispatcher.include(ApplicationDispatcher.java:530)
    at com.liferay.portlet.InvokerPortletImpl.invoke(InvokerPortletImpl.java:534)
    at com.liferay.portlet.InvokerPortletImpl.invokeAction(InvokerPortletImpl.java:579)
    at com.liferay.portlet.InvokerPortletImpl.processAction(InvokerPortletImpl.java:294)
    at com.liferay.portal.action.LayoutAction.processPortletRequest(LayoutAction.java:944)
    at com.liferay.portal.action.LayoutAction.processLayout(LayoutAction.java:688)
    at com.liferay.portal.action.LayoutAction.execute(LayoutAction.java:249)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236)
    at com.liferay.portal.struts.PortalRequestProcessor.process(PortalRequestProcessor.java:176)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196)
    at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:432)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
    at com.liferay.portal.servlet.MainServlet.callParentService(MainServlet.java:560)
    at com.liferay.portal.servlet.MainServlet.service(MainServlet.java:537)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:72)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilter.java:294)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:684)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:471)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
    at com.liferay.portal.servlet.FriendlyURLServlet.service(FriendlyURLServlet.java:138)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:72)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.strip.StripFilter.processFilter(StripFilter.java:335)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.gzip.GZipFilter.processFilter(GZipFilter.java:123)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.secure.SecureFilter.processFilter(SecureFilter.java:294)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.i18n.I18nFilter.processFilter(I18nFilter.java:241)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.autologin.AutoLoginFilter.processFilter(AutoLoginFilter.java:246)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.sso.ntlm.NtlmPostFilter.processFilter(NtlmPostFilter.java:83)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.sharepoint.SharepointFilter.processFilter(SharepointFilter.java:80)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.BaseFilter.processFilter(BaseFilter.java:163)
    at com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter.processFilter(VirtualHostFilter.java:216)
    at com.liferay.portal.kernel.servlet.BaseFilter.doFilter(BaseFilter.java:57)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:187)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:95)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:738)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDoFilter(InvokerFilterChain.java:206)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:108)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:167)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:95)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:167)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:95)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:116)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.processDirectCallFilter(InvokerFilterChain.java:187)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilterChain.doFilter(InvokerFilterChain.java:95)
    at com.liferay.portal.kernel.servlet.filters.invoker.InvokerFilter.doFilter(InvokerFilter.java:73)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
    at com.googlecode.psiprobe.Tomcat60AgentValve.invoke(Tomcat60AgentValve.java:30)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:999)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:309)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
    at java.lang.Thread.run(Thread.java:722) 

我的会话失效代码如下: 顺便说一下,这个方法是从另一个带有@ActionMapping注释标记的方法中调用的。

 private void exit(PortletRequest request, ActionResponse response) {
    logger.debug("Entering exit");
    String exitURL = Constants.EXIT_URL;
    request.getPortletSession().invalidate();
    try {
        response.sendRedirect(exitURL);
    } catch (IOException ex) {
        logger.error("Error: IOException: {}", ex.getMessage());
        throw new RuntimeException(ex);
    }

    logger.debug("Exiting exit");
}

我在stackoverflow上找到了一个与session失效相关的现有问题IllegalStateException: getAttribute: Session already invalidated,但是对于我的情况,我从中没有得到很多帮助。

有人可以帮助我解决这个问题吗?当控制转移到Spring代码时,由于此错误而无法解决此问题,我该如何处理?


你能否尝试在方法签名中添加 SessionStatus status,然后通过 status.setCompleted() 使会话无效,而不是通过请求使其失效?另外,在执行 response.sendRedirect() 后再无效化。 - CodeChimp
错误并不是发生在执行request.getPortletSession().invalidate();或者response.sendRedirect(exitURL);的时候,甚至不是在这些语句的执行点。它是在我的控制权回到Spring框架之后发生的,也就是说,当控制权回到Spring时发生了错误。因此,我猜测上述语句的执行顺序并不重要。 - stallion
会话范围的Bean会引起任何问题吗?也就是说,我需要单独使它们失效吗?如果是的话,我应该在什么时候使其失效,如何使其失效? - stallion
1
从堆栈跟踪来看,异常似乎发生在 LifeRay 的一个 Servlet 过滤器中。 我猜测是 LifeRay 在您已经无效之后尝试访问会话。 我建议尝试上面提到的 SessionStatus 和 .setCompleted()。 由于它不直接作用于会话,因此可能会延迟实际会话失效,直到所有进程完成。 - CodeChimp
是的,我相信那正是发生的事情,但我不明白如何应用你的修复方法,请问你能否提供与你答案相关的示例代码? - stallion
显示剩余2条评论
3个回答

2
我从这里的JavaDoc可以看出,我从未使用过WebLogic,但我可以告诉你,如果你想使现有会话失效,调用getPortletSession()已经是错误的想法,因为JavaDocs中已经说明了:
Returns the current portlet session or, if there is no current session,
creates one and returns the new session.

因此,它创建了一个新的会话,如果您只想使已经存在的会话失效,这不是您想要的。
您需要的方法是getPortletSession(boolean create),在调用它时需要传递false,并且如果在调用该方法时没有可用的会话,则可能返回null值,因此您还需要处理null:
PortletSession current = request.getPortletSession();
if (current != null) try {
    current.invalidate();
} catch (IllegalStateException ignored) {
    // ok: session is already invalidated
}

我们需要捕获这个异常,因为从我看到的JavaDocs中,没有办法确定会话是否已经失效。所以我们只是无论如何都使其失效,并忽略由于会话已经失效而抛出的IllegalStateException。
另外,在使会话失效之前,不要忘记调用response.sendRedirect(exitURL);,我的直觉告诉我应该先做这个。

这里response.sendRedirect(exitURL)的作用是什么? - nightfury
这是主题发起人的代码片段。他需要发送重定向响应。 您可以在JavaDoc中了解更多信息: https://portals.apache.org/pluto/portlet-2.0-apidocs/javax/portlet/ActionResponse.html#sendRedirect(java.lang.String) - semplar

1
无论如何,如果您想做这件事,您可以做到。你有一个解决方案。 确保在请求线程内运行此方法,Spring为每个请求分配一个线程。 如果您在请求之外,则无法从请求中获取任何内容。 如果您使用了@ Async 或者如果您创建了自己的 own thread thread-pool 来执行此方法,则无法并行执行。 我认为这应该是您面临的问题。 解决方案是您可以创建自己的类作为 Cloneable 并进行克隆。 要了解更多信息,请查看此答案。

https://dev59.com/Nin_s4cB2Jgan1znsPEU#68937755


-2

尝试使用SessionStatus替代:

private void exit(PortletRequest request, ActionResponse response, SessionStatus status) {
    logger.debug("Entering exit");
    String exitURL = Constants.EXIT_URL;
    status.setComplete();  // instead of request.getPortletSession().invalidate()
    try {
        response.sendRedirect(exitURL);
    } catch (IOException ex) {
        logger.error("Error: IOException: {}", ex.getMessage());
        throw new RuntimeException(ex);
    }

    logger.debug("Exiting exit");
}

我不认为这会有什么影响,但尝试一下也值得。


我不确定这些信息是否有帮助,但我认为提供这些信息是值得的:
  1. 我已经使用会话范围创建了bean,并使用代理(<aop:scoped-proxy />)进行创建。
  2. 执行此会话失效的方法是从默认情况下带有actionmapping注释的方法中调用的。
- stallion

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接