當我有JSR-303(驗證框架)的註釋如下模型:彈簧引導結合和REST控制器處理驗證錯誤
public enum Gender {
MALE, FEMALE
}
public class Profile {
private Gender gender;
@NotNull
private String name;
...
}
和以下JSON數據:
{ "gender":"INVALID_INPUT" }
在我的REST控制器,我想要處理綁定錯誤(gender
屬性的無效枚舉值)和驗證錯誤(name
屬性不能爲空)。
下面的控制器方法不起作用:
@RequestMapping(method = RequestMethod.POST)
public Profile insert(@Validated @RequestBody Profile profile, BindingResult result) {
...
}
這給com.fasterxml.jackson.databind.exc.InvalidFormatException
序列化錯誤結合或驗證發生之前。
一些擺弄後,我想出了這個定製的代碼做什麼,我想:
@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.
...
}
基本上這代碼做什麼,是序列化到一個通用的地圖,而不是模型,然後使用自定義代碼綁定建模並檢查錯誤。
我有以下問題:
- 是自定義代碼去這裏的路還是有春季啓動這樣做的更標準的方式?
@Validated
註釋是如何工作的?我怎樣才能使自己的自定義註釋像@Validated
一樣封裝我的自定義綁定代碼?
這裏缺點是,當出現綁定錯誤你沒有得到BindingResult。即您可以對'MethodArgumentNotValidException'異常執行'ex.getBindingResult()',但不會出現'HttpMessageNotReadableException'異常。 –
後者似乎是合理的,因爲當綁定失敗時,我們無法獲得綁定結果。沒有約束力。 –
在我看來,將一個字符串放在一個int字段或一個錯誤的Enum值中的綁定錯誤應該被視爲驗證錯誤。在'BindingResult'中使用'DataBinder'獨立的綁定字段錯誤,這樣服務可以返回更詳細的錯誤響應。 –