Как добавить сообщения Faces во время @PostConstruct
В режиме поддержки bean @PostConstruct я делаю вызов EJB, который может возвращать некоторые сообщения, которые я хочу отображать на странице, через сообщения p:. Однако, даже если я добавлю FacesMessages, например. FacesContext.getCurrentInstance(). AddMessage (...), p: сообщения не обновляются с помощью FacesMessages.
Если я вместо этого вызываю вызов EJB на действие со страницы (например, пользователь нажимает кнопку на странице, которая вызывает метод, который вызывает EJB, а затем добавляет FacesMessage (s)), а затем показывает messags используя сообщения p: как ожидалось.
Как добавить сообщения Faces во время @PostConstruct и показать их, когда страница первоначально отображается?
код:
Page1Controller.java:
@ManagedBean
public class Page1Controller
{
@PostConstruct
public void init()
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Test Message from @PostConstruct"));
}
public String getValue()
{
return "Some Value";
}
public void triggerMessage(ActionEvent event)
{
FacesContext.getCurrentInstance().addMessage(null,
new FacesMessage("Test Message from Trigger Button"));
}
}
page1.xhtml
<h:form>
<p:messages showDetail="true" showSummary="true" autoUpdate="true"/>
<h:outputText value="#{page1Controller.value}"/>
<br/>
<p:commandButton value="Trigger Message"
actionListener="#{page1Controller.triggerMessage}"/>
</h:form>
Ответы
Ответ 1
В вашем конкретном примере <p:messages>
отображается прежде, чем управляемый bean будет создан в первый раз. Это слишком поздно, чтобы добавить сообщение. Ваш bean создается в первый раз, когда значение <h:outputText>
оценивается во время рендеринга.
Вам нужно как-то убедиться, что bean будет создан до отображения <p:messages>
. В вашем конкретном примере вы можете достичь этого, например, перемещая <h:outputText>
до <p:messages>
. Или, добавив <f:viewAction>
или <f:event type="preRenderView">
, которые вызываются перед всем рендерингом, как вы сами узнали. Кстати, добавление сообщения не обязательно должно происходить в методе слушателя.
См. также:
Ответ 2
Вы можете собрать ошибку, а затем отобразить ее в конце загрузки страницы с помощью remoteCommand из-за поверхностей с autorun = true.
В моем случае у меня есть viewScope, а в xhtml я показываю список значений, которые загружаются в @PostConstruct. Если генерируется исключение, я сохраню его в примере в конце загрузки страницы, если он существует с помощью remoteCommand.
private ArrayList<Exception> postConstucError = new ArrayList<>();
@PostConstruct
public void validarAcceso() {
/**
* verificar permisos a la vista de coeficientes
*/
try {
this.init() //load data;
} catch (Exception e) {
System.out.print(e.getMessage());
this.postConstucError.add(e);
}
}
public void showPostConstructError() {
try {
for (int i = 0; i < this.postConstucError.size(); i++) {
JsfUtil.addErrorMessage("Error al cargar datos iniciales: " + postConstucError.get(i).getMessage());
}
} catch (Exception e) {
JsfUtil.addErrorMessage(e, "Error: showPostConstructError() " + e.getMessage());
}
}
xhtml code
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true"/>
<h:form>
<p:remoteCommand id="rcomerror" name="showError" process="@this" autoRun="true"
actionListener="#{mBPresentNinos.showPostConstructError()}" />
</h:form>