Chú thích @Valid cho biết điều gì trong Mùa xuân?


87

Trong ví dụ sau, ScriptFiletham số được đánh dấu bằng @Validchú thích.

Không gì @Validchú thích làm gì?

@RequestMapping(value = "/scriptfile", method = RequestMethod.POST)    
public String create(@Valid ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        
    if (result.hasErrors()) {        
        modelMap.addAttribute("scriptFile", scriptFile);            
        modelMap.addAttribute("showcases", ShowCase.findAllShowCases());            
        return "scriptfile/create";            
    }        
    scriptFile.persist();        
    return "redirect:/scriptfile/" + scriptFile.getId();        
}    

Câu trả lời:


63

Nó dành cho mục đích xác nhận.

Xác thực Thông thường để xác thực một mô hình sau khi ràng buộc đầu vào của người dùng với nó. Spring 3 cung cấp hỗ trợ xác thực khai báo với JSR-303. Hỗ trợ này được bật tự động nếu nhà cung cấp JSR-303, chẳng hạn như Trình xác thực Hibernate, có mặt trên classpath của bạn. Khi được bật, bạn có thể kích hoạt xác thực đơn giản bằng cách chú thích một tham số phương thức Bộ điều khiển với chú thích @Valid: Sau khi liên kết các tham số POST đến, Biểu mẫu bổ nhiệm sẽ được xác thực; trong trường hợp này, để xác minh giá trị trường ngày không phải là giá trị rỗng và xảy ra trong tương lai.


Xem tại đây để biết thêm thông tin:
http://blog.springsource.com/2009/11/17/spring-3-type-conversion-and-validation/


36

Thêm vào các câu trả lời trên, hãy xem phần sau. AppointmentForm's datecột được chú thích với vài chú thích. Bằng cách có @Validchú thích kích hoạt xác thực trên AppointmentForm(trong trường hợp này @NotNull@Future). Các chú thích này có thể đến từ các nhà cung cấp JSR-303 khác nhau (ví dụ: Hibernate, Spring..vv).

    @RequestMapping(value = "/appointments", method = RequestMethod.POST)
    public String add(@Valid AppointmentForm form, BindingResult result) {
        ....
    }

    static class AppointmentForm {

        @NotNull @Future
        private Date date;
    }

1
Tôi có một mã tương tự. Tôi đã xóa @Validtrên ApplicationFormtham số nhưng, các xác thực vẫn được kích hoạt trên trường date(set as null). Vui lòng giải thích.
lupchiazoem

17

IIRC @Valid không phải là một chú thích Spring mà là một chú thích JSR-303 (là tiêu chuẩn Xác thực Bean). Về cơ bản, nó sẽ kiểm tra xem dữ liệu mà bạn gửi đến phương thức có hợp lệ hay không (nó sẽ xác thực scriptFile cho bạn).


2
"Nó sẽ xác thực scriptFile cho bạn" có nghĩa là gì? Kiểm tra nó không phải là null, nó có một số cú pháp, hoặc một số nội dung? Nói cách khác, nó xác thực cái gì và như thế nào? Người dùng có nên triển khai thứ gì đó không? Tôi có thể lấy thông tin về nó ở đâu? Cảm ơn bạn!
cháu trai

Hãy trả lời câu hỏi của @ nephewtom, nó không đủ câu trả lời để xác thực với điểm chính còn thiếu đó là "chống lại cái gì"?
monami

17

@Validtự nó không liên quan gì đến mùa Xuân. Đó là một phần của thông số kỹ thuật Bean Validation (có một số trong số chúng, cái mới nhất là JSR 380 tính đến nửa cuối năm 2017), nhưng đã @Validrất cũ và bắt nguồn từ JSR 303.

Như chúng ta đã biết, Spring rất giỏi trong việc cung cấp tích hợp với tất cả các JSR khác nhau và thư viện java nói chung (hãy nghĩ đến JPA, JTA, Caching, v.v.) và tất nhiên những người đó cũng quan tâm đến việc xác nhận. Một trong những thành phần quan trọng hỗ trợ điều này là MethodValidationPostProcessor .

Cố gắng trả lời câu hỏi của bạn - @Validrất hữu ích cho cái gọi là phân tầng xác thực khi bạn muốn xác thực một biểu đồ phức tạp chứ không chỉ là các phần tử cấp cao nhất của một đối tượng. Mỗi khi bạn muốn đi sâu hơn, bạn phải sử dụng @Valid. Đó là những gì JSR ra lệnh. Spring sẽ tuân thủ điều đó với một số sai lệch nhỏ (ví dụ: tôi đã thử đặt @Validatedthay vì @Validphương thức RestController và xác thực hoạt động, nhưng điều tương tự sẽ không áp dụng cho bean "dịch vụ" thông thường).


Nhưng, xác thực cái gì?
cháu trai

