为什么使用@Validated
前端传过来数据的时候,要进行校验,但是大量的校验很繁琐,会造成大量的if else语句的产生,所以@Valid和@Validated很好的解决了这个问题.
①,所属的包不同
@Valid属于javax.validation包下,是jdk给提供的
@Validated是org.springframework.validation.annotation包下的,是spring提供的
②,@Validated要比@Valid更加强大
@Validated在@Valid之上提供了分组功能和验证排序功能
1,定义实体类,在要验证参数上加注解;
@Data
public class Person {
@NotEmpty(message = "姓名不能为空")
private String name;
@Max(value = 18,message = "年龄不能超过18岁")
private String age;
@Max(value = 1, message = "性别只能为0和1: 0=女1=男")
@Min(value = 0, message = "性别只能为0和1: 0=女1=男")
private Short sex;
}
2,在接口参数省添加@Validated注解
@RestController
@Slf4j
public class VerifyController {
@PostMapping(value = "/valid")
public void verifyValid(@Validated @RequestBody Person person) {
log.info("I am verifyValid() method, the request params is: 【{}】", JSON.toJSONString(person));
if (result.hasErrors()) {
FieldError fieldError = result.getFieldError();
if (fieldError != null) {
log.error("error msg: 【{}】", fieldError.getDefaultMessage());
}
}
}
}
3,调用接口,传不符合要求的值。抛出MethodArgumentNotValidException异常
复制代码
org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public void com.example.controller.VerifyController.verifyValidated(com.example.model.Person) with 3 errors: [Field error in object 'person' on field 'age': rejected value [19]; codes [Max.person.age,Max.age,Max.java.lang.String,Max]; arguments [NotEmpty.person.name,NotEmpty.name,NotEmpty.java.lang.String,NotEmpty]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.name,name]; arguments []; default message [name]]; default message [姓名不能为空]] [Field error in object 'person' on field 'sex': rejected value [10]; codes [Max.person.sex,Max.sex,Max.java.lang.Short,Max]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [person.sex,sex]; arguments []; default message [sex],1]; default message [性别只能为0和1: 0=女1=男]]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:139)
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:167)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:134)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
4,定义全局异常拦截,将异常中重要信息返回给前端。
@ControllerAdvice
@Slf4j
public class ExceptionController {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
@ResponseStatus
public R handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
StringBuilder sb=new StringBuilder("");
Iterator var2 = ex.getBindingResult().getAllErrors().iterator();
while(var2.hasNext()) {
ObjectError error = (ObjectError)var2.next();
if (error.getDefaultMessage()!=null) {
sb.append("[").append(error.getDefaultMessage()).append("] ");
}
}
return R.fail(sb.toString());
}
}
5,调用接口,name不传。验证成果:
{
"code": 500,
"msg": "[姓名不能为空] "
}
1,定义两个分组接口:
public interface Add{
}
public interface Update{
}
2,注解中使用分组:
@Data
public class Person {
@NotEmpty(groups = Update.class, message = "更新时候id不能为空")
private Long id;
@NotEmpty(groups = Add.class, message = "姓名不能为空")
private String name;
}
3,使用分组进行接口验证
@RestController
@Slf4j
public class VerifyController {
@PostMapping(value = "/validated/add")
public void add(@Validated(value = Add.class) @RequestBody Person person) {
...
}
@PostMapping(value = "/validated/update")
public void update(@Validated(value = Update.class) @RequestBody Person person) {
...
}
}
然后controller中 value=Group.class,就可以对所有已经分组的字段进行校验了,但是没有进行分组的字段是不会被校验的