如何在 JSF ajax 侦听器方法中导航/重定向

How to navigate / redirect in JSF ajax listener method

我有这个可选择的 PrimeFaces 树,在我的 index.xhtml 中选择了一个 Ajax 侦听器:

<p:tree value="#{seccionesArbolView.root}" var="node" selectionMode="single" >
    <p:treeNode>
        <h:outputText value="#{node.nombre}" />
    </p:treeNode>
    <p:ajax event="select" listener="#{seccionesArbolView.onNodeSelect}"></p:ajax>
</p:tree>                    

侦听器方法在会话范围内的命名 bean 上,应该使用一些 GET 参数重定向到另一个页面 (grupal.xhtml)。我试过这个:

public String onNodeSelect(NodeSelectEvent event) throws IOException {
    Seccion sec = (Seccion) event.getTreeNode().getData();
    String enlace = "grupal.xhtml?faces-redirect=true&id=" + sec.getId() + "&nombre=" + sec.getNombre();
    return enlace;
}

但是没有任何反应。我在另一个问题中读到这可能是因为 Ajax 请愿书,所以我尝试使用 ExternalContext:

public String onNodeSelect(NodeSelectEvent event) throws IOException {
    Seccion sec = (Seccion) event.getTreeNode().getData();
    FacesContext context = FacesContext.getCurrentInstance();
    String enlace = "faces/grupal.xhtml?id=" + sec.getId() + "&nombre=" + sec.getNombre();
    context.getExternalContext().redirect(enlace);
    context.responseComplete();
}

这种方法的问题在于 link 的构造。它的完成方式(使用 "faces" 前缀)有效,但每次单击树时 URL 不断变大,并添加另一个 "faces/"(例如 http://localhost:8080/MyApp/faces/faces/faces/grupal.xhtml?.. .) 并且 Glassfish 发出警告 Request path '/faces/faces/grupal.xhtml' begins with a or more occurrences of the FacesServlet prefix path mapping '/faces'

如果构建 link 时没有 "faces/" 前缀:

String enlace = "grupal.xhtml?id=" + sec.getId() + "&nombre=" + sec.getNombre();

有效,前提是通过URL访问index.html http://localhost:8080/MyApp/faces/index.xhtml. But when index.html is accessed through the base URL http://localhost:8080/MyApp/,显然找不到grupal.xhtml。

我不确定在这种情况下最好的解决方案是什么。

有没有办法使用 JSF 2.0 导航(第一种方法,我无法开始工作)来做到这一点?

有没有办法让整个基础URL用绝对路径进行重定向?

有没有办法告诉 Glassfish 重定向基础 URL http://localhost:8080/MyApp/ to http://localhost:8080/MyApp/faces/index.xhtml

I tried this:

return enlace;

but nothing happens.

您确实可以 notlistener/actionListener 方法导航。您只能从 action 方法导航。

另请参阅:

  • Differences between action and actionListener


Is there a way to do this with JSF 2.0 navigation (the first approach, that I cannot get to work)?

您可以使用 NavigationHandler#handleNavigation() 以编程方式执行导航。

public void onNodeSelect(NodeSelectEvent event) {
    // ...
    String outcome = "grupal.xhtml?faces-redirect=true&id=" + sec.getId() + "&nombre=" + sec.getNombre();
    FacesContext context = FacesContext.getCurrentInstance();
    context.getApplication().getNavigationHandler().handleNavigation(context, null, outcome);
}

另请参阅:

  • How to make redirect using navigation-rule


Is there a way to get the whole base URL to make the redirection with an absolute path?

您可以使用 ExternalContext#getRequestContextPath().

以编程方式获取上下文路径
public void onNodeSelect(NodeSelectEvent event) throws IOException {
    // ...
    String uri = "/faces/grupal.xhtml?id=" + sec.getId() + "&nombre=" + sec.getNombre();
    ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
    ec.redirect(ec.getRequestContextPath() + uri);
}

另请参阅:

  • ExternalContext#redirect() does not redirect to parent directory


Is there a way to tell Glassfish to redirect the base URL http://localhost:8080/MyApp/ to http://localhost:8080/MyApp/faces/index.xhtml ?

index.xhtml 上的 web.xml 中使用 <welcome-file> 并用 JSF 2.0 样式 [=23] 替换 /faces/* 的笨拙的 JSF 1.0 样式 FacesServlet 映射=].

另请参阅:

  • JSF welcome file is not recognized
  • Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?