使用session.invalidate()注销,此后不会转发到登录页面

时间:2013-06-24 11:31:21

标签: jsf session redirect prettyfaces

我有一个注销链接,如下所示:

    <h:form>
       <div>
         <h:commandButton value="Logout" action="#{Bean.logOut}" />
       </div>
    </h:form>

以及相应的注销方法:

 public String logOut()throws Exception{
        FacesContext facesContext = FacesContext.getCurrentInstance();
        HttpSession httpSession = (HttpSession)facesContext.getExternalContext().getSession(false);
        httpSession.invalidate();
        return "pretty:index?faces-redirect=true";
    }

当我点击退出按钮时,它工作正常,但当我试图转发登录页面时它接触不起作用,我得到了错误

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed
at org.apache.catalina.connector.ResponseFacade.sendRedirect(ResponseFacade.java:483)
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at com.test.Bean.onErrorHome(Bean.java:262)
at com.test.Bean.<init>(Bean.java:51)
at com.test.service.BeanList.<init>(BeanList.java:84)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at java.lang.Class.newInstance0(Class.java:374)
at java.lang.Class.newInstance(Class.java:327)
at com.sun.faces.mgbean.BeanBuilder.newBeanInstance(BeanBuilder.java:188)
at com.sun.faces.mgbean.BeanBuilder.build(BeanBuilder.java:102)
at com.sun.faces.mgbean.BeanManager.createAndPush(BeanManager.java:409)
at com.sun.faces.mgbean.BeanManager.create(BeanManager.java:269)
at com.sun.faces.el.ManagedBeanELResolver.resolveBean(ManagedBeanELResolver.java:244)
at com.sun.faces.el.ManagedBeanELResolver.getValue(ManagedBeanELResolver.java:116)
at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
at org.apache.el.parser.AstIdentifier.getValue(AstIdentifier.java:72)
at org.apache.el.parser.AstValue.getTarget(AstValue.java:94)
at org.apache.el.parser.AstValue.getType(AstValue.java:82)
at org.apache.el.ValueExpressionImpl.getType(ValueExpressionImpl.java:176)
at com.ocpsoft.pretty.faces.util.FacesElUtils.getExpectedType(FacesElUtils.java:50)
at com.ocpsoft.pretty.faces.beans.ParameterInjector.injectQueryParams(ParameterInjector.java:125)
at com.ocpsoft.pretty.faces.beans.ParameterInjector.injectParameters(ParameterInjector.java:55)
at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.afterPhase(PrettyPhaseListener.java:102)
at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:145)
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:690)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:477)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:402)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:329)
at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:137)
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:123)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
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.ajp.AjpProcessor.process(AjpProcessor.java:200)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:579)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:722)

我如何解决这个问题。 请帮我 。 提前致谢。

2 个答案:

答案 0 :(得分:1)

查看在错误的时刻正在调用sendRedirect的堆栈跟踪:

at javax.servlet.http.HttpServletResponseWrapper.sendRedirect(HttpServletResponseWrapper.java:138)
at com.test.Bean.onErrorHome(Bean.java:262)
at com.test.Bean.<init>(Bean.java:51)
at com.test.service.BeanList.<init>(BeanList.java:84)

您在注销后重定向到的页面显然引用BeanList,在其构造函数中,手动构建了另一个Bean实例,其中调用了构造函数onErrorHome()方法,该方法正在调用HttpServletResponse#sendRedirect()

我不确定你们在那里做了什么,但鉴于这个问题,它肯定做得不对。在页面忙于生成HTML输出时,您基本上是在尝试重定向。该HTML的一部分已经发送到webbrowser(即响应已经提交)。

你有两个选择:

  1. 将该逻辑移至servlet filter

  2. onErrorHome()事件期间而不是在构造函数中执行preRenderView作业。

    <f:event type="preRenderView" listener="#{beanList.init}" />
    

    在 JSF开始呈现/生成/发送HTML输出之前调用此方法,因此您可以自由地将响应更改为其他目标,而不会有IllegalStateException: response already committed错误。

  3. 另见:

答案 1 :(得分:-1)

在函数结束时,您可以使用true值再次调用getSession以重新创建会话。


     public String logOut()throws Exception{
            FacesContext facesContext = FacesContext.getCurrentInstance();
            HttpSession httpSession = (HttpSession)facesContext.getExternalContext().getSession(false);
            httpSession.invalidate();
            return "pretty:index?faces-redirect=true";
            httpSession = (HttpSession)facesContext.getExternalContext().getSession(true);
            return "pretty:index?faces-redirect=true";
        }