2008-11-24 2 views
37

В моем JSF/приложение Facelets, вот упрощенная версия часть моей формы:Как отображать ошибки моего приложения в JSF?

<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> 

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

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

Я попытался это как лучшее предположение, но не повезло:

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

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

ответ

22

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

Это в 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)); 

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

1

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

+0

Я знаю, что это не заблудиться, потому что Водородные: сообщения теги выплевывают ошибку просто отлично ... Я просто не знаю, как связать ошибку к специфический h: тег сообщения. Изменение идентификатора тоже не помогло. – 2008-11-24 23:34:10

2

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

<h:outputText 
    value="#{CreateNewPasswordBean.errorMessage}" 
    render="#{CreateNewPasswordBean.errorMessage != null}" /> 
+0

Я вижу, как это будет работать, но должен быть более грациозный способ обработки сообщений об ошибках! – 2008-11-24 23:35:35

+0

Я должен признать, что я решил одно и то же, когда мне не удалось подружиться с h: message (s) и rich: message (s) – 2008-11-25 10:13:11

1

Я попытался это как лучшее предположение , но не повезло:

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

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

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

6

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

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

Это должно сделать трюк.

С уважением.

55

FacesContext.addMessage(String, FacesMessage) требует ClientId компонента, не это идентификатор. Если вам интересно, почему, подумайте о том, что у вас есть элемент управления как дочерний элемент 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> 

Управляемый боб логика:

/** 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; 
    } 
} 
3

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

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

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

Подробнее: coreservlets.com // Устаревшие