简体   繁体   English

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

[英]Using JSF 2.0 / Facelets, is there a way to attach a global listener to all AJAX calls?

Is there a way to attach a global listener to all AJAX calls in JSF? 有没有办法将全局侦听器附加到JSF中的所有AJAX调用? Maybe through a phase listener or something? 也许通过阶段听众或其他什么?

Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. 这是一个难题...让我们说你正在使用f:ajax标签和像apache shiro之类的东西,你让你的会话到期。 Then you come back and click a button that has an f:ajax attached to it. 然后你回来并点击一个附有f:ajax的按钮。 The server will respond with a 302 redirect to the login page. 服务器将以302重定向响应登录页面。

The user sees nothing. 用户什么也看不见。 They can repeatedly click and invoke the ajax call, but to them the app is just "dead." 他们可以反复点击并调用ajax调用,但对他们来说应用程序只是“死了”。

So, my though is, is there a way to attach a listener to all ajax calls in JSF? 所以,我的问题是,有没有办法将监听器附加到JSF中的所有ajax调用? If so, what I'd like to do is monitoring the response code. 如果是这样,我想做的是监控响应代码。 If it's a redirect, use a window.navigate to send them along their way. 如果是重定向,请使用window.navigate沿途发送它们。

I'm always open to hear how others have solved this problem! 我总是乐于听取其他人如何解决这个问题!

Is there a way to attach a global listener to all AJAX calls in JSF? 有没有办法将全局侦听器附加到JSF中的所有AJAX调用? Maybe through a phase listener or something? 也许通过阶段听众或其他什么?

Yes, a PhaseListener can do it. 是的, PhaseListener可以做到这一点。 A SystemEventListener also. 还有一个SystemEventListener A Filter also. Filter也。

If you're inside JSF context, then you can check as follows whether the current request is an ajax request or not. 如果您在JSF上下文中,那么您可以检查当前请求是否是ajax请求,如下所示。

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

If you're not inside JSF context, eg inside a Filter , then you can check as follows whether the current request is a JSF ajax request or not. 如果你不在JSF上下文中,例如在Filter ,那么你可以检查当前请求是否是JSF ajax请求。

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

Here is the conundrum... Lets say you're using f:ajax tags and something like apache shiro and you let your session expire. 这是一个难题...让我们说你正在使用f:ajax标签和像apache shiro之类的东西,你让你的会话到期。 Then you come back and click a button that has an f:ajax attached to it. 然后你回来并点击一个附有f:ajax的按钮。 The server will respond with a 302 redirect to the login page. 服务器将以302重定向响应登录页面。

The user sees nothing. 用户什么也看不见。 They can repeatedly click and invoke the ajax call, but to them the app is just "dead." 他们可以反复点击并调用ajax调用,但对他们来说应用程序只是“死了”。

Forcing a redirect on an ajax request requires a special XML response. 强制重定向ajax请求需要特殊的XML响应。 When you're inside JSF context, then ExternalContext#redirect() already takes this implicitly into account. 当你在JSF上下文中时, ExternalContext#redirect()已经隐含地考虑了这一点。 All you need to do is to write this: 你需要做的就是写这个:

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

If you're not inside JSF context, eg inside a Filter , then you'd need to write the whole XML response yourself. 如果您不在JSF上下文中,例如在Filter ,那么您需要自己编写整个XML响应。 Eg 例如

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

To redirect a jsf ajax request you need xml as follows 要重定向jsf ajax请求,您需要xml,如下所示

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

Here XXX is url you want redirect to happen. 这里XXX是你想重定向发生的网址。

On ajax call redirect sent is not as above hence no redirect. 在ajax调用重定向发送不是上面因此没有重定向。

To get the desired result have a filter for all jsf request except few pages(login page) and check session is valid and if it is really jsf ajax call by checking header "Faces-Request", its value should be "partial/ajax". 为了获得所需的结果,除了几个页面(登录页面)和检查会话有效之外,所有jsf请求都有一个过滤器,如果通过检查标题“Faces-Request”确实是jsf ajax调用,则其值应为“partial / ajax” 。 If session has expired and is ajax request send above xml as response. 如果会话已过期并且是ajax请求,则将上面的xml作为响应发送。

It should work. 它应该工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM