Ответ 1
Есть ли способ подключить глобальный прослушиватель ко всем вызовам AJAX в JSF? Может быть, через слушателя фазы или что-то в этом роде?
Да, PhaseListener
может это сделать. A SystemEventListener
. A Filter
.
Если вы находитесь внутри контекста JSF, вы можете проверить, будет ли текущий запрос ajax-запросом или нет.
if (FacesContext.getCurrentInstance().getPartialViewContext().isAjaxRequest()) {
// It an ajax request.
}
Если вы не находитесь в контексте JSF, например. внутри a Filter
, тогда вы можете проверить, будет ли текущий запрос JSF-запросом ajax или нет.
if ("partial/ajax".equals(request.getHeader("Faces-Request"))) {
// It a JSF ajax request.
}
Вот головоломка... Допустим, вы используете теги f: ajax и что-то вроде apache shiro, и вы позволяете истечь вашей сессии. Затем вы вернетесь и нажмите кнопку с прикрепленным к ней f: ajax. Сервер ответит перенаправлением 302 на страницу входа.
Пользователь ничего не видит. Они могут многократно нажимать и вызывать вызов ajax, но для них приложение просто "мертво".
Принудительное перенаправление по запросу ajax требует специального ответа XML. Когда вы находитесь в контексте JSF, ExternalContext#redirect()
уже учитывает это неявно. Все, что вам нужно сделать, это написать следующее:
FacesContext.getCurrentInstance().getExternalContext().redirect(url);
Если вы не находитесь в контексте JSF, например. внутри a 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);