Với Spring MVC, có 3 cách khác nhau để thực hiện xác nhận: sử dụng chú thích, thủ công hoặc kết hợp cả hai. Không có một "cách sạch nhất và tốt nhất" duy nhất để xác nhận, nhưng có lẽ có một cách phù hợp với dự án / vấn đề / bối cảnh của bạn hơn.
Hãy có một Người dùng:
public class User {
private String name;
...
}
Phương pháp 1: Nếu bạn có Spring 3.x + và xác thực đơn giản để thực hiện, hãy sử dụng javax.validation.constraints
các chú thích (còn được gọi là chú thích JSR-303).
public class User {
@NotNull
private String name;
...
}
Bạn sẽ cần một nhà cung cấp JSR-303 trong các thư viện của mình, như Trình xác thực Hibernate là người triển khai tham chiếu (thư viện này không liên quan gì đến cơ sở dữ liệu và ánh xạ quan hệ, nó chỉ thực hiện xác nhận :-).
Sau đó, trong bộ điều khiển của bạn, bạn sẽ có một cái gì đó như:
@RequestMapping(value="/user", method=RequestMethod.POST)
public createUser(Model model, @Valid @ModelAttribute("user") User user, BindingResult result){
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}
Lưu ý @Valid: nếu người dùng tình cờ có tên null, result.hasErrors () sẽ đúng.
Phương pháp 2: Nếu bạn có xác thực phức tạp (như logic xác thực doanh nghiệp lớn, xác thực có điều kiện trên nhiều trường, v.v.) hoặc vì một số lý do bạn không thể sử dụng phương pháp 1, hãy sử dụng xác thực thủ công. Đó là một cách thực hành tốt để tách mã của bộ điều khiển khỏi logic xác thực. Không tạo (các) lớp xác thực của bạn từ đầu, Spring cung cấp org.springframework.validation.Validator
giao diện tiện dụng (kể từ Mùa xuân 2).
Vì vậy, hãy nói rằng bạn có
public class User {
private String name;
private Integer birthYear;
private User responsibleUser;
...
}
và bạn muốn thực hiện một số xác thực "phức tạp" như: nếu tuổi của người dùng dưới 18 tuổi, người dùng có trách nhiệm không được rỗng và tuổi của người có trách nhiệm phải trên 21 tuổi.
Bạn sẽ làm một cái gì đó như thế này
public class UserValidator implements Validator {
@Override
public boolean supports(Class clazz) {
return User.class.equals(clazz);
}
@Override
public void validate(Object target, Errors errors) {
User user = (User) target;
if(user.getName() == null) {
errors.rejectValue("name", "your_error_code");
}
// do "complex" validation here
}
}
Sau đó, trong bộ điều khiển của bạn, bạn sẽ có:
@RequestMapping(value="/user", method=RequestMethod.POST)
public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){
UserValidator userValidator = new UserValidator();
userValidator.validate(user, result);
if (result.hasErrors()){
// do something
}
else {
// do something else
}
}
Nếu có lỗi xác thực, result.hasErrors () sẽ đúng.
Lưu ý: Bạn cũng có thể đặt trình xác nhận theo phương thức @InitBinder của bộ điều khiển, với "binder.setValidator (...)" (trong trường hợp đó, không thể sử dụng kết hợp phương thức 1 và 2, vì bạn thay thế mặc định người xác nhận). Hoặc bạn có thể khởi tạo nó trong hàm tạo mặc định của bộ điều khiển. Hoặc có một UserValidator @ Thành phần / @ Dịch vụ mà bạn tiêm (@Autowired) trong bộ điều khiển của bạn: rất hữu ích, bởi vì hầu hết các trình xác nhận là singletons + thử nghiệm đơn vị trở nên dễ dàng hơn + trình xác nhận của bạn có thể gọi các thành phần Spring khác.
Phương pháp 3:
Tại sao không sử dụng kết hợp cả hai phương pháp? Xác thực các công cụ đơn giản, như thuộc tính "tên", với các chú thích (việc này được thực hiện nhanh chóng, súc tích và dễ đọc hơn). Giữ các xác nhận hợp lệ cho các trình xác nhận (khi phải mất hàng giờ để mã các chú thích xác thực phức tạp tùy chỉnh hoặc chỉ khi không thể sử dụng các chú thích). Tôi đã làm điều này trên một dự án cũ, nó hoạt động như một sự quyến rũ, nhanh chóng và dễ dàng.
Cảnh báo: bạn không được nhầm lẫn xử lý xác thực để xử lý ngoại lệ . Đọc bài này để biết khi nào nên sử dụng chúng.
Người giới thiệu :