JSF导航重定向到上一页

JSF navigation redirect to previous page

用户成功登录系统后,系统会将用户重定向到主页。 现在我的问题是,如果用户单击视图帐户页面而不登录到系统,则系统会将用户重定向到登录页面。 如果现在用户登录到系统,系统会将用户重定向到首页,在这种情况下,有什么方法可以将用户重定向到上一个页面,即查看帐户页面而不是首页?

我尝试使用会话

1
2
3
4
5
String url = (String)session.getAttribute("url");
if(url != null)
    response.sendRedirect(url);
else
    response.sendRedirect("homepage.faces");

如果用户登录成功,我会将这段代码放在public void doBtnAction(){}下,然后重定向到url。 但是我得到这个错误

1
2
3
4
5
6
7
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)

造成此异常的原因是,您调用了response.sendRedirect()并且没有阻止JSF呈现正常响应。您需要通过添加以下内容通知JSF不需要处理正常响应:

1
FacesContext.getCurrentInstance().responseComplete();

行动方法。

或者,甚至更好的是,不要从JSF的幕后拿到HttpServletResponse,而是这样做:

1
FacesContext.getCurrentInstance().getExternalContext().redirect(url);

这将自动调用responseComplete(),还可以使您的代码远离不必要的Servlet API。另请参见ExternalContext API。


不确定,但是尝试通过ExternalContext工具执行此操作:

像这样:

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

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


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

异常非常清楚:

  • 响应已提交。
  • 提交响应后,您将无法转发。

没有什么意义?


您尚未描述用于身份验证的任何框架功能,因此我假设您以自己的代码执行身份验证。可能最简单的方法是在重定向到登录页面之前在会话中保存初始目标,然后在成功登录后可以检查此属性并重定向到正确的位置。
我特别喜欢JSF,您可以在处理登录的实际方法中执行此操作。
实际上,我建议使用某种框架进行身份验证,例如Spring Security,因为它开箱即用,并且在需要一些附加功能的情况下扩展安全系统会容易得多,尽管它需要一些附加功能。附加配置


将以下语法放在web.xml中应该可以工作:

1
2
3
4
<context-param>
<param-name>com.sun.faces.writeStateAtFormEnd</param-name>
<param-value>false</param-value>
</context-param>


你来不及了,那给了你例外。在渲染响应阶段之前,在相位侦听器中执行此操作。