Почему жизненный цикл jsf пропускает ответ при вызове приложения при перенаправлении страницы?

У меня два сценария
У меня есть два действия, которые имеют логику в бобе, как
Мои кнопки

<h:commandButton  value="Submit" action="#{bean.test}" />
<h:commandButton  value="Submit" action="#{bean.testOne}" />

Это две кнопки commnad и логика в бине

public void test() {
    log.info("I m in test");
}

public void testOne() {
    log.info("I m in testOne");
    try {
        FacesContext.getCurrentInstance()
            .addMessage("", new FacesMessage("Record Saved successfully."));
        FacesContext
                .getCurrentInstance()
                .getExternalContext()
                .redirect(
                        FacesContext.getCurrentInstance()
                            .getExternalContext().getRequestContextPath()
                                + "/cycle/page");

    } catch (IOException e) {
        log.error(e.getMessage());
    }
}

Когда я собираюсь нажать на 1-ю кнопку (тестовое действие), то время жизненного цикла JSF переходит к каждой фазе, как
восстановить вид
Применить значения запроса
Проверка процесса
обновить модели
вызвать приложение
сделать ответ
Но когда я нажимаю на кнопку testOne, время jsf жизненного цикла пропускает ответ на рендеринг после вызова приложения, например
восстановить вид
Применить значения запроса
Проверка процесса
обновить модели
вызвать приложение
восстановить вид
сделать ответ

Простым языком. Когда я перемещаюсь по странице через FaceContext, jsf пропускает эту фазу.
Но почему это происходит? Я не понимаю проблемы.

1 ответ

Решение

Согласно документации JSF, это то, что делает фаза INVOKE_APPLICATION:

На этом этапе реализация JavaServer Faces обрабатывает любые события уровня приложения, такие как отправка формы или ссылки на другую страницу.

На этом этапе, если приложению необходимо перенаправить на другой ресурс веб-приложения или сгенерировать ответ, который не содержит компонентов JavaServer Faces, оно может вызвать метод FacesContext.responseComplete.

Если обрабатываемое представление было восстановлено из информации о состоянии из предыдущего запроса и если компонент вызвал событие, эти события передаются заинтересованным слушателям.

Наконец, реализация JavaServer Faces передает управление фазе Render Response.

То, что вы делаете, звонит FacesContext#getCurrentInstance#getExternalContext#redirect на этом этапе, который выполняет ваше перенаправление. Этот метод запускает FacesContext#getCurrentInstance#responseComplete, который завершает жизненный цикл JSF. Перенаправление выполняется в представление JSF, поэтому после этого начинается новый цикл.

Помимо этого и не имеет отношения к конкретной проблеме, не выполняйте такие перенаправления, если вы хотите перенаправить во внутреннее представление JSF. Просто верните навигационный кейс + ?faces-redirect=true в вашем методе действий (т.е. /cycle/page?faces-redirect=true). Используйте внешний контекст, только если вы хотите получить доступ к внешним URL-адресам.

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

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