如何在 JSF ajax 监听器方法中导航/重定向
Posted
技术标签:
【中文标题】如何在 JSF ajax 监听器方法中导航/重定向【英文标题】:How to navigate / redirect in JSF ajax listener method 【发布时间】:2015-08-08 00:10:19 【问题描述】:我的 index.xhtml 中有这个可选择的 PrimeFaces 树,带有一个 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();
这种方法的问题在于链接的构建。它的完成方式(带有“faces”前缀)有效,但是每次单击树时,URL 都会变得越来越大,并添加另一个“faces/”(例如http://localhost:8080/MyApp/faces/faces/faces/grupal.xhtml?...)并且 Glassfish 发出警告 请求路径“/faces/faces/grupal.xhtml”以一次或多次出现的 FacesServlet 前缀路径映射“/faces”开始
如果链接的构造没有“faces/”前缀:
String enlace = "grupal.xhtml?id=" + sec.getId() + "&nombre=" + sec.getNombre();
只要通过 URL http://localhost:8080/MyApp/faces/index.xhtml 访问 index.html,它就可以工作。但是当通过基本 URL http://localhost:8080/MyApp/ 访问 index.html 时,显然找不到 grupal.xhtml。
我不确定在这种情况下最好的解决方案是什么。
有没有办法通过 JSF 2.0 导航来做到这一点(第一种方法,我无法开始工作)?
有没有办法获取整个基本 URL 以使用绝对路径进行重定向?
有没有办法告诉 Glassfish 将基本 URL http://localhost:8080/MyApp/ 重定向到 http://localhost:8080/MyApp/faces/index.xhtml ?
【问题讨论】:
【参考方案1】:我试过这个:
return enlace;
但什么也没发生。
您确实可以不从listener
/actionListener
方法导航。您只能从 action
方法导航。
另见:
Differences between action and actionListener有没有办法通过 JSF 2.0 导航来做到这一点(第一种方法,我无法开始工作)?
您可以使用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有没有办法获取整个基本 URL 以使用绝对路径进行重定向?
您可以使用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有没有办法告诉 Glassfish 将基本 URL http://localhost:8080/MyApp/ 重定向到 http://localhost:8080/MyApp/faces/index.xhtml ?
在index.xhtml
上的web.xml
中使用<welcome-file>
,并将/faces/*
的尴尬JSF 1.0 样式FacesServlet
映射替换为JSF 2.0 样式*.xhtml
。
另见:
JSF welcome file is not recognized Sometimes I see JSF URL is *.jsf, sometimes *.xhtml and sometimes /faces/*. Why?【讨论】:
谢谢,我试试。两种方式之间有任何技术差异,还是只是风格问题? 导航处理程序是抽象的,因此可以使用自定义处理程序进行配置,也可以通过 faces 配置覆盖。重定向是“硬编码”的。以上是关于如何在 JSF ajax 监听器方法中导航/重定向的主要内容,如果未能解决你的问题,请参考以下文章
在 servlet 过滤器中使用请求参数将 JSF ajax 请求重定向到 URL
当发送的请求是 Ajax 请求时,如何从 ManagedBean 重定向?
JSF2 <h:selectOneMenu 和 <f:ajax 侦听器在 PrettyFaces 过滤器导航之后未调用