2010-03-17 50 views
11

Tôi có tình huống sau. Tôi có một trình xác nhận hợp lệ để xác thực đối tượng lệnh của tôi và thiết lập các lỗi trên một đối tượng Lỗi được hiển thị trong biểu mẫu của tôi. Trình xác thực được gọi như mong đợi và hoạt động tốt, nhưng các lỗi tôi đặt trên các đối tượng Lỗi không được hiển thị, khi tôi được gửi trở lại biểu mẫu của tôi do lỗi xác thực.Lỗi xác thực mùa xuân không được hiển thị

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

Command:

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 
} 

Mẫu:

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

Bộ điều khiển:

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

Có thể là các đường dẫn mà tôi cung cấp trong trình xác thực và thẻ không chính xác không? Trình xác nhận hợp lệ hóa một đối tượng lệnh có chứa một danh sách các đối tượng, vì vậy đó là lý do tại sao tôi đưa ra một chỉ mục trong danh sách trong đối tượng lệnh khi đăng ký một thông báo lỗi (ví dụ: "fields [" + index + "]". Value). Hoặc có phải là đối tượng Lỗi chứa lỗi không có sẵn cho chế độ xem của tôi không?

Bất kỳ trợ giúp nào được chào đón và đánh giá cao, nó có thể cho tôi gợi ý hoặc chỉ cho tôi đúng hướng.

+0

thử thêm trong mã biểu mẫu của bạn để đảm bảo trình xác thực của bạn hoạt động ok –

Trả lời

1

Dòng err.rejectValue("fields[" + index + "].value", "errors.missing"); sẽ không làm những gì bạn đang cố gắng đạt được. Đối số đầu tiên phải là tên thuộc tính của bean Command của bạn, trong trường hợp của bạn.

Để cung cấp cho người dùng một thông báo, bạn sẽ phải sử dụng thông báo có thể tham số trong tệp thuộc tính của bạn, ví dụ: myform.field.error = you have an error in field {0}

Vì vậy, sử dụng phương pháp này trong những lỗi phản đối:

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

đâu bạn vượt qua index vào errorArgs

+0

Cảm ơn bạn đã phản hồi303. Những gì tôi không nhận được chính xác là những gì bạn có nghĩa là với đi qua các chỉ số vào errorArgs. Tôi đã được giả định rằng errorArgs là đối số cho các thông báo tham số trong tập tin thuộc tính của tôi và không có gì để làm với một tài sản chỉ mục lệnh (như danh sách). Nhưng có lẽ tôi không hiểu bạn đang nói gì. Vì vậy, bạn có nghĩa là errorArgs nên có giá trị "fields [" + index + "]. Value"? –

+0

có chỉ mục, như trong biến phương pháp bạn sử dụng trong mã bạn đã đăng –

+0

Nhưng chỉ mục là một int chứ không phải đối tượng [] và trường [index] .value là một chuỗi, vì vậy tôi không thấy cách sử dụng chỉ mục i có thể cung cấp một đối tượng [] làm tham số. –

3

tôi thấy vấn đề của bạn là gì. thuộc tính fields trong đối tượng myCommand luôn rỗng. Bạn cần phải tạo constructor cho lớp MyCommand trong đó bạn cần phải sử dụng LazyList từ Apache Commons hoặc AutoPopulatingList từ mùa xuân để tạo auto danh sách ngày càng tăng của Field

Trong ví dụ (sử dụng AutoPopulatingList):

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

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

Cuối cùng tôi đã xác nhận biểu mẫu của mình để hoạt động. Khi nó bật ra, Spring đã thêm đối tượng BindingResult vào mô hình, nhưng dưới một tên khác (tên lớp bắt đầu bằng chữ thường) so với tên lệnh mà tôi đang sử dụng trong thẻ biểu mẫu của tôi. Thay đổi tên lệnh để phản ánh tên Spring đang sử dụng để thêm BindingResult vào mô hình, đã xác nhận biểu mẫu của tôi để hoạt động như mong đợi. Dù sao, cảm ơn cho bạn nỗ lực và giúp đỡ. ps. Tại sao cần LazyList? Bởi vì không có nó, hình thức của tôi có vẻ ổn. –

+0

Tôi đồng ý với câu trả lời của Yuri.Bulkin. Tôi gặp phải vấn đề tương tự trước 2 tháng và tôi đã tìm ra giải pháp này. Bạn cần phải khởi tạo 'LazyList' trước khi bạn sử dụng danh sách các trường trong * jsp * bằng cách sử dụng thẻ * form * của * spring *. –

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