2013-02-05 52 views
5

Tôi mới sử dụng Spring và tôi đang cố gắng tạo biểu mẫu xác thực định dạng ngày (ví dụ: nó chỉ chấp nhận ngày có định dạng "MM/dd/yyyy" nếu người dùng đặt "mm-dd-yyyy" nó sẽ hiển thị thông báo lỗi).Cách xác thực định dạng ngày ở dạng Spring

Làm cách nào để đạt được điều này với Spring?

Tôi đã đọc rất nhiều bài đăng và câu trả lời như thisthis, khuyên bạn nên sử dụng @InitBinder trong bộ điều khiển (Tôi đã thử nhưng không thể làm cho nó hoạt động btw). Nhưng nếu tôi có một biểu mẫu với các ngày khác nhau thì sao? hoặc nếu trình điều khiển của tôi quản lý nhiều yêu cầu đăng từ các biểu mẫu khác nhau và mỗi yêu cầu xác thực ngày khác nhau thì sao?

Hiện nay tôi có hình thức này:

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

Và đây sẽ là đậu ủng hộ hình thức (các @DateTimeFormat chú thích chỉ làm cho nó hoạt động nếu bạn đặt đúng định dạng):

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


} 

Trả lời

7

tôi không biết nếu có một cách trực tiếp để làm điều đó trong mùa xuân, nhưng cách tôi đã làm nó là một sự kết hợp của DatePicker của jQuery và InitBinder.

Ở phía bên JS, bạn tạo một:

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

Sau đó, trong JS:

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

Về phía Controller, tạo ra một phương pháp như vậy:

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

Từ đây, bạn có thể tạo các thông báo kiểu Mismatch trong gói tài nguyên của mình để tạo một thông điệp đẹp, đẹp mắt. Người dùng sẽ không thể nhập thủ công vào trường, nhưng thay vào đó sẽ chỉ có thể sử dụng jQuery DatePicker, sẽ định dạng ngày khi cần (tôi nghĩ mặc định là MM/dd/yyyy). Trong trường hợp họ DO quản lý để nhập ngày, Spring sẽ sử dụng CustomEditor đã định cấu hình để chuyển đổi chuỗi từ khung nhìn sang Date mong đợi. Nếu nó không thành công, bạn nhận được một lỗi trong BindingResults (nếu bạn đưa nó vào chữ ký phương thức của bạn). Bạn có thể tùy chỉnh phương thức này, như tôi đã nói trước đây, nhưng thiết lập một thông báo typeMismatch tùy chỉnh trong gói tài nguyên của bạn.

Chỉnh sửa: Thêm các chi tiết khác như Giải thích của tôi ở trên rõ ràng là không đủ rõ ràng ...

Đầu tiên, tạo một Bean hoặc một cái gì đó để hoạt động như Thuộc tính Model của bạn (những gì bạn gửi qua lại từ Xem để Bộ điều khiển). Đảm bảo có ít nhất một ngày trong đó.

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

Bây giờ bạn cần bộ điều khiển.Tôi muốn làm cho mẫu của tôi thuộc tính thuộc tính phiên qua

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

Sau đó, bạn cần một số view ("someDefaultView" nêu trên trong bộ điều khiển, mã của tôi là JSP trong ví dụ này, sử dụng thư viện mùa xuân thẻ 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> 

Một lần nữa, tôi sẽ đề nghị Google Initing Spring Init Binders, cusomizing ràng buộc lỗi (typeMismatch), và JSR 303 cho các tùy chọn bổ sung để xác nhận, hầu hết khi nào cũng là documentet here. Ngoài ra, nếu bạn không muốn lỗi bên dưới trường, như tôi đã làm ở đây, có nhiều cách để lặp lại tất cả các lỗi ở một vị trí, như đặt tất cả các lỗi ở đầu trang. Nó rất có thể cấu hình, và tôi có thể gõ 20 trang khác có giá trị vượt qua tất cả. Điều này sẽ rất nhiều để giúp bạn bắt đầu tìm kiếm các ví dụ và tài liệu tốt.

+0

Cảm ơn bạn đã dành thời gian! và có, nhưng nó có thể thất bại nếu trình duyệt đã tắt js, tôi có sai không? cách duy nhất tôi có thể nhìn thấy tôi có thể làm điều đó là với "trường học cũ" nhận được các tham số trong bộ điều khiển và xác nhận nó ở đó. Trong sự thiếu hiểu biết của tôi, tôi không thể tìm thấy một cách hữu ích để làm điều đó bằng cách sử dụng một bean sao lưu hoặc validator. Vì vậy, nếu bạn có một hình thức lớn với nhiều ngày và muốn sử dụng một bean để trở lại và xác nhận nó, bạn sẽ luôn luôn phải xác nhận định dạng ngày trong bộ điều khiển? (Tôi hy vọng tôi sai) –

+0

Đó là những gì mà InitBinder thực hiện. Spring sẽ cố gắng chuyển đổi Chuỗi thành Ngày bằng cách sử dụng trình chỉnh sửa đã đăng ký. Nếu nó không thành công, nó sẽ điền vào các BindingResults với một thông báo lỗi. Một mặc định là khá khó chịu, nhưng bạn có thể ghi đè nó khá dễ dàng, như đã đề cập. Trong phương thức xử lý của bạn, bạn chỉ cần nhìn xem liệu bạn có lỗi trong BindingResults hay không và nếu bạn chuyển chúng trở lại trang biểu mẫu. Spring đã xử lý các lỗi BindingResult ngay trên biểu mẫu của bạn và tài liệu được viết khá tốt. Ngay cả thiết lập CSS để gắn cờ các trường màu đỏ và pring tin nhắn. – CodeChimp

+0

Tôi làm như thế nào? bạn có thể đăng câu trả lời đó cho câu hỏi đã cho của tôi không? –

Các vấn đề liên quan