2010-03-17 6 views
11

Ich habe die folgende Situation. Ich habe einen Validator, um mein Befehlsobjekt zu validieren und die Fehler für ein Errors-Objekt festzulegen, das in meinem Formular angezeigt werden soll. Der Validator wird wie erwartet aufgerufen und funktioniert ordnungsgemäß, aber die Fehler, die ich für die Errors-Objekte festgelegt habe, werden nicht angezeigt, wenn ich aufgrund der Validierungsfehler an mein Formular zurückgesendet werde.Spring Validierung Fehler nicht angezeigt

Validator:

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"); 
    } 
} 

Befehl:

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 
} 

Form:

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

Controller:

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

Könnte es sein, dass die Pfade, die ich im Validator und Tag gebe, nicht korrekt sind? Der Validator validiert ein Befehlsobjekt, das eine Liste von Objekten enthält. Aus diesem Grund gebe ich bei der Registrierung einer Fehlermeldung einen Index für die Liste im Befehlsobjekt an (Beispiel: "fields [" + index + "]". Value). Oder ist das Errors-Objekt, das die Fehler enthält, für meine Ansicht nicht verfügbar?

Jede Hilfe ist willkommen und geschätzt, es könnte mir einen Hinweis oder zeigen Sie mir in die richtige Richtung.

+0

try hinzufügen in ihrem form code um sicherzustellen, dass ihr validator funktioniert ok –

Antwort

1

Die Linie err.rejectValue("fields[" + index + "].value", "errors.missing"); wird nicht das tun, was Sie erreichen wollen. Das erste Argument muss ein Eigenschaftsname Ihrer Command Bean sein, in Ihren Fallfeldern.

Um dem Benutzer eine Nachricht zu geben, müssen Sie eine parametrisierbare Nachricht in Ihrer Eigenschaftendatei verwenden, z. myform.field.error = you have an error in field {0}

So verwenden Sie diese Methode der Fehler-Objekt:

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

Wo Sie passieren index in errorArgs

+0

Danke für ihre antwort mirror303. Was ich nicht genau verstehe, ist, was Sie meinen, wenn Sie den Index in errorArgs übergeben. Ich ging davon aus, dass errorArgs Argumente für die parametrisierte Nachricht in meiner Eigenschaftendatei sind und nichts mit einer indizierten Befehlseigenschaft (wie List) zu tun haben. Aber wahrscheinlich verstehe ich nicht, was du sagst. Meinst du also, dass errorArgs den Wert "fields [" + index + "]. Value" haben sollte? –

+0

Ja Index, wie in der Methode Variable, die Sie im Code verwenden, den Sie gepostet haben –

+0

Aber der Index ist ein int und nicht ein Object [] und Felder [index] .value ist ein String, so dass ich nicht sehe, wie der Index i kann ein Object [] als Parameter angeben. –

3

ich gefunden, was dein Problem ist. Eigenschaft fields in Objekt myCommand immer Null. Sie müssen Konstruktor für Klasse MyCommand schaffen, in dem Sie benötigen LazyList von Apache Commons oder AutoPopulatingList von Spring verwenden Auto wachsende Liste der Field

In Beispiel (unter Verwendung von AutoPopulatingList) zu erstellen:

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

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

Ich habe endlich meine Formularvalidierung zu arbeiten. Wie sich herausstellte, fügte Spring das BindingResult-Objekt dem Modell hinzu, aber unter einem anderen Namen (der Klassenname beginnt mit Kleinbuchstaben) als der Befehlsname, den ich in meinem Formular-Tag verwende. Wenn Sie den Befehlsnamen so ändern, dass er den Namen widerspiegelt, den Spring verwendet, um das BindingResult zum Modell hinzuzufügen, wurde meine Formularvalidierung erwartungsgemäß ausgeführt. Wie auch immer, danke für deine Mühe und Hilfe. ps. Warum die Notwendigkeit für LazyList? Denn ohne sie scheint meine Form in Ordnung zu sein. –

+0

Ich stimme Yuri.Bulkins Antwort zu. Ich hatte das gleiche Problem vor 2 Monaten und ich fand diese Lösung. Sie müssen die LazyList-Initialisierung durchführen, bevor Sie die Liste der Felder in * jsp * mit * form * -Tags von * spring * verwenden. –

Verwandte Themen