Java中@valid和@Validated注解的使用详解

 更新时间:2024年01月15日 09:32:16   作者:Mu_Mu是一只小白  
这篇文章主要介绍了Java中@valid和@Validated注解的使用详解,@Validated可以用在类型、方法和方法参数上,但是不能用在成员属性(字段)上,不支持嵌套检测,@Valid可以用在方法、构造函数、方法参数和成员属性(字段)上,支持嵌套检测,需要的朋友可以参考下

1.简介

  • @Validated:可以用在类型、方法和方法参数上。但是不能用在成员属性(字段)上,不支持嵌套检测
  • @Valid:可以用在方法、构造函数、方法参数和成员属性(字段)上,支持嵌套检测

2.引入maven

springboot 2.3.0 以后不会自动引入jar包,所以要添加以下maven,2.3以前则不需要引入maven包

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

3.配合使用注解

  • @Null 限制只能为null
  • @NotNull 限制必须不为null
  • @AssertFalse 限制必须为false
  • @AssertTrue 限制必须为true
  • @DecimalMax(value) 限制必须为一个不大于指定值的数字
  • @DecimalMin(value) 限制必须为一个不小于指定值的数字
  • @Digits(integer,fraction) 限制必须为一个小数,且整数部分的位数不能超过integer,小数部分的位数不能超过fraction
  • @Future 限制必须是一个将来的日期
  • @Max(value) 限制必须为一个不大于指定值的数字
  • @Min(value) 限制必须为一个不小于指定值的数字
  • @Past 限制必须是一个过去的日期
  • @Pattern(value) 限制必须符合指定的正则表达式
  • @Size(max,min) 限制字符长度必须在min到max之间
  • @Past 验证注解的元素值(日期类型)比当前时间早
  • @NotEmpty 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0)
  • @NotBlank 验证注解的元素值不为空(不为null、去除首位空格后长度为0),不同于@NotEmpty,@NotBlank只应用于字符串且在比较时会去除字符串的空格
  • @Email 验证注解的元素值是Email,也可以通过正则表达式和flag指定自定义的email格式

4.例子

4.1 model

@Valid 定义schoole属性是为了实现嵌套验证,没有这个注解无法校验school类内部需要校验的属性。

public class UserVO {
    @NotNull(message = "id不能为空。" ,groups = {Insert.class})
    private Integer id;
    @NotBlank(message = "name不能为空。",groups = {Update.class})
    private String name;
    @NotNull(message = "schoole不能为空。")
    @Valid
    private Schoole schoole;
    @Min(value = 1,message = "age不能小于1")
    @Max(value = 130,message = "age不能大于130")
    private int age;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Schoole getSchoole() {
        return schoole;
    }
    public void setSchoole(Schoole schoole) {
        this.schoole = schoole;
    }
public class Schoole {
    @NotBlank(message = "name不能为空。",groups = {Update.class})
    private String name;
    @NotNull(message = "id不能为空")
    private Integer id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }

4.2分组接口

实现Default 接口,不然@Validated({Update.class}) 使用Update分组时,未定义分组的默认校验属性不会生效(比如校验schoole的 @NotNull(message = “schoole不能为空。”))

import javax.validation.groups.Default;
public interface Insert  extends Default {
}
public interface Update extends Default {
}

4.3controller

@Validated 标明group 时(Update.class)只有需要校验属性上校验注解含有该接口(Update.class)才生效,如果group (Update.class)实现了Default接口那么需要校验属性上的校验注解未定义任何group 时也会生效。

@RestController
@RequestMapping("/valid")
public class TestValidController {
    private static final Logger LOG = LoggerFactory.getLogger(TestValidController.class);
    @RequestMapping("/test")
    public void testValid(@Validated({Update.class}) UserVO userVO){
        LOG.info("userVo:"+userVO);
    }
    @PostMapping("/test2")
    public void testValid2(@Validated() @RequestBody UserVO userVO){
        LOG.info("userVo:"+userVO);
    }
}

4.3.1 基本数据类型校验

需要在类上加@Validated,然后方法直接使用@NotNull等校验注解

@Validated
public class HrmEmployeeContractController {
    @Resource
    private IHrmEmployeeContractService contractService;
    @GetMapping("/listByEmployeeId2")
    public ResponseUtil listByEmployeeId2( @NotNull(message = "employeeId 不能为空") Long employeeId) {
        return ResponseUtil.success(contractService.list(Wrappers.<HrmEmployeeContract>lambdaQuery()
                .eq(HrmEmployeeContract::getEmployeeId, employeeId)
                .eq(HrmEmployeeContract::getDeleted, DataStatusEnum.ENABLE.getType())));
    }
}

4.4使用全局异常拦截器拦截参数校验异常

MethodArgumentNotValidException异常由@RequestBody 修饰的参数未校验过抛出,其他未校验通过抛出异常BindException。

@RestControllerAdvice
public class GlobalExceptionHandler {
    private Logger LOG= LoggerFactory.getLogger(GlobalExceptionHandler.class);
//BindException 校验参数不满足条件抛出
    @ExceptionHandler(BindException.class)
    public Object handleValidException(BindException e) {
        return ResponseUtil.fail(400,e.getBindingResult().getFieldError().getDefaultMessage());
    }
	//MethodArgumentNotValidException  @RequestBody 修饰的参数未校验过抛出
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object handleValidException2(MethodArgumentNotValidException e) {
        return ResponseUtil.fail(400,e.getBindingResult().getFieldError().getDefaultMessage());
    }
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseUtil handleRuntimeException(RuntimeException ex) {
        int code = 500;
        String message = ex.getMessage();
         LOG.error(ex.getMessage(), ex);
        return ResponseUtil.fail(code,message);
    }
    @ExceptionHandler(Exception.class)
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseUtil handleException(Exception ex) {
        int code = 500;
        String message = ex.getMessage();
        LOG.error(ex.getMessage(), ex);
        return ResponseUtil.fail(code,message);
    }
}

测试

在这里插入图片描述

结果:

Schoole 里面的id 每天报id不能为空

在这里插入图片描述

spring Validation 默认会校验完所有字段,然后抛异常,可以配置快速失败,一旦校验失败立马抛异常。

