2010-03-17 25 views
11

Tengo la siguiente situación. Tengo un validador para validar mi objeto de comando y establecer los errores en un objeto de errores para que se muestren en mi formulario. El validador se invoca como se espera y funciona bien, pero los errores que establezco en los objetos de Errores no se muestran cuando me vuelven a enviar a mi formulario debido a los errores de validación.Errores de validación de primavera no mostrados

Validador:

public void validate(Object obj, Errors err) { 
    MyCommand myCommand = (MyCommand) obj; 
    int index = 0; 
    for (Field field : myCommand.getFields()) { 
     if (field.isChecked()) { 
      if ((field.getValue() == null) || (field.getValue().equals(""))) { 
       err.rejectValue("fields[" + index + "].value", "errors.missing"); 
      } 
     } 
     index++; 
    } 
    if (myCommand.getLimit() < 0) { 
     err.rejectValue("limit", "errors.invalid"); 
    } 
} 

Comando:

public class MyCommand { 
    private List<Field> fields; 
    private int limit; 

    //getters and setters 
} 

public class Field { 
    private boolean checked; 
    private String name; 
    private String value; 

    //getters and setters 
} 

Forma:

<form:form id="myForm" method="POST" action="${url}" commandName="myCommand"> 
    <c:forEach items="${myCommand.fields}" var="field" varStatus="status"> 
     <form:checkbox path="fields[${status.index}].checked" value="${field.checked}" /> 
     <c:out value="${field.name}" /> 
     <form:input path="fields[${status.index}].value" /> 
     <form:errors path="fields[${status.index}].value" cssClass="error" /></td> 
     <form:hidden path="fields[${status.index}].name" /> 
    </c:forEach> 
    <fmt:message key="label.limit" />  
    <form:input path="limit" /> 
    <form:errors path="limit" cssClass="error" /> 
</form:form> 

controlador:

@RequestMapping(value = REQ_MAPPING, method = RequestMethod.POST) 
    public String onSubmit(Model model, MyCommand myCommand, BindingResult result) { 
    // validate 
    myCommandValidator.validate(myCommand, result); 
    if (result.hasErrors()) { 
     model.addAttribute("myCommand", myCommand); 
     return VIEW; 
    } 

    // form is okay, do stuff and redirect 
} 

¿Podría ser que las rutas que doy en el validador y la etiqueta no son correctas? El validador valida un objeto de comando que contiene una lista de objetos, por eso doy un índice en la lista en el objeto de comando al registrar un mensaje de error (por ejemplo: "campos [" + índice + "]". Valor). ¿O es que el objeto Errores que contiene los errores no está disponible para mi vista?

Cualquier ayuda es bienvenida y apreciada, podría darme una pista o me punto en la dirección correcta.

+0

intenta agregar en el código del formulario para asegurar que su validador funciona ok –

Respuesta

1

La línea err.rejectValue("fields[" + index + "].value", "errors.missing"); no hará lo que usted está tratando de lograr. El primer argumento debe ser un nombre de propiedad de su bean Command, en los campos de su caso.

para dar al usuario un mensaje que tendrá que utilizar un mensaje parametrizable en el archivo de propiedades, por ejemplo. myform.field.error = you have an error in field {0}

lo tanto, utilizar este método de los errores de objeto:

void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage) 

donde se pasa index en errorArgs

+0

Gracias por sus mirror303 de respuesta. Lo que no entiendo con precisión es lo que quiere decir con pasar el índice a errorArgs. Estaba bajo la suposición de que errorArgs son argumentos para el mensaje parametrizado en mi archivo de propiedades y no tienen nada que ver con una propiedad indexada del comando (como List). Pero probablemente no entiendo lo que estás diciendo. Entonces, ¿quiere decir que errorArgs debería tener el valor "fields [" + index + "]. Value"? Si Indice de –

+0

, como en la variable método que se utiliza en el código que envió –

+0

embargo, el índice es un entero y no un Object [] y los campos [índice] .value es una cadena, así que no veo cómo utilizar el índice i puede suministrar un Objeto [] como parámetro. –

3

he encontrado cuál es su problema. propiedad fields en el objeto myCommand siempre nula. Es necesario crear constructor para MyCommand clase en la que es necesario utilizar LazyList de Apache Commons o AutoPopulatingList de primavera para crear lista creciente de automóviles de Field

En el ejemplo (usando AutoPopulatingList):

public class MyCommand { 
    private List<Field> fields; 
    private int limit; 

    //getters and setters 
    //... 
    //Constructor 
    public MyCommand() { 
     fields = new AutoPopulatingList<Field>(Field.class); 
    } 
} 
+1

Finalmente obtuve la validación de mi formulario para que funcione. Resultó que Spring estaba agregando el objeto BindingResult al modelo, pero con un nombre diferente (el nombre de clase comenzando con minúsculas) que el nombre de comando que estoy usando en mi etiqueta de formulario. Cambiando el nombre del comando para reflejar el nombre que Spring está usando para agregar BindingResult al modelo, obtuve que la validación de mi formulario funcione como se esperaba. De todos modos, gracias por su esfuerzo y ayuda. PD. ¿Por qué la necesidad de LazyList? Porque sin eso mi forma parece funcionar bien. –

+0

Estoy de acuerdo con la respuesta de Yuri.Bulkin. Me enfrenté al mismo problema antes de los 2 meses y encontré esta solución. Necesita tener la inicialización de 'LazyList' antes de usar la lista de campos en * jsp * usando las etiquetas * form * de * spring *. –

Cuestiones relacionadas