Есть ли способ присоединить глобальный слушатель ко всем вызовам AJAX в JSF?Может быть, через фазовый слушатель или что-то еще?
Да, PhaseListener
может это сделать.A SystemEventListener
также.A Filter
также.
Если вы находитесь в контексте JSF, вы можете проверить следующим образом, является ли текущий запрос ajax-запросом или нет.
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// It's an ajax request.
}
Если вы находитесь вне контекста JSF, например, внутри Filter
, вы можете проверить следующим образом, является ли текущий запрос ajax-запросом JSF.
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);