2013-02-05 13 views
5

Ich bin neu bei Spring, und ich versuche ein Formular zu erstellen, das ein Datumsformat validiert (dh: akzeptiert nur Daten im Format "MM/dd/yyyy" wenn der Benutzer setzt "mm-dd-yyyy" sollte es eine Fehlermeldung zeigen).So validieren Sie das Datumsformat in einem Spring-Formular

Wie kann ich dies mit Feder erreichen?

Ich habe viele Beiträge und Antworten wie this und this, welche die @InitBinder im Controller empfehlen lesen (Ich habe versucht, aber konnte es nicht btw funktioniert). Aber was, wenn ich ein Formular mit verschiedenen Daten habe? Oder wenn mein Controller mehrere Postanforderungen von verschiedenen Formularen verwaltet und für jede eine andere Datumsvalidierung erforderlich ist?

Zur Zeit habe ich diese Form:

<form:form action="getReportFile.html" commandName="staticReportForm"> 
      <table> 
       <tr> 
        <td>Reports:</td> 
       </tr> 
       <tr> 
        <td><form:select path="report" items="${staticReports}"/>       
        </td> 
       </tr> 
       <tr> 
        <td>Date (MM/DD/YYYY) (empty for most recent possible):<FONT color="red"><form:errors 
           path="date" /></FONT></td> 
       </tr> 
       <tr> 
        <td><form:input path="date" /></td> 
       </tr> 
       <tr> 
        <td><input type="submit" value="Submit" /></td> 
       </tr> 
      </table>    
     </form:form> 

Und das wäre die Bohne Sicherung der Form (die @DateTimeFormat Anmerkung machen es nur, wenn Sie das richtige Format gesetzt):

public class StaticReportForm { 
     @NotEmpty   
     private String report;  
     @DateTimeFormat(pattern="MM/dd/yyyy") 
     private Date date; 

    public String getReport() { 
     return report; 
    } 

    public void setReport(String report) { 
     this.report = report; 
    } 

    public Date getDate() { 
     return date; 
    } 

    public void setDate(Date date) { 
     this.date = date; 
    } 


} 

Antwort

7

I Ich weiß nicht, ob es im Frühling einen direkten Weg gibt, aber die Art, wie ich es gemacht habe, ist eine Kombination aus jQuerys DatePicker und InitBinder.

In der JS Seite erstellen Sie ein:

<form:input cssClass="datepicker" path="someProperty" readonly="true" /> 

Dann in der JS:

$(document).ready(function() { 
    $('.datepicker').datepicker(); 
}); 

auf der Steuerungsseite, eine Methode, wie so erstellen:

@InitBinder 
public void initBinder(WebDataBinder binder) { 
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 
    sdf.setLenient(true); 
    binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true)); 
} 

Von hier aus können Sie typeMismatch-Nachrichten in Ihrem Ressourcenpaket erstellen, um eine nette, hübsche Nachricht zu erstellen. Der Benutzer kann nicht manuell in das Feld eingeben, sondern kann nur den jQuery DatePicker verwenden, der das Datum nach Bedarf formatiert (ich denke, der Standardwert ist MM/TT/JJJJ). Wenn es ihnen gelingt, ein Datum einzugeben, verwendet Spring den konfigurierten CustomEditor, um den String von der Ansicht in das erwartete Datum zu konvertieren. Wenn dies fehlschlägt, erhalten Sie einen Fehler in BindingResults (wenn Sie es in Ihre Methodensignatur aufnehmen). Sie können diese Methode wie bereits erwähnt anpassen, aber in Ihrem Ressourcenpaket eine benutzerdefinierte typeMismatch-Nachricht einrichten.

Edit: Hinzufügen von zusätzlichen Details wie meine explaination oben offenbar nicht klar genug war ...

zunächst eine Bean oder etwas zu tun, als Ihr Modell Attribut erstellen (was Sie hin und her von Ansicht Link Regler). Stellen Sie sicher, dass es mindestens ein Datum enthält.

public class SomeBean { 
    private Date someDate; 
    // ...additional properties, getters, setters... 
    public Date getSomeDate() { return someDate; } 
    public void setSomeDate(Date date) { somedate = date; } 
} 

Jetzt benötigen Sie einen Controller.Ich mag an meinem Modell Attribute Sitzungsattribute über die

@SessionAttribute. 
@Controller 
@RequestMapping("/somePath") 
@SessionAttributes({"someFormBean"}) 
public class SomeController { 
    /** 
    * Handler method 
    */ 
    @RequestMapping() 
    public String defaultView(@ModelAttribute("someFormBean") SomeBean someFormBean, Model uiModel) { 
     // Do something in your default view 
     return "someDefaultView"; // Assuming you have a ViewResolver, like JspViewResolver or Tiles 
    } 