  @Bean
    public Validator validator(){
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class).configure()
                .failFast(true)
                .buildValidatorFactory();
       return validatorFactory.getValidator();
    }

到此这篇关于Java中@valid和@Validated注解的使用详解的文章就介绍到这了,更多相关@valid和@Validated注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot集成Auth0 JWT的示例代码

    SpringBoot集成Auth0 JWT的示例代码

    本文主要介绍了SpringBoot集成Auth0 JWT的示例代码,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • 在netty中使用native传输协议的方法

    在netty中使用native传输协议的方法

    这篇文章主要介绍了在netty中使用native传输协议,这里我们只以Kqueue为例介绍了netty中native传输协议的使用,需要的朋友可以参考下
    2022-05-05
  • SpringBoot集成Hadoop实现文件的上传和下载功能

    SpringBoot集成Hadoop实现文件的上传和下载功能

    Spring Hadoop简化了Apache Hadoop,提供了一个统一的配置模型以及简单易用的API来使用HDFS、MapReduce、Pig以及Hive,这篇文章主要介绍了SpringBoot集成Hadoop实现文件的上传和下载,需要的朋友可以参考下
    2024-07-07
  • SpringBoot项目中连接SQL Server的三种方式

    SpringBoot项目中连接SQL Server的三种方式

    连接SQL Server是许多Spring Boot项目中常见的需求之一,本文主要介绍了SpringBoot项目中连接SQL Server的三种方式,具有一定的参考价值 ,感兴趣的可以了解一下
    2023-09-09
  • Spring boot2.0 实现日志集成的方法(2)

    Spring boot2.0 实现日志集成的方法(2)

    这篇文章主要介绍了Spring boot2.0 实现日志集成的方法,上一章讲解了spring boot日志简单集成,这篇我们将日志进行分类,常规日志、异常日志、监控日志等,需要将日志输出到不同的文件,具体内容需要的小伙伴可以参考一下
    2022-04-04
  • 详谈锁和监视器之间的区别_Java并发

    详谈锁和监视器之间的区别_Java并发

    下面小编就为大家带来一篇详谈锁和监视器之间的区别_Java并发。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • @Autowired注入为null问题原因分析

    @Autowired注入为null问题原因分析

    这篇文章主要介绍了@Autowired注入为null问题原因分析吗,小编觉得挺不错的,对日后比较有帮助,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • SpringMVC通过RESTful结构实现页面数据交互

    SpringMVC通过RESTful结构实现页面数据交互

    RESTFUL是一种网络应用程序的设计风格和开发方式,基于HTTP,可以使用XML格式定义或JSON格式定义。RESTFUL适用于移动互联网厂商作为业务接口的场景,实现第三方OTT调用移动网络资源的功能,动作类型为新增、变更、删除所调用资源
    2022-08-08
  • 基于RecyclerChart的KLine绘制Volume实现详解

    基于RecyclerChart的KLine绘制Volume实现详解

    这篇文章主要为大家介绍了基于RecyclerChart的KLine绘制Volume实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Java中自定义注解类及使用实例解析

    Java中自定义注解类及使用实例解析

    这篇文章主要介绍了Java中自定义注解类并使用过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11

最新评论