2013-02-05 21 views
5

我是新來的春天,我試圖創建一個驗證日期格式形式(即:只接受的格式以「MM/dd/yyyy」日期如果用戶將「mm-dd-yyyy」它應該顯示一條錯誤消息)。如何驗證日期格式在Spring形式

我如何使用Spring實現這一目標?

我已經閱讀了很多帖子和答案,如thisthis,建議在控制器中使用@InitBinder(我試過但不能讓它工作順便說一句)。但是如果我有不同日期的表格呢?或者如果我的控制器管理來自不同表單的多個發佈請求,並且每個請求都需要不同的日期驗證?

目前我有這種形式:

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

,這將是該bean支持的形式(在@DateTimeFormat註釋只會讓你把正確的格式它的工作):

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


} 

回答

7

我不知道在春季是否有直接的方法,但我做的方式是jQuery的DatePicker和InitBinder的組合。在JS

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

然後::

在JS側,創建

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

在控制器側,創建像這樣的方法:

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

從這裏你可以在你的資源包中創建typeMismatch消息來創建一個漂亮的消息。用戶將無法手動鍵入該字段,而是隻能使用jQuery DatePicker,它會根據需要格式化日期(我認爲默認值是MM/dd/yyyy)。在他們設法輸入日期的情況下,Spring將使用配置的CustomEditor將字符串從視圖轉換爲預期的日期。如果失敗,則在BindingResults中出現錯誤(如果將其包含在方法簽名中)。正如我前面所述,您可以自定義此方法,但在您的資源包中設置自定義typeMismatch消息。

編輯:添加額外的細節,我的解釋上面顯然不夠清晰...

首先,創建一個Bean什麼作爲你的模型屬性(你從視野中來回發送控制器)。確保它至少有一個日期。

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

現在你需要一個控制器。我喜歡讓我的模型通過

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

然後,你需要一些示意圖(在控制器上面的「someDefaultView」,我的代碼是JSP在這個例子中,使用Spring 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> 

同樣,我會建議谷歌的Spring Init Binders,cusomizing綁定錯誤(typeMismatch)和JSR 303的其他選項進行驗證,大部分時候是很好的文檔here。此外,如果您不希望下面的錯誤出現在字段中,就像我在此處所做的那樣,有一些方法可以將所有錯誤迭代到一個位置,例如將所有錯誤都放在頁面頂部。它的配置非常好,我可以輸入另外20頁的內容。這應該足以讓你開始找到好的例子和文檔。

+0

謝謝你的時間!是的,但如果瀏覽器禁用了js,它可能會失敗,我錯了嗎?我能看到的唯一方法就是讓「老派」在控制器中獲取參數並在那裏驗證它。在我的無知中,我找不到使用支持bean或驗證器的有用方法。因此,如果你有一個有多個日期的大表單,並且想用bean來返回並驗證它,你總是需要在控制器中驗證日期格式。 (我希望我錯了) –

+0

這就是InitBinder所做的。 Spring會嘗試使用註冊的編輯器將字符串轉換爲日期。如果失敗,則會填充BindingResults並顯示錯誤消息。默認的是非常討厭的,但你可以很容易地覆蓋它,如前所述。在您的處理程序方法中,您只需查看BindingResults中是否存在錯誤,以及是否將它們轉發回表單頁面。 Spring已經在你的表單上處理了BindingResult錯誤,並且它有很好的文檔記錄。甚至設置CSS來標記紅色字段並提示消息。 – CodeChimp

+0

我該怎麼做?你能回答我的問題嗎? –