Khi tôi có mô hình sau đây với JSR-303 (khung xác nhận) chú thích:Xuân Boot ràng buộc và xử lý lỗi xác nhận trong điều khiển REST của
public enum Gender {
MALE, FEMALE
}
public class Profile {
private Gender gender;
@NotNull
private String name;
...
}
và các dữ liệu sau JSON:
{ "gender":"INVALID_INPUT" }
Trong bộ điều khiển REST của tôi, tôi muốn xử lý cả hai lỗi liên kết (giá trị enum không hợp lệ cho thuộc tính gender
) và các lỗi xác thực (name
thuộc tính không thể rỗng).
Phương pháp điều khiển sau đây KHÔNG làm việc:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@Validated @RequestBody Profile profile, BindingResult result) {
...
}
Điều này cho phép com.fasterxml.jackson.databind.exc.InvalidFormatException
lỗi serialization trước khi ràng buộc hoặc xác nhận diễn ra.
Sau khi một số không quan trọng, tôi đã đưa ra mã tùy chỉnh này mà làm những gì tôi muốn:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@RequestBody Map values) throws BindException {
Profile profile = new Profile();
DataBinder binder = new DataBinder(profile);
binder.bind(new MutablePropertyValues(values));
// validator is instance of LocalValidatorFactoryBean class
binder.setValidator(validator);
binder.validate();
// throws BindException if there are binding/validation
// errors, exception is handled using @ControllerAdvice.
binder.close();
// No binding/validation errors, profile is populated
// with request values.
...
}
Về cơ bản những gì mã này không được serialize đến một bản đồ chung thay vì mô hình và sau đó sử dụng mã tùy chỉnh để ràng buộc để lập mô hình và kiểm tra lỗi.
Tôi có câu hỏi sau:
- là mã tùy chỉnh con đường để đi đây hoặc là có một cách tiêu chuẩn hơn để làm điều này trong mùa xuân Boot?
- Cách hoạt động của chú thích
@Validated
? Làm cách nào để tạo chú thích tùy chỉnh của riêng tôi hoạt động như@Validated
để đóng gói mã ràng buộc tùy chỉnh của tôi?
Nhược điểm ở đây là bạn không nhận được BindingResult khi một lỗi ràng buộc xảy ra. I E. bạn có thể làm 'ex.getBindingResult()' trên 'MethodArgumentNotValidException' ngoại lệ, nhưng không phải trên một ngoại lệ' HttpMessageNotReadableException'. –
Sau này có vẻ hợp lý, bởi vì khi ràng buộc không thành công, chúng ta không thể có kết quả ràng buộc. Không có ràng buộc. –
Trong quan điểm của tôi ràng buộc lỗi như đặt một String trong một lĩnh vực int hoặc một giá trị Enum sai nên được coi là lỗi xác nhận. Việc sử dụng các lỗi trường độc lập 'DataBinder' cũng có ràng buộc trong trường' BindingResult' để dịch vụ có thể trả về một phản hồi lỗi chi tiết hơn. –