【问题标题】:How to use ExternalContext.redirect() in JSF2.0?如何在 JSF2.0 中使用 ExternalContext.redirect()?
【发布时间】:2010-09-16 13:26:38
【问题描述】:

考虑一个页面webapp/myPage.xhtml

...
<h:form id="myForm">
    ...
    <h:selectOneMenu id="..." required="true" value="#{myController.aValue}">
       <f:selectItems value="#{...}" var="..." itemValue="#{...}" itemLabel="#{...}"/>
    </h:selectOneMenu>
    ...
    <h:commandButton value="Go for it!" action="#{myController.goForIt(...)}"/>
    ...
</h:form>
...

按钮动作绑定到控制器方法MyController.goForIt()

@ManagedBean(name = "myController")
@RequestScoped
public class MyController {
   public String goForIt(...){
      if (myCondition){
         try {
            FacesContext.getCurrentInstance().getExternalContext()
                        .redirect("http://www.myTarget.com/thePage.html");
         } catch (IOException e) {
           ...
         }
      }
      return "myPage.xhtml"   
   }
}

我的第一个问题是:上面说的有意义吗?这是使用 redirect() 的正确方法吗?

如果myCondition 为真,我想将用户重定向到http://www.myTarget.com/thePage.html。如果myCondition 为假,他将不得不留在myPage.xhtml

如果是这样,我想更好地了解会发生什么...在 Firefox 中使用 Live HTTP Headers 时,我观察到单击按钮时会发生这种情况

  1. 一个 POST 到 webapp/myPage.xhtml 发生
  2. 服务器回复 302 已临时移动 - 位置:www.myTarget.com/thePage.html
  3. 浏览器 GET 的 www.myTarget.com/thePage.html

到目前为止,这是预期的行为吗?

我现在觉得烦人的是 webapp/myPage.xhtml 被调用了。更具体地说,这里再次调用了 preRenderView 事件。 (我在 preRenderView-listener 中有一些代码应该只执行一次。)

上面说的有道理吗?有没有人看到改进的方法?

谢谢! J.

【问题讨论】:

    标签: java jsf jsf-2


    【解决方案1】:

    到目前为止,这是预期的行为吗?

    重定向基本上指示客户端在Location 响应标头中指定的URL 上触发new HTTP 请求。所以是的,你看到的行为是正确的。

    但是,您的网址错误。它与当前请求 URL 相关。所以如果当前 URL 是例如http://example.com/context/page.jsf,那么这个重定向基本上会指向http://example.com/context/www.myTarget.com/thePage.html,这显然是错误的。当新 URL 涉及不同的域时,您应该重定向到 absolute URL。换句话说,在它前面加上 http:// 方案。

    我现在觉得烦人的是 webapp/myPage.xhtml 被调用了。

    理论上,当重定向发生时,这不应该发生。尝试将return null 添加到try 块中。

    【讨论】:

    • 谢谢 BalusC。您对重定向 URL 是正确的。我实际上使用的是绝对 URL。我过分简化了我的例子。 (现在在原始问题中修复它。)
    • 有趣的是,您说在重定向期间不应再次调用 preRenderView。我尝试在重定向后return null,但这并没有真正改变行为。
    • 它不只是在重定向之前调用了 并且您错误地解释/调试了它吗?您即提交到同一页面,并且 bean 是请求范围的。
    • 理论上,制作 bean @ViewScoped 并将逻辑放入 bean 的构造函数或 @PostConstruct 应该可以实现您想要的。
    • 好的,我明白你的意思了。好吧,也许您想检查FacesContext#isPostback() 以确定它是否是回发(POST 请求),如果不是,则持久化它们。
    猜你喜欢
    • 2011-09-11
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 2012-08-10
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多