2008-11-24 15 views
37

En mi JSF/app Facelets, aquí es una versión simplificada de parte de mi formulario:¿Cómo mostrar los errores de mi aplicación en 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> 

me gustaría ser capaz de asignar un error a una hora específica: Etiqueta de mensaje en función de algo que sucede en el Método continueButton() Se deben mostrar diferentes errores para newPassword y newPassword2. Un validador no funcionará realmente, porque el método que entregará los resultados (desde el DB) se ejecuta en el método continueButton() y es demasiado caro para ejecutarse dos veces.

No puedo usar la etiqueta h: mensajes porque la página tiene varios lugares donde necesito mostrar diferentes mensajes de error. Cuando probé esto, la página muestra duplicados de cada mensaje.

He intentado esto como una mejor estimación, pero no hubo suerte:

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

¿Qué me falta? ¡Cualquier ayuda sería apreciada!

Respuesta

22

En caso de que alguien tuviera curiosidad, ¡pude resolver esto basándome en todas las respuestas combinadas!

esto es en el 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> 

Esto es en el método continueButton():

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

y funciona! ¡Gracias por la ayuda!

1

Encontrado this durante la búsqueda de Google. La segunda publicación hace un punto sobre las diferentes fases de JSF, lo que podría estar causando la pérdida de su mensaje de error. Además, pruebe null en lugar de "newPassword" porque no tiene ningún objeto con la id newPassword.

+0

Sé que no se está perdiendo debido a que el código h: mensajes escupe el error bien ... Es sólo que no sé cómo atar el error a una h específico: etiqueta de mensaje. Cambiar la identificación tampoco ayudó. –

2

JSF es una bestia. Puedo estar perdiendo algo, pero he usado para resolver problemas similares guardando el mensaje deseado a una propiedad del grano, y luego mostrar la propiedad a través de un outputText:

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

¡Puedo ver cómo funcionaría esto, pero debe haber una forma más elegante de manejar los mensajes de error! –

+0

Tengo que admitir que he resuelto lo mismo cuando no he podido hacer amigos con h: message (s) y rich: message (s) –

1

He intentado esto como una mejor estimación , pero sin suerte:

Me parece a mí. ¿Has intentado configurar la severidad de un mensaje explícitamente? Además, creo que la ID debe ser la misma que la de un componente (es decir, necesitaría utilizar la nueva contraseña1 o la nueva contraseña2, si esas son sus identificaciones, y no la contraseña nueva como lo hizo en el ejemplo).

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

A continuación, utilice <h:message for="newPassword1" /> para mostrar el mensaje de error en la página JSF.

6

También debe incluir el FormID en su llamada a addMessage().

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

Esto debería hacer el truco.

Atentamente.

55

FacesContext.addMessage(String, FacesMessage) requiere clientId del componente, no Es Identificación. Si se pregunta por qué, piense en tener un control como elemento secundario de una tabla de datos, eliminando los diferentes valores con el mismo control para cada fila, sería posible imprimir un mensaje diferente para cada fila. El id es siempre el mismo; el ID de cliente es único por fila.

Por lo tanto, "myform: mybutton" es el valor correcto, pero el código difícil es desacertado. Una búsqueda crearía menos acoplamiento entre la vista y la lógica comercial y sería un enfoque que funciona en entornos más restrictivos, como los 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> 

lógica bean gestionado:

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

Lea el OP, el modelo del validador no se puede aplicar a este situación. –

+0

Más información sobre el uso de IDs de clientes: http://illegalargumentexception.blogspot.com/2009/02/jsf-working-with-component-ids.html – McDowell

+0

@StudioWorks - _UIComponent_ instances son objetos de alcance de solicitud; sería una fuga de alcance inyectarlo en un objeto con ámbito de sesión. – McDowell

3

Recuerde que:

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

es también válida, porque cuando nula se especifica como primer parámetro, que se aplica a todo el formulario .

Más información: // coreservlets.com que ha sido superado

Cuestiones relacionadas