JSF导航重定向到上一页

7
一旦用户成功登录系统,系统将重定向用户到主页。现在我的问题是,如果用户在未登录系统的情况下单击“查看账户”页面,则系统将重定向用户到登录页面。如果用户现在登录到系统,则系统将重定向用户到主页,在这种情况下,任何方法都可以将用户重定向到以前的页面,即“查看账户”页面,而不是主页吗?
我尝试使用会话。
String url = (String)session.getAttribute("url");
if(url != null)
    response.sendRedirect(url);
else
    response.sendRedirect("homepage.faces");

如果用户成功登录,则将此代码放在public void doBtnAction(){}下,并重定向到URL。但我收到了以下错误信息:
java.lang.IllegalStateException: Cannot forward after response has been committed
    com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:322)
    com.sun.faces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:130)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:87)
    com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:200)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:117)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:198)
7个回答

17

出现该异常是因为您调用了response.sendRedirect(),但没有阻止JSF渲染正常响应。您需要通过添加以下内容告知JSF,它不需要处理正常响应:

FacesContext.getCurrentInstance().responseComplete(); 

传递给动作方法。

或者,更好的方法是不要从JSF的内部获取HttpServletResponse,而是执行以下操作:

FacesContext.getCurrentInstance().getExternalContext().redirect(url);
这将自动调用responseComplete(),并且它还可以使您的代码不受不必要的Servlet API限制。另请参阅ExternalContext API

我喜欢stackoverflow!我还没有需要提问的情况,因为我总是在这里找到已经回答了我的问题。感谢BalusC。 - Naganalf
这在我的情况下不起作用:当我在HttpSession上调用getAttribute("url")时,我得到null。我尝试在HttpServletRequest上调用getRequestURI(),但是如果用户没有登录,则返回重定向到登录页面的URI。 - Theo
@Theo:那是完全不同的问题。你必须先自己设置它 :) - BalusC
我已经发布了另一个关于此问题的问题:http://stackoverflow.com/questions/4105263/jsf-2-0-how-to-get-the-url-that-is-entered-in-the-browsers-address-bar :) - Theo
我尝试了这个解决方案,但是 dispath() 仍然抛出了 IllegalStateException 异常(我的代码:FacesContext.getCurrentInstance().responseComplete(); FacesContext.getCurrentInstance().getExternalContext().dispatch("/mypage.xhtml"); ) - Cattani Simone

2

不确定,但可以通过ExternalContext工具来尝试实现:

类似于以下内容:

ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
externalContext.redirect(externalContext.encodeResourceURL(externalContext.getRequestContextPath()+getUrl()));

0

java.lang.IllegalStateException: Cannot forward after response has been committed

这个异常非常明确:

  • 响应已经被提交。
  • 在响应被提交后,您不能进行转发操作。

什么不合理呢?


0

登录重定向描述的逻辑应该通过过滤器机制实现。您还可以尝试使用标准jsf导航规则(如果它适用于您的情况)。如果您仍然想要将重定向发送到自定义URL,并且不想使用过滤器,请在呈现阶段的servlet中执行,而不是在jsf bean中执行。


0

您没有描述您在身份验证方面使用的任何框架设施,因此我假设您在自己的代码中执行身份验证。可能,最简单的方法是在重定向到登录页面之前在会话中保存初始目标,然后在成功登录后,您可以检查此属性并重定向到正确的位置。 特别是对于JSF,您可以在处理登录的操作方法中执行此操作。 实际上,我建议使用一些身份验证框架,例如Spring Security,因为它可以直接完成这些事情,并且在需要某些其他功能时扩展安全系统将更加容易,尽管它需要一些额外的配置。


Seam还允许您直接完成此操作。 - mtpettyp
我正在使用JSF和Filter来检查会话是否为空,如果为空,则将用户重定向到登录页面。 - Hoe Chin

-2

你太晚了,这导致了异常。在渲染响应阶段之前,在phaselistener中完成它。


-2
将以下语法放置在 web.xml 中应该可以工作:
<context-param>
<param-name>com.sun.faces.writeStateAtFormEnd</param-name>
<param-value>false</param-value>
</context-param>

这是针对一种不同原因的解决方案,恰好导致了类似(但并非完全相同!)的异常。另请参阅https://dev59.com/nGsz5IYBdhLWcg3wLUt2#8072445。 - BalusC

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