    /** 
    * Submission Handler method 
    */ 
    @RequestMapping(method = RequestMethod.POST 
    public String submit(
     @ModelAttribute("someFormBean") SomeBean someFormBean, 
     BindingResult bindingResults, 
     Model uiModel) { 
     // bindingResults will have your errors from binding 
     if(bindingResults.hasErrors()) { 
      return "errorView"; 
     } else { 
      return "successView"; 
     } 
    } 

    /** 
    * Will be called to create your Model Attribute when its missing 
    */ 
    @ModelAttribute("someFormBean") 
    public SomeBean createSomeBean() { 
     return new SomeBean(); 
    } 

    /** 
    * register property editors 
    */ 
    @InitBinder 
    public void initBinder(WebDataBinder binder) { 
     SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy"); 
     sdf.setLenient(true); 
     binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true)); 
     // You can register other Custom Editors with the WebDataBinder, like CustomNumberEditor for Integers and Longs, or StringTrimmerEditor for Strings 
    } 
} 

Dann Sie etwas Ansicht brauchen machen („someDefaultView“ oben in der Steuerung, mein Code JSP in diesem Beispiel die Feder JSTL-Tag-Bibliothek)

<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core" %> 
<%@ taglib prefix="fmt"  uri="http://java.sun.com/jsp/jstl/fmt" %> 
<%@ taglib prefix="fn"  uri="http://java.sun.com/jsp/jstl/functions" %> 
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> 
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 
<html> 
    <head> 
     <script type="text/javascript" src="/resources/jquery/1.7.1/jquery-1.7.1.min.js"></script> 
     <script type="text/javascript" src="resources/jquery.ui/1.8.13/jquery.ui.min.js"></script> 

     <script type="text/javascript"> 
      $(document).ready(function() { 
       $('.datepicker').datepicker(); 
      }; 
     </script> 
    </head> 
    <body> 
     <form:form modelAttribute="someFormBean"> 
      <form:input cssClass="datepicker" path="someDate" readonly="true" /><br /> 
      <form:errors path="a"/><br /><br /> 
      <input type="submit" value="Submit" /> 
     </form:form> 
    </body> 
</html> 

Noch einmal, ich würde vorschlagen, Springing Init Binders, Cusomizing Binding Fehler (typeMismatch), und JSR 303 für zusätzliche Optionen für die Validierung, die meisten der ist gut dokumented here. Wenn Sie den Fehler unterhalb des Felds nicht möchten, wie ich hier getan habe, gibt es Möglichkeiten, alle Fehler an einer Stelle zu iterieren, wie alle Fehler am Anfang der Seite. Es ist sehr konfigurierbar, und ich könnte wahrscheinlich noch weitere 20 Seiten eingeben, die es wert sind, alles in die Tiefe zu gehen. Dies sollte genug sein, um Sie bei der Suche nach guten Beispielen und Dokumentationen zu unterstützen.

+0

Danke für Ihre Zeit! und ja, aber es könnte scheitern, wenn der Browser js deaktiviert hat, liege ich falsch? Der einzige Weg, den ich sehen kann, ist, dass die "alte Schule" den Parameter im Controller bekommt und ihn dort validiert. In meiner Ignoranz kann ich keinen nützlichen Weg finden, dies mit einer Backing Bean oder einem Validator zu tun. Wenn Sie also ein großes Formular mit mehreren Daten haben und eine Bean verwenden möchten, um es zu bestätigen und zu validieren, müssten Sie das Datumsformat immer im Controller überprüfen. (Ich hoffe ich bin falsch) –

+0

Das ist was der InitBinder tut. Spring versucht, den String mithilfe des registrierten Editors in das Datum zu konvertieren. Wenn es fehlschlägt, füllt es die BindingResults mit einer Fehlermeldung aus. Der Standard ist ziemlich unangenehm, aber Sie können es wie erwähnt leicht übersteuern. In Ihrer Handler-Methode suchen Sie einfach nach Fehlern in den BindingResults und wenn Sie sie zurück an die Formularseite weiterleiten. Spring hat BindingResult Fehler direkt auf Ihrem Formular behandelt und es ist ziemlich gut dokumentiert. Erstellt sogar CSS, um die Felder rot und die Nachricht zu markieren. – CodeChimp

+0

Wie mache ich das? Kannst du diese Antwort für meine gegebene Frage posten? –

Verwandte Themen