Страница ошибки ViewExpiredException не отображается
Я оставляю некоторые вкладки открытыми с формами, и когда я нажимаю кнопки команд (через некоторое время, когда сеанс заканчивается), я получаю предупреждение java-скрипта, говорящее:
serverError: класс javax.faces.application.ViewExpiredException viewId: /register.xhtml - представление /register.xhtml не может быть восстановлено.
На Firefox (Glassfish 4 локально)
Я добавил:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/index.xhtml?faces-redirect=true</location>
</error-page>
в моем web.xml
но я не перенаправлен на мой индекс. Это почему?
Изменить: образец кнопки
<h:commandButton value="Register" action="#{userController.register}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
UserController является ViewScoped
2 ответа
Это ожидаемое поведение, если вы посмотрите на разделы 13.3.6.3 и 13.3.6.4 спецификации JSF-2.2, по крайней мере, если у вас есть
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
в вашем web.xml
(он молча игнорирует ошибку в производственном режиме). Код JSF на стороне клиента отправляет запрос AJAX при нажатии этой кнопки и получает
<error>
<error-name>...</error-name>
<error-message>...</error-message>
</error>
с вашим ViewExpiredException
в ответ. Ожидается, что клиентский код будет реагировать на эту информацию об ошибке. Зарегистрировать функцию с onerror
(на f:ajax
тег) или addOnError
(на jsf.ajax
объект), чтобы справиться с ошибкой самостоятельно.
Поскольку многие люди ожидают, что сервер направит клиента на такую проблему, omnifaces включает в себя FullAjaxExceptionHandler, который в основном сбрасывает ваш ответ и отправляет указанную вами страницу ошибки.
Смотрите также:
Тайм-аут сеанса и обработка ViewExpiredException при запросе JJF/PrimeFaces ajax
Попробуйте этот подход для обработки истечения срока действия представления: создайте следующие 2 класса в своем проекте
import javax.faces.context.ExceptionHandler;
import javax.faces.context.ExceptionHandlerFactory;
public class ViewExpiredExceptionExceptionHandlerFactory extends
ExceptionHandlerFactory {
private ExceptionHandlerFactory parent;
public ViewExpiredExceptionExceptionHandlerFactory(
ExceptionHandlerFactory parent) {
this.parent = parent;
}
@Override
public ExceptionHandler getExceptionHandler() {
return new ViewExpiredExceptionExceptionHandler(
parent.getExceptionHandler());
}
}
а также
public class ViewExpiredExceptionExceptionHandler extends
ExceptionHandlerWrapper {
private ExceptionHandler wrapped;
public ViewExpiredExceptionExceptionHandler(ExceptionHandler wrapped) {
this.wrapped = wrapped;
}
@Override
public ExceptionHandler getWrapped() {
return this.wrapped;
}
@Override
public void handle() throws FacesException {
for (Iterator<ExceptionQueuedEvent> i =
getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
ExceptionQueuedEvent event = i.next();
ExceptionQueuedEventContext context = (ExceptionQueuedEventContext)
event.getSource();
Throwable t = context.getException();
if (t instanceof ViewExpiredException) {
ViewExpiredException vee = (ViewExpiredException) t;
FacesContext facesContext = FacesContext.getCurrentInstance();
Map<String, Object> requestMap = facesContext
.getExternalContext().getRequestMap();
NavigationHandler navigationHandler = facesContext
.getApplication().getNavigationHandler();
try {
// Push some useful stuff to the request scope for use in
// the page
requestMap.put("currentViewId", vee.getViewId());
navigationHandler.handleNavigation(facesContext, null,
"/index");
facesContext.renderResponse();
} finally {
i.remove();
}
}
}
// At this point, the queue will not contain any ViewExpiredEvents.
// Therefore, let the parent handle them.
getWrapped().handle();
}
}
В Face-config.xml добавить следующие строки:
<factory>
<exception-handler-factory>path.to.class.ViewExpiredExceptionExceptionHandlerFactory</exception-handler-factory>
И все, ты идешь в путь.
РЕДАКТИРОВАТЬ
Хорошо, я забыл о способе Omnifaces сделать это, я не использую это, потому что, как только вы установите страницу для ошибки, она предупреждает вас сделать страницы для 404 и еще один, который я сейчас не помню. Вы должны добавить в ваши лица-config.xml следующее:
<factory>
<exception-handler-factory>org.omnifaces.exceptionhandler.FullAjaxExceptionHandlerFactory</exception-handler-factory>
и ваш код будет работать. Для получения дополнительной информации см. Демонстрацию FullAjaxExceptionHandlerFactory с веб-сайта omnifaces http://showcase.omnifaces.org/exceptionhandlers/FullAjaxExceptionHandler;jsessionid=sOwX0FVqcY-InUhvDWEMksfQ.
Не забудьте добавить в свой проект необходимую банку.