it-swarm.com.de

Wie kann ich die Fehler meiner Anwendung in JSF anzeigen?

In meiner JSF/Facelets-App finden Sie hier eine vereinfachte Version eines Teils meines Formulars:

<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 möchte in der Lage sein, einem bestimmten h: message-Tag einen Fehler zuzuordnen, der auf einem Ereignis in der continueButton () -Methode beruht. Für newPassword und newPassword2 müssen verschiedene Fehler angezeigt werden. Ein Validator funktioniert nicht wirklich, 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 den Tag h: messages nicht verwenden, da die Seite mehrere Stellen hat, an denen verschiedene Fehlermeldungen angezeigt werden müssen. Als ich dies versuchte, wurden auf jeder Seite Duplikate aller Nachrichten angezeigt.

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

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

Was vermisse ich? Jede Hilfe wäre dankbar!

38
Eric Noob

Für den Fall, dass jemand neugierig war, konnte ich dies anhand Ihrer gesamten Antworten herausfinden!

Dies ist 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!

24
Eric Noob

FacesContext.addMessage (String, FacesMessage) erfordert die clientId der Komponente, nicht es ist id. Wenn Sie sich fragen, warum Sie ein Steuerelement als untergeordnetes Element einer dataTable verwenden möchten, müssen Sie für jede Zeile unterschiedliche Werte mit demselben Steuerelement ausstempeln. Möglicherweise wird für jede Zeile eine andere Nachricht gedruckt. Die id ist immer gleich. Die clientId ist pro Zeile eindeutig.

"Myform: mybutton" ist also der richtige Wert, aber eine harte Kodierung ist nicht ratsam. Eine Suche würde weniger Kopplung zwischen der Ansicht und der Geschäftslogik schaffen 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>

Verwaltete 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;
    }
}
57
McDowell

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

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

Das sollte den Trick tun.

Grüße.

6
huo73

Erinnere dich daran:

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

ist auch gültig, denn wenn null als erster Parameter angegeben wird, wird er auf das gesamte Formular angewendet.

Weitere Informationen: coreservlets.com // Veraltet

3
InfZero

JSF ist ein Biest. Ich vermisse vielleicht etwas, aber ich löste ähnliche Probleme, indem ich die gewünschte Nachricht in einer Eigenschaft des Beans speicherte und dann die Eigenschaft über einen outputText anzeigt:

<h:outputText
    value="#{CreateNewPasswordBean.errorMessage}"
    render="#{CreateNewPasswordBean.errorMessage != null}" />
2
Jan Zich

dies beim Googeln gefunden. Im zweiten Beitrag wird auf die verschiedenen Phasen der JSF eingegangen, wodurch möglicherweise die Fehlermeldung verloren geht. Versuchen Sie auch null anstelle von "newPassword", da Sie kein Objekt mit der ID newPassword haben.

1
kevindaub

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

Es sieht für mich richtig aus. Haben Sie versucht, einen Nachrichtenschweregrad explizit festzulegen? Ich glaube auch, dass die ID mit der einer Komponente identisch sein muss (d. H. Sie müssten newPassword1 oder newPassword2 verwenden, sofern dies Ihre IDs sind, und nicht NewPassword wie im Beispiel).

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

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

1
user7094

Einfache Antwort, wenn Sie es nicht an eine bestimmte Komponente binden müssen ... 

Java:

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

XHTML:

            <h:messages></h:messages>