当我有以下模型与JSR-303(验证框架)注释:
public enum Gender { MALE, FEMALE } public class Profile { private Gender gender; @NotNull private String name; ... }
以及以下JSON数据:
{ "gender":"INVALID_INPUT" }
在我的REST控制器中,我想处理绑定错误(gender
属性的无效枚举值)和验证错误(name
属性不能为null).
以下控制器方法不起作用:
@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. ... }
基本上这个代码的作用是序列化为通用映射而不是模型,然后使用自定义代码绑定到模型并检查错误.
我有以下问题:
自定义代码是这样的,或者在Spring Boot中有更标准的方法吗?
@Validated
注释如何工作?如何创建自己的自定义注释,@Validated
以便封装我的自定义绑定代码?
al_mukthar.. 6
这是我在一个项目中用于在春季启动时验证REST api的代码,这与您的要求不同,但是相同。
@RequestMapping(value = "/person/{id}",method = RequestMethod.PUT) @ResponseBody public Object updatePerson(@PathVariable Long id,@Valid Person p,BindingResult bindingResult){ if (bindingResult.hasErrors()) { Listerrors = bindingResult.getFieldErrors(); List message = new ArrayList<>(); error.setCode(-2); for (FieldError e : errors){ message.add("@" + e.getField().toUpperCase() + ":" + e.getDefaultMessage()); } error.setMessage("Update Failed"); error.setCause(message.toString()); return error; } else { Person person = personRepository.findOne(id); person = p; personRepository.save(person); success.setMessage("Updated Successfully"); success.setCode(2); return success; }
成功.java
public class Success { int code; String message; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
错误.java
public class Error { int code; String message; String cause; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getCause() { return cause; } public void setCause(String cause) { this.cause = cause; } }
您也可以在这里看看:Spring REST Validation
这是我在一个项目中用于在春季启动时验证REST api的代码,这与您的要求不同,但是相同。
@RequestMapping(value = "/person/{id}",method = RequestMethod.PUT) @ResponseBody public Object updatePerson(@PathVariable Long id,@Valid Person p,BindingResult bindingResult){ if (bindingResult.hasErrors()) { Listerrors = bindingResult.getFieldErrors(); List message = new ArrayList<>(); error.setCode(-2); for (FieldError e : errors){ message.add("@" + e.getField().toUpperCase() + ":" + e.getDefaultMessage()); } error.setMessage("Update Failed"); error.setCause(message.toString()); return error; } else { Person person = personRepository.findOne(id); person = p; personRepository.save(person); success.setMessage("Updated Successfully"); success.setCode(2); return success; }
成功.java
public class Success { int code; String message; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
错误.java
public class Error { int code; String message; String cause; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getCause() { return cause; } public void setCause(String cause) { this.cause = cause; } }
您也可以在这里看看:Spring REST Validation