springboot中@Validated注解使用,以及与@Valid注解区别

为什么使用@Validated
        前端传过来数据的时候,要进行校验,但是大量的校验很繁琐,会造成大量的if else语句的产生,所以@Valid和@Validated很好的解决了这个问题.

@Validated与@Valid注解区别

①,所属的包不同

@Valid属于javax.validation包下,是jdk给提供的

@Validated是org.springframework.validation.annotation包下的,是spring提供的

②,@Validated要比@Valid更加强大

@Validated在@Valid之上提供了分组功能和验证排序功能

@Validated的使用:

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 [性别只能为01: 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": "[姓名不能为空] "
}

Validated分组验证

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,就可以对所有已经分组的字段进行校验了,但是没有进行分组的字段是不会被校验的

你可能感兴趣的:(注解,java,sping,参数验证,Validated,全局异常)