Почему FullAjaxExceptionHandler не просто выполняет ExternalContext#redirect()?

В OmniFaces FullAjaxExceptionHandler, после того как он нашел нужную страницу с ошибкой для использования, вызывает среду выполнения JSF для построения представления и его рендеринга вместо страницы, содержащей вызов AJAX.

Почему это? ИМХО было бы проще просто выполнить ExternalContext#redirect()? Есть ли конкретные причины для этого?

Мы пишем наш собственный ExceptionHandler на основе FullAjaxExceptionHandler и хотели понять причину этого дизайна.

1 ответ

Решение

Основная цель FullAjaxExceptionHandler позволяет исключениям во время запросов ajax вести себя точно так же, как исключения во время запросов не-ajax. Разработчик должен иметь возможность повторно использовать страницы ошибок в обоих условиях, не беспокоясь о состоянии при реализации страниц ошибок.

Перенаправление не является частью обычного потока во время не-AJAX-запросов. По умолчанию <error-page> механизм в web.xml выполняет пересылку для отображения страницы с ошибкой, а не перенаправления. Если перенаправление было выполнено, все атрибуты запроса страницы ошибки, такие как javax.servlet.error.exception потерялся бы и рендерился как null, Более того, обычной практикой является размещение страниц с ошибками в /WEB-INF чтобы конечные пользователи не могли получить к ним прямой доступ (а также сделать закладки и делиться ими). Перенаправление потребовало бы, чтобы они были общедоступными, что указывает на серьезную проблему дизайна (действительно ли целевая страница на самом деле является страницей с реальной ошибкой?).

Если вам действительно нужно выполнить перенаправление на / с вашей страницы ошибок, либо создайте собственный обработчик исключений, который явно вызывает ExternalContext#redirect() и не использует web.xml<error-page> механизм, или добавить <meta http-equiv="refresh" ...> в HTML-заголовок рассматриваемой страницы ошибки ( пример здесь).

Если вы действительно намеревались перенаправить на какую-либо страницу входа, когда ViewExpiredException происходит, тогда вы должны понимать, что существует большая разница между случаями "пользователь не вошел в систему" ​​и "сеанс / представление истекло". Для первых, вы не должны ловить ViewExpiredException но использовать простой фильтр сервлетов, который проверяет, вошел ли пользователь в систему и перенаправляет ли он соответственно задолго до FacesServlet вызывается. Обычная структура аутентификации (JAAS, Shiro, Spring Security и т. Д.) Также работает таким образом.

Смотрите также:

Другие вопросы по тегам