Исключение, выброшенное в @PostConstruct, вызывает IllegalStateException в JSF 2.1 - PullRequest
1 голос
/ 23 марта 2012

У меня есть метод init для моего обработанного bean-компонента @ViewScoped.В пост-конструкции я загружаю данные из базы данных.У меня есть пользовательский ExceptionHandlerWrapper для перехвата всех исключений и отправки на страницы ошибок.Однако, когда @PostConstuct выдает исключение, я получаю исключение IllegalStateException и не перенаправляем на страницу ошибки.Я пробовал много комбинаций .....

Я пробовал это в моем ExcpetionHandler

externalContext.getRequestMap().put(ERROR_BEAN_ID, ERROR_TEXT);
externalContext.dispatch(ERROR_PAGE);
fc.responseComplete();

Эта строка ниже - то, что у меня изначально было.Это также делает работу

externalContext.getFlash().put(ERROR_BEAN_ID, ERROR_TEXT);
nav.handleNavigation(fc, null, ERROR_PAGE);
fc.renderResponse();

Все это вызывает исключения IllegalStateExceptions.Я также вызвал перенаправление с тем же результатом.

Можете ли вы глобально отлавливать ошибки, генерируемые @PostConstruct?

1 Ответ

3 голосов
/ 24 марта 2012

Все это вызывает IllegalStateExceptions.

С сообщением "Ответ уже принят", я полагаю?Ну, это точка невозврата.Часть ответа уже отправлена ​​клиенту (веб-браузеру).Невозможно вернуть уже отправленные байты обратно.Сервер получит это исключение в журналах, а клиент получит полуготовый ответ.

Что вы можете сделать?

Самый простой способ - увеличить размер буфера ответов.до размера самой большой страницы.Например, 64 КБ:

<context-param>
    <param-name>javax.faces.FACELETS_BUFFER_SIZE</param-name>
    <param-value>65536</param-value>
</context-param>

По умолчанию ~ 2 КБ в зависимости от конфигурации сервера.Вам нужно только помнить, что это может привести к перегрузке памяти, когда вашему серверу приходится обрабатывать относительно много запросов / ответов.Профилируйте и измерьте должным образом.

Другой способ - сослаться на bean-компонент до , ответ должен быть обработан / передан так, чтобы его (post) конструкция запускалась до этой точки.Возможно, на рассматриваемый бин впервые ссылаются в самом низу представления, далеко за пределами границы размера ответа ~ 2 КБ.Вы можете взять на себя работу @PostConstruct с <f:event type="preRenderView"> где-нибудь в верхней части представления.Например,

<f:event type="preRenderView" listener="#{bean.init}" />

с

public void init() {
    if (!FacesContext.getCurrentInstance().isPostback()) {
        // Do here your original @PostConstruct job.
    }
}
...