Как отобразить ошибки моего приложения в JSF? - PullRequest
38 голосов
/ 25 ноября 2008

В моем приложении JSF / Facelets приведена упрощенная версия части моей формы:

<h:form id="myform">
  <h:inputSecret value="#{createNewPassword.newPassword1}" id="newPassword1" />
  <h:message class="error" for="newPassword1" />
  <h:inputSecret value="#{createNewPassword.newPassword2}" id="newPassword2" />
  <h:message class="error" for="newPassword2" />
  <h:commandButton value="Continue" action="#{createNewPassword.continueButton}" />
</h:form>

Я бы хотел иметь возможность назначить ошибку определенному тегу h: message, основываясь на том, что происходит в методе continueButton (). Для newPassword и newPassword2 должны отображаться разные ошибки. Валидатор на самом деле не будет работать, потому что метод, который будет доставлять результаты (из БД), запускается в методе continueButton () и слишком дорог, чтобы запускаться дважды.

Я не могу использовать тег h: messages, потому что на странице есть несколько мест, которые мне нужны для отображения разных сообщений об ошибках. Когда я попробовал это, на странице отображались дубликаты каждого сообщения.

Я попробовал это как лучшую догадку, но не повезло:

public Navigation continueButton() {
  ...
  expensiveMethod();
  if(...) {
    FacesContext.getCurrentInstance().addMessage("newPassword", new FacesMessage("Error: Your password is NOT strong enough."));
  }
}

Чего мне не хватает? Любая помощь будет оценена!

Ответы [ 8 ]

57 голосов
/ 26 ноября 2008

FacesContext.addMessage (String, FacesMessage) требуется clientId компонента , , а не , это id . Если вам интересно, почему, подумайте о том, чтобы иметь элемент управления как дочерний элемент dataTable, выделяя разные значения с одинаковым элементом управления для каждой строки - было бы возможно напечатать различное сообщение для каждой строки. id всегда одинаков; clientId уникален для каждой строки.

Так что «myform: mybutton» - правильное значение, но жесткое кодирование это не рекомендуется. Поиск создаст меньшую связь между представлением и бизнес-логикой и будет подходом, который работает в более ограниченных средах, таких как портлеты.

<f:view>
  <h:form>
    <h:commandButton id="mybutton" value="click"
      binding="#{showMessageAction.mybutton}"
      action="#{showMessageAction.validatePassword}" />
    <h:message for="mybutton" />
  </h:form>
</f:view>

Управляемая логика bean:

/** Must be request scope for binding */
public class ShowMessageAction {

    private UIComponent mybutton;

    private boolean isOK = false;

    public String validatePassword() {
        if (isOK) {
            return "ok";
        }
        else {
            // invalid
            FacesMessage message = new FacesMessage("Invalid password length");
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(mybutton.getClientId(context), message);
        }
        return null;
    }

    public void setMybutton(UIComponent mybutton) {
        this.mybutton = mybutton;
    }

    public UIComponent getMybutton() {
        return mybutton;
    }
}
24 голосов
/ 26 ноября 2008

В случае, если кому-то было любопытно, я смог выяснить это, основываясь на всех ваших ответах вместе взятых!

Это в Facelet:

<h:form id="myform">
  <h:inputSecret value="#{createNewPassword.newPassword1}" id="newPassword1" />
  <h:message class="error" for="newPassword1" id="newPassword1Error" />
  <h:inputSecret value="#{createNewPassword.newPassword2}" id="newPassword2" />
  <h:message class="error" for="newPassword2" id="newPassword2Error" />
  <h:commandButton value="Continue" action="#{createNewPassword.continueButton}" />
</h:form>

Это в методе continueButton ():

FacesContext.getCurrentInstance().addMessage("myForm:newPassword1", new FacesMessage(PASSWORDS_DONT_MATCH, PASSWORDS_DONT_MATCH));

И это работает! Спасибо за помощь!

6 голосов
/ 25 ноября 2008

Вы также должны включить FormID в свой вызов addMessage ().

 FacesContext.getCurrentInstance().addMessage("myform:newPassword1", new FacesMessage("Error: Your password is NOT strong enough."));

Это должно сработать.

С уважением.

4 голосов
/ 11 июля 2012

Помните, что:

FacesContext context = FacesContext.getCurrentInstance();
context.addMessage( null, new FacesMessage( "The message to display in client" ));            

также допустимо, поскольку, если null указано в качестве первого параметра, оно применяется ко всей форме.

Дополнительная информация: coreservlets.com // Устаревший

2 голосов
/ 25 ноября 2008

JSF - зверь. Возможно, я что-то упустил, но раньше я решал подобные проблемы, сохраняя нужное сообщение в свойстве компонента, а затем отображая свойство через outputText:

<h:outputText
    value="#{CreateNewPasswordBean.errorMessage}"
    render="#{CreateNewPasswordBean.errorMessage != null}" />
1 голос
/ 25 ноября 2008

Я попробовал это как лучшую догадку, но не повезло:

Это выглядит правильно для меня. Вы пытались установить серьезность сообщения явно? Также я считаю, что идентификатор должен совпадать с идентификатором компонента (т. Е. Вам нужно будет использовать newPassword1 или newPassword2, если это ваши идентификаторы, а не newPassword, как в примере).

FacesContext.getCurrentInstance().addMessage("newPassword1", 
                    new FacesMessage(FacesMessage.SEVERITY_ERROR, "Error Message"));

Затем используйте <h:message for="newPassword1" /> для отображения сообщения об ошибке на странице JSF.

1 голос
/ 25 ноября 2008

Найдено это во время поиска в Google. Во втором посте рассказывается о различных фазах JSF, которые могут привести к потере сообщения об ошибке. Кроме того, попробуйте null вместо «newPassword», потому что у вас нет объекта с идентификатором newPassword.

0 голосов
/ 21 мая 2018

Простой ответ, если вам не нужно привязывать его к определенному компоненту ...

Java:

            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Authentication failed", null);
            FacesContext context = FacesContext.getCurrentInstance();
            context.addMessage(null, message);      

XHTML:

            <h:messages></h:messages>
...