h: действие commandButton вызывается только один раз при двух вызовах - PullRequest
3 голосов
/ 24 мая 2011

Я использую JSF 1.2 в своем веб-приложении.На моей странице test.xhtml у меня есть форма, содержащая такую ​​кнопку commandButton:

<h:form>
  <h:commandButton action="#{myBean.myMethod}" value="Call my method" />
</h:form>

В исходном коде Java мой компонент выглядит так:

public class MyBean {
  public void myMethod() {
    System.out.println("my method called");
  }
}

Когда я отображаю свою страницуtest.xhtml, при первом нажатии на командную кнопку действие запускается хорошо.Страница обновлена.Затем я пытаюсь нажать на командную кнопку, и действие не вызывается.Это как если бы жизненный цикл JSF перешел в фазу RENDER_RESPONSE напрямую, не вызывая фазу INVOKE_APPLICATION.

Страница обновляется, а затем, когда я нажимаю, действие хорошо запускается.Итак, действие вызывается один раз на два.

Чтобы попытаться понять, я добавил слушателя фазы очень просто:

public class MyPhaseListener implements PhaseListener{

public PhaseId getPhaseId() {
    return PhaseId.ANY_PHASE;
}

public void beforePhase(PhaseEvent event) {
    System.out.println("START PHASE " + event.getPhaseId());
}

public void afterPhase(PhaseEvent event) {
    System.out.println("END PHASE " + event.getPhaseId());
}}

Когда я запускаю тесты, нажимаю на мою страницу, у меня есть следующий вывод:

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
END PHASE PROCESS_VALIDATIONS 3
START PHASE UPDATE_MODEL_VALUES 4
END PHASE UPDATE_MODEL_VALUES 4
START PHASE INVOKE_APPLICATION 5
my method called
END PHASE INVOKE_APPLICATION 5
START PHASE RENDER_RESPONSE 6
END PHASE RENDER_RESPONSE 6

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE RENDER_RESPONSE 6
END PHASE RENDER_RESPONSE 6

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE APPLY_REQUEST_VALUES 2
END PHASE APPLY_REQUEST_VALUES 2
START PHASE PROCESS_VALIDATIONS 3
END PHASE PROCESS_VALIDATIONS 3
START PHASE UPDATE_MODEL_VALUES 4
END PHASE UPDATE_MODEL_VALUES 4
START PHASE INVOKE_APPLICATION 5
my method called
END PHASE INVOKE_APPLICATION 5
START PHASE RENDER_RESPONSE 6
END PHASE RENDER_RESPONSE 6

START PHASE RESTORE_VIEW 1
END PHASE RESTORE_VIEW 1
START PHASE RENDER_RESPONSE 6
END PHASE RENDER_RESPONSE 6

Используя PhaseListener, я ясно вижу, что во втором вызове каждый раз жизненный цикл переходит в фазу RESTORE_VIEW в RENDER_RESPONSE напрямую, без участия моей части в жизненном цикле.

Кто-то должен был бы и подумать, чтобы этого избежатьи выполнить жизненный цикл в каждый раз для этой страницы?Или решение для выполнения действия каждый раз, когда я нажимаю на командную кнопку?

Как вы сказали мне, я добавляю отладочную информацию к отпечаткам, например, объект UIViewRoot и идентификатор сеанса.Последовательность действий теперь дает следующую информацию:

START PHASE RESTORE_VIEW 1
UIViewRoot :null
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RESTORE_VIEW 1
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE APPLY_REQUEST_VALUES 2
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE APPLY_REQUEST_VALUES 2
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE PROCESS_VALIDATIONS 3
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE PROCESS_VALIDATIONS 3
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE UPDATE_MODEL_VALUES 4
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE UPDATE_MODEL_VALUES 4
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE INVOKE_APPLICATION 5
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
my method called
END PHASE INVOKE_APPLICATION 5
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7cbcb4
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7


START PHASE RESTORE_VIEW 1
UIViewRoot :null
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RESTORE_VIEW 1
UIViewRoot :javax.faces.component.UIViewRoot@7cbaea
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7cbaea
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7cbaea
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7


START PHASE RESTORE_VIEW 1
UIViewRoot :null
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RESTORE_VIEW 1
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE APPLY_REQUEST_VALUES 2
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE APPLY_REQUEST_VALUES 2
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE PROCESS_VALIDATIONS 3
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE PROCESS_VALIDATIONS 3
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE UPDATE_MODEL_VALUES 4
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE UPDATE_MODEL_VALUES 4
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE INVOKE_APPLICATION 5
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
my method called
END PHASE INVOKE_APPLICATION 5
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7ccfa1
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7


START PHASE RESTORE_VIEW 1
UIViewRoot :null
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RESTORE_VIEW 1
UIViewRoot :javax.faces.component.UIViewRoot@7cac2f
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
START PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7cac2f
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7
END PHASE RENDER_RESPONSE 6
UIViewRoot :javax.faces.component.UIViewRoot@7cac2f
Session ID : 8385AC329B4C75AB4FBCA2CE1FBDFDC7

Сеанс всегда одинаков для каждой последовательности вызовов.Так что я не думаю, что это проблема UIViewRoot.Есть ли другие вещи, которые я могу сделать, чтобы проверить проблему?

Сильвен.

1 Ответ

1 голос
/ 24 мая 2011

Если вы не читали эту статью в блоге, вам следует: http://balusc.blogspot.com/2006/09/debug-jsf-lifecycle.html

Похоже, вы теряете сеанс, так как UIViewRoot не существует и, следовательно, нет UIViewRoot для восстановления.

...