【问题标题】:Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?使用 JSF 2.0 / Facelets,有没有办法将全局侦听器附加到所有 AJAX 调用?
【发布时间】:2012-03-07 11:44:02
【问题描述】:

有没有办法将全局侦听器附加到 JSF 中的所有 AJAX 调用?也许通过相位侦听器之类的?

这是一个难题...假设您正在使用 f:ajax 标签和类似 apache shiro 的东西,并且您让会话过期。然后您返回并单击一个附加了 f:ajax 的按钮。服务器将响应 302 重定向到登录页面。

用户什么也看不到。他们可以反复单击并调用 ajax 调用,但对他们来说,应用程序只是“死”了。

那么,我的想法是,有没有办法将侦听器附加到 JSF 中的所有 ajax 调用?如果是这样,我想做的是监视响应代码。如果是重定向,请使用 window.navigate 将它们沿途发送。

我总是乐于倾听其他人如何解决这个问题!

【问题讨论】:

标签: java ajax redirect jsf-2 listener


【解决方案1】:

有没有办法将全局侦听器附加到 JSF 中的所有 AJAX 调用?也许通过相位监听器或其他方式?

是的,PhaseListener 可以做到。 SystemEventListener 也是。还有Filter

如果您在 JSF 上下文中,则可以如下检查当前请求是否为 ajax 请求。

if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
    // It's an ajax request.
}

如果您不在 JSF 上下文中,例如在Filter里面,那么你可以如下检查当前请求是否是JSF ajax请求。

if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
    // It's a JSF ajax request.
}

这是一个难题...假设您正在使用 f:ajax 标签和类似 apache shiro 的东西,并且您让会话过期。然后您返回并单击一个附加了 f:ajax 的按钮。服务器将响应 302 重定向到登录页面。

用户什么也看不到。他们可以反复单击并调用 ajax 调用,但对他们来说,应用程序只是“死机”。

在 ajax 请求上强制重定向需要特殊的 XML 响应。当您在 JSF 上下文中时,ExternalContext#redirect() 已经隐含地考虑了这一点。你需要做的就是写这个:

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

如果您不在 JSF 上下文中,例如在Filter 中,那么您需要自己编写整个 XML 响应。例如

response.setContentType("text/xml");
response.getWriter()
    .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
    .printf("<partial-response><redirect url=\"%s\"></redirect></partial-response>", url);

【讨论】:

  • T所以我猜最佳路线是编写一个位于 Shiro 过滤器前面的过滤器。当 Shiro 发送重定向时,我的过滤器将拦截它并发送 XML。我觉得我无法在 Faces 应用程序中执行此操作,因为 Shiro 会阻止请求。
  • 那么你最好的选择确实是在 Shiro 过滤器前面加一个过滤器。
  • 为了您的信息,我写了一篇关于这个案例的博客,并为 Shiro 提供了一个完整的即用型过滤器:balusc.blogspot.com/2013/01/…
【解决方案2】:

要重定向 jsf ajax 请求,您需要 xml,如下所示

<?xml version="1.0" encoding="UTF-8"?>   
<partial-response>  
      <redirect url="XXX">  
      </redirect>  
</partial-response>

这里的 XXX 是您希望发生重定向的网址。

在 ajax 调用上发送的重定向与上面不同,因此没有重定向。

为了得到想要的结果,对所有 jsf 请求都有一个过滤器,除了少数 页面(登录页面)并检查会话是否有效,如果它真的是 jsf 通过检查标头“Faces-Request”进行ajax调用,其值应为 “部分/ajax”。如果会话已过期并且是上面发送的 ajax 请求 xml 作为响应。

它应该工作。

【讨论】:

猜你喜欢
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
相关资源
最近更新 更多