2013-02-05 12 views
5

Jestem nowy w Spring i próbuję utworzyć formularz, który sprawdza poprawność formatu daty (tzn. Akceptuje tylko daty w formacie "MM/dd/yyyy", jeśli użytkownik umieści "mm-dd-yyyy" powinien pokazać komunikat o błędzie).Jak sprawdzić format daty w formularzu wiosennym?

Jak mogę to osiągnąć wiosną?

Przeczytałem wiele postów i odpowiedzi, takich jak this i this, które zalecają użycie @InitBinder w kontrolerze (próbowałem, ale nie mogłem sprawić, żeby zadziałało). Ale co jeśli mam formularz z różnymi datami? lub czy mój kontroler zarządza wieloma żądaniami postów z różnych formularzy, a każdy z nich wymaga walidacji różnych dat?

Obecnie mam ten formularz:

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

I to byłoby fasola kopii formularza (the @DateTimeFormat adnotacja zrobić tylko to działa, jeśli umieścić poprawny format):

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


} 

Odpowiedz

7

I nie wiem, czy jest na to bezpośredni sposób na wiosnę, ale sposób, w jaki to zrobiłem, to połączenie jQuery's DatePicker i InitBinder.

Na stronie JS można utworzyć:

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

Następnie w JS:

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

Po stronie sterownika, utworzyć metodę jak tak:

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

Stąd możesz tworzyć wiadomości typu Mismatch w pakiecie zasobów, aby stworzyć ładną, ładną wiadomość. Użytkownik nie będzie mógł ręcznie wpisywać danych w polu, ale zamiast tego będzie mógł korzystać tylko z jQuery DatePicker, który sformatuje datę w razie potrzeby (domyślnie jest to MM/dd/rrrr). W przypadku, gdy ZDĄŻE wprowadzą datę, Spring użyje skonfigurowanego CustomEditor do konwersji ciągu znaków z widoku na oczekiwaną datę. Jeśli się nie powiedzie, pojawi się błąd w BindingResults (jeśli umieścisz go w sygnaturze metody). Możesz dostosować tę metodę, jak już wcześniej wspomniałem, ale konfiguruję niestandardową wiadomość typuMismatch w pakunku zasobów.

Edycja: Dodawanie dodatkowych szczegółów w moim wyjaśnieniu powyżej oczywiście nie było wystarczająco jasne ...

Najpierw utwórz Bean czy coś działać jak model Attribute (co wysyłać iz powrotem z widokiem na Kontroler). Upewnij się, że zawiera co najmniej jedną datę.

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

Teraz potrzebujesz kontrolera.Chciałbym, aby mój model Atrybuty atrybuty sesji poprzez

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

to trzeba jakiś pogląd („someDefaultView” powyżej w kontrolerze, mój kod jest JSP w tym przykładzie, stosując bibliotekę Wiosna tagów JSTL)

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

Powtórzę, chciałbym zasugerować Google'ing Spring Init Binders, wyjaśnić błędy wiązania (typeMismatch) i JSR 303, aby uzyskać dodatkowe opcje sprawdzania poprawności, z których większość jest dobrze udokumentowana here. Ponadto, jeśli nie chcesz, aby błąd znajdował się poniżej pola, tak jak to zrobiłem, istnieją sposoby na powtórzenie wszystkich błędów w jednym miejscu, na przykład umieszczenie wszystkich błędów na górze strony. Jest bardzo konfigurowalny i mógłbym napisać około 20 stron, które warto dokładnie przeanalizować. To powinno wystarczyć, aby zacząć od znalezienia dobrych przykładów i dokumentacji.

+0

Dziękujemy za poświęcony czas! i tak, ale może zawieść, jeśli przeglądarka ma js wyłączone, czy jestem w błędzie? Jedyny sposób, w jaki widzę, że mogę to zrobić, to "stara szkoła", która otrzymuje parametr w kontrolerze i zatwierdza go tam. W mojej niewiedzy nie mogę znaleźć przydatnego sposobu, aby to zrobić za pomocą fasoli lub walidatora. Więc jeśli masz duży formularz z wieloma datami i chcesz użyć komponentu bean do jego kopii i sprawdzenia poprawności, zawsze będziesz musiał sprawdzić poprawność formatu daty w kontrolerze? (Mam nadzieję, że się mylę) –

+0

To właśnie robi InitBinder. Spring spróbuje przekonwertować ciąg na datę za pomocą zarejestrowanego edytora. Jeśli się nie powiedzie, wypełnia komunikat BindingResults, wyświetlając komunikat o błędzie. Domyślna jest dość nieprzyjemna, ale możesz ją przesłonić dość łatwo, jak wspomniano. W swojej metodzie obsługi po prostu sprawdzasz, czy masz błędy w BindingResults i czy przekazujesz je z powrotem do strony formularza. Wiosna była z obsługą błędów BindingResult bezpośrednio na formularzu, a jej dość dobrze udokumentowane. Nawet ustawia CSS, aby oznaczać pola na czerwono i wyświetlać komunikat. – CodeChimp

+0

Jak to zrobić? czy możesz umieścić tę odpowiedź na moje pytanie? –