使用JSF 2.0 / Facelets,有没有办法将全局侦听器附加到所有AJAX调用?

有没有办法将全局侦听器附加到JSF中的所有AJAX调用? 也许通过阶段听众或其他什么?

这是一个难题…让我们说你正在使用f:ajax标签和apache shiro之类的东西,你让你的会话到期。 然后你回来并点击一个附有f:ajax的按钮。 服务器将以302重定向响应登录页面。

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

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

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

有没有办法将全局侦听器附加到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("") .printf("", url); 

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

      

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

在ajax调用重定向发送不是上面因此没有重定向。

为了获得所需的结果,所有jsf请求都有一个filter,除了几页(登录页面)和检查会话是有效的,如果通过检查标题“Faces-Request”真的是jsf ajax调用,它的值应该是“partial / ajax” 。 如果会话已过期且是ajax请求,则将以上xml作为响应发送。

它应该工作。