Xin vui lòng giải thích, @nephewtom. Bạn muốn làm rõ điều gì?
yuranos

Tôi đã đọc JSR 303: Bean Validation, beanvalidation.org/1.0/spec nhưng tôi vẫn không hiểu xác thực sẽ được thực hiện trên ScriptFile scriptFile.
cháu trai

ScriptFile bên trong nó có thể có một loạt các trường và các trường đó cũng có chú thích. Đây là nơi bắt đầu xác thực. Dựa trên câu hỏi ban đầu, không rõ chính xác bên trong lớp ScriptFile là gì.
yuranos

Được rồi cảm ơn. Bạn có thể đặt một ví dụ về những gì có thể xác thực nếu các trường của nó có Chuỗi, Số nguyên và Đậu?
cháu trai

2
public String create(@Valid @NotNull ScriptFile scriptFile, BindingResult result, ModelMap modelMap) {    
    if (scriptFile == null) throw new IllegalArgumentException("A scriptFile is required");        

Tôi đoán @NotNullchú thích này là hợp lệ do đó nếu điều kiện là không cần thiết.


1

Chỉ cần thêm vào câu trả lời ở trên, Trong một ứng dụng web @validđược sử dụng trong đó bean cần được xác thực cũng được chú thích với các chú thích xác thực @NotNull, ví dụ: @Email(chú thích ngủ đông) vì vậy khi nhận đầu vào từ người dùng, các giá trị có thể được xác thực và kết quả ràng buộc sẽ có xác nhận các kết quả. bindingResult.hasErrors()sẽ cho biết nếu có bất kỳ xác thực nào không thành công.


1

Một khía cạnh hữu ích khác của @Valid không được đề cập ở trên là (nghĩa là: sử dụng Postman để kiểm tra điểm cuối) @Valid sẽ định dạng đầu ra của một lệnh gọi REST không chính xác thành JSON được định dạng thay vì một khối văn bản khó đọc. Điều này rất hữu ích nếu bạn đang tạo một API thương mại cho người dùng của mình.


1

Tôi nghĩ tôi biết câu hỏi của bạn đang hướng đến đâu. Và vì câu hỏi này là câu hỏi xuất hiện trong kết quả tìm kiếm chính của google, tôi có thể đưa ra câu trả lời đơn giản về chức năng của chú thích @Valid.

Tôi sẽ trình bày 3 tình huống về cách tôi đã sử dụng @Valid

Mô hình:

public class Employee{
private String name;
@NotNull(message="cannot be null")
@Size(min=1, message="cannot be blank")
private String lastName;
 //Getters and Setters for both fields.
 //...
}

JSP:

...
<form:form action="processForm" modelAttribute="employee">
 <form:input type="text" path="name"/>
 <br>
 <form:input type="text" path="lastName"/>
<form:errors path="lastName"/>
<input type="submit" value="Submit"/>
</form:form>
...

Bộ điều khiển cho kịch bản 1:

     @RequestMapping("processForm")
        public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
        return "employee-confirmation-page";
    }

Trong trường hợp này, sau khi gửi biểu mẫu của bạn với trường LastName trống, bạn sẽ nhận được một trang lỗi vì bạn đang áp dụng các quy tắc xác thực nhưng bạn không xử lý nó theo cách nào.

Ví dụ về lỗi đã nói: Trang ngoại lệ

Bộ điều khiển cho kịch bản 2:

 @RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee,
BindingResult bindingResult){
                return bindingResult.hasErrors() ? "employee-form" : "employee-confirmation-page";
            }

Trong trường hợp này, bạn đang chuyển tất cả các kết quả từ quá trình xác thực đó đến bindResult, vì vậy, bạn có thể quyết định phải làm gì với kết quả xác thực của biểu mẫu đó.

Bộ điều khiển cho kịch bản 3:

@RequestMapping("processForm")
    public String processFormData(@Valid @ModelAttribute("employee") Employee employee){
                return "employee-confirmation-page";
            }
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public Map<String, String> invalidFormProcessor(MethodArgumentNotValidException ex){
  //Your mapping of the errors...etc
}

Trong trường hợp này, bạn vẫn không xử lý các lỗi như trong trường hợp đầu tiên, nhưng bạn chuyển nó cho một phương thức khác sẽ xử lý ngoại lệ mà @Valid kích hoạt khi xử lý mô hình biểu mẫu. Kiểm tra điều này để xem phải làm gì với ánh xạ và tất cả những điều đó.

Tóm lại : @Valid tự nó mà không cần phải làm gì nữa để kích hoạt xác thực các trường được chú thích JSR 303 xác thực ( @NotNull, @Email, @Size, v.v. ), bạn vẫn cần chỉ định chiến lược về những việc cần làm với các kết quả xác nhận đã nói.

Hy vọng tôi có thể giải thích điều gì đó cho những người có thể gặp khó khăn với điều này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.