41 votes

Comment afficher les erreurs de mon application dans JSF?

Dans mon JSF/Facelets application, voici une version simplifiée d'une partie de mon formulaire:

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

J'aimerais être en mesure d'attribuer une erreur à un h:message d'étiquette sur la base de quelque chose qui se passe dans le continueButton() la méthode. Les différentes erreurs doivent être affichés pour newPassword et newPassword2. Un validateur n'aurez pas vraiment de travail, car la méthode qui permettra d'obtenir des résultats (à partir de la DB) est exécuté dans le continueButton() la méthode, et il est trop coûteux de faire fonctionner deux fois.

Je ne peux pas utiliser le h:messages de la balise parce que la page a plusieurs endroits que j'ai besoin d'afficher différents messages d'erreur. Quand j'ai essayé ceci, la page affiche les doublons de chaque message.

J'ai essayé ce que deviner, mais, pas de chance:

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

Ce qui me manque? Toute aide serait appréciée!

58voto

McDowell Points 62645

FacesContext.addMessage(String, FacesMessage) exige du composant clientId, non c'est l'id. Si vous vous demandez pourquoi, pensez à avoir un contrôle en tant qu'enfant d'un dataTable, à l'estampillage des valeurs différentes avec le même contrôle pour chaque ligne serait - il possible d'avoir un message différent imprimé pour chaque ligne. L' id est toujours le même; le clientId est unique par ligne.

Donc "myform:mybutton" est la bonne valeur, mais de codage en dur c'est de mauvais conseil. Une recherche serait de créer moins de couplage entre la vue et la logique d'entreprise et serait une approche qui fonctionne dans des milieux plus contraignants comme des portlets.

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

Managed bean logique:

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

25voto

Eric Noob Points 531

Au cas où quelqu'un serait curieux, j'ai pu comprendre cela en fonction de toutes vos réponses combinées!

Ceci est dans le 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>
 

C'est dans la méthode continueButton ():

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

Et il fonctionne! Merci pour l'aide!

6voto

huo73 Points 471

Vous devez également inclure le FormID dans votre appel à addMessage ().

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

Cela devrait faire l'affaire.

Cordialement.

4voto

Rappelez-vous que:

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

est également valide, car lorsque null est spécifié en tant que premier paramètre, il est appliqué à l'ensemble du formulaire.

Plus d'infos: http://goo.gl/HBN26

1voto

daub815 Points 1675

Trouvé ceci en googlant. La deuxième publication fait un point sur les différentes phases de JSF, ce qui pourrait entraîner la perte de votre message d'erreur. Aussi, essayez null à la place de "newPassword" car vous n'avez aucun objet avec l'id newPassword.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X