2008-11-24 9 views
37

Dans mon JSF/app Facelets, voici une version simplifiée d'une partie de ma forme:Comment afficher les erreurs de mon application dans 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> 

Je voudrais être en mesure d'attribuer une erreur à un h spécifique: balise de message basé sur quelque chose qui se passe dans la Méthode continueButton(). Différentes erreurs doivent être affichées pour newPassword et newPassword2. Un validateur ne fonctionnera pas vraiment, car la méthode qui fournira les résultats (à partir de la base de données) est exécutée dans la méthode continueButton() et est trop chère pour être exécutée deux fois.

Je ne peux pas utiliser la balise h: messages car la page comporte plusieurs emplacements dont j'ai besoin pour afficher différents messages d'erreur. Quand j'ai essayé ceci, la page affichait des doublons de chaque message.

J'ai essayé cela comme une meilleure estimation, mais pas de chance:

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

Qu'est-ce que je manque? Toute aide serait appréciée!

Répondre

22

Si quelqu'un était curieux, j'ai été capable de comprendre cela en fonction de toutes vos réponses combinées!

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

Ceci est la méthode continueButton():

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

Et ça marche! Merci pour l'aide!

1

Trouvé this lors d'un googling. Le deuxième article fait un point sur les différentes phases de JSF, ce qui pourrait entraîner la perte de votre message d'erreur. Essayez également null à la place de "newPassword" car vous n'avez aucun objet avec l'ID newPassword.

+0

Je sais que ce n'est pas se perdre parce que les h: balise messages recrache l'erreur très bien ... Je ne sais pas comment lier l'erreur à un h spécifique: balise de message. Changer l'identifiant n'a pas aidé non plus. –

2

JSF est une bête. Je peux manquer quelque chose, mais je l'habitude de résoudre des problèmes similaires en enregistrant le message souhaité à une propriété du grain, puis afficher la propriété via un outputText:

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

Je peux voir comment cela fonctionnerait, mais il doit y avoir une façon plus gracieuse de gérer les messages d'erreur! –

+0

Je dois admettre que j'ai résolu à la même chose quand je n'ai pas pu me faire des amis avec h: message (s) et riche: message (s) –

1

J'ai essayé cela comme une meilleure estimation , mais pas de chance:

Cela me semble juste. Avez-vous essayé de définir une gravité de message explicitement? Je crois également que l'ID doit être identique à celui d'un composant (c'est-à-dire que vous devez utiliser newPassword1 ou newPassword2, s'il s'agit de vos ID, et non newPassword comme dans l'exemple).

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

Utilisez ensuite <h:message for="newPassword1" /> pour afficher le message d'erreur sur la page JSF.

6

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

Cela devrait faire l'affaire.

Cordialement.

55

FacesContext.addMessage(String, FacesMessage) nécessite clientId, pas il est du composant id. Si vous vous demandez pourquoi, pensez à avoir un contrôle en tant qu'enfant d'un tableau de données, en écrasant des valeurs différentes avec le même contrôle pour chaque ligne - il serait possible d'avoir un message différent imprimé pour chaque ligne. Le id est toujours le même; le ID client est unique par ligne. Donc, "myform: mybutton" est la valeur correcte, mais le codage en dur est mal avisé. Une recherche créerait moins de couplage entre la vue et la logique métier et serait une approche qui fonctionne dans des environnements plus restrictifs, tels que les 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> 

Géré logique de haricot:

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

Lire l'OP, le modèle de validateur ne peut pas être appliqué à cette situation. –

+0

Plus d'informations sur l'utilisation de clientIds: http://illegalargumentexxx.blogspot.com/2009/02/jsf-working-with-component-ids.html – McDowell

+0

@StudioWorks - Les instances _UIComponent_ sont des objets de portée de requête; ce serait une fuite de portée de l'injecter dans un objet de portée de session. – McDowell

3

Rappelez-vous que:

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

est également valable, car lorsque null est spécifié en tant que premier paramètre, il est appliqué à la forme entière .

Plus d'info: coreservlets.com // Périmé