2008-11-24 8 views
37

In meiner JSF/Facelets App, hier ist eine vereinfachte Version von Teil meiner Form:Wie kann ich die Fehler meiner Anwendung in JSF anzeigen?

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

ich in der Lage sein möchten, um einen Fehler zu einem bestimmten h zuweisen: Message-Tag auf etwas geschieht in der Basis continueButton() -Methode. Verschiedene Fehler müssen für newPassword und newPassword2 angezeigt werden. Ein Validator wird nicht wirklich funktionieren, da die Methode, die Ergebnisse liefert (aus der Datenbank), in der continueButton() -Methode ausgeführt wird und zu teuer ist, um sie zweimal auszuführen.

Ich kann das Tag h: messages nicht verwenden, da die Seite mehrere Stellen hat, an denen ich verschiedene Fehlermeldungen anzeigen muss. Als ich das versuchte, zeigte die Seite Duplikate jeder Nachricht an.

Ich habe versucht, dies als beste Vermutung, aber kein Glück:

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

Was bin ich? Jede Hilfe wäre willkommen!

Antwort

22

Für den Fall, dass jemand neugierig war, konnte ich das anhand all Ihrer Antworten herausfinden! Diese

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

Dies ist in der continueButton() -Methode:

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

Und es funktioniert! Danke für die Hilfe!

1

Gefunden this beim Googeln. Der zweite Beitrag macht einen Hinweis auf die verschiedenen Phasen von JSF, die dazu führen können, dass Ihre Fehlermeldung verloren geht. Probieren Sie auch null anstelle von "newPassword" aus, da Sie kein Objekt mit der ID newPassword haben.

+0

Ich weiß, dass es nicht verloren gehen, weil die die h: Nachrichten-Tag den Fehler spuckt ganz gut ... Ich weiß einfach nicht, wie der Fehler ein binden spezifisches h: Nachrichten-Tag. Das Ändern der ID hat auch nicht geholfen. –

2

JSF ist ein Biest. Ich kann etwas fehlt, aber ich verwendet, um ähnliche Probleme zu lösen, indem Sie die gewünschte Nachricht an eine Eigenschaft der Bean Speichern und Anzeigen dann die Eigenschaft über eine output:

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

Ich kann sehen, wie das funktionieren würde, aber es muss eine elegantere Art sein, mit Fehlermeldungen umzugehen! –

+0

Ich muss zugeben, dass ich das gleiche Problem gelöst habe, wenn ich keine Freunde mit h haben konnte: Nachricht (en) und Rich: Nachricht (en) –

1

Ich habe versucht, dies als beste Vermutung , aber kein Glück:

Es sieht gut zu mir aus. Haben Sie versucht, eine Nachrichtenschwere explizit festzulegen? Ich glaube auch, dass die ID die gleiche wie die einer Komponente sein muss (d. H., Sie müssten newPassword1 oder newPassword2 verwenden, wenn dies Ihre IDs sind und nicht newPassword wie im Beispiel).

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

Dann <h:message for="newPassword1" /> verwenden, um die Fehlermeldung auf der JSF-Seite anzuzeigen.

6

Sie müssen auch die FormID in Ihren Aufruf von addMessage() einfügen.

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

Dies sollte den Trick tun.

Grüße.

55

FacesContext.addMessage(String, FacesMessage) erfordert die clientId der Komponente, nicht es ist id. Wenn Sie sich fragen, warum, denken Sie darüber nach, ein Steuerelement als Kind einer dataTable zu haben, indem Sie für jede Zeile verschiedene Werte mit demselben Steuerelement ausstanzen - es wäre möglich, für jede Zeile eine andere Nachricht auszudrucken. Die ID ist immer gleich; Die clientId ist einzigartig pro Zeile.

Also "myform: mybutton" ist der richtige Wert, aber hard-Codierung ist dies nicht ratsam. Eine Suche würde weniger Kopplung zwischen der Ansicht und der Geschäftslogik erzeugen und wäre ein Ansatz, der in restriktiveren Umgebungen wie Portlets funktioniert.

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

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

Lesen Sie das OP, das Validator-Modell kann nicht angewendet werden Lage. –

+0

Weitere Informationen zur Verwendung von clientIds: http://illegalargumenttexception.blogspot.com/2009/02/jsf-working-with-component-ids.html – McDowell

+0

@StudioWorks - _UIComponent_ Instanzen sind Anforderungsbereichsobjekte; Es wäre ein Scope-Leck, um es in ein Session-Scoped-Objekt zu injizieren. – McDowell

3

Denken Sie daran, dass:

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

auch gültig ist, denn wenn null als erster Parameter angegeben wird, um es in die ganze Form angewendet wird, .

Weitere Informationen: coreservlets.com // Veraltete