Java 校验注解@NotNull,@NotBlank,@Max,@Valid等注解简单使用

Posted 不允许摆烂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 校验注解@NotNull,@NotBlank,@Max,@Valid等注解简单使用相关的知识,希望对你有一定的参考价值。

说明

这些注解多用于进行参数校验,这里挑了几个简单使用下

首先创建一个项目

SpringBoot或者Maven项目都可以,我这里就选择Maven项目了

然后加入依赖

在pom里面添加依赖坐标

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

编写entity,controller代码

实体如下

这里我们分别对name限制不能为空,备注不能为空,这两个空是有区别的,age不能小于18岁,都是通过注解的方式去限制要求的

package com.wyh.entity;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * @description: 用户实体表
 * @author: 魏一鹤
 * @createDate: 2022-08-03 22:09
 **/

@Data
public class User 
    @NotNull(message = "姓名不能为空!")
    private String name;
    @NotBlank(message = "备注不能为空!")
    private String remark;
    @Min(value = 18,message = "未满18岁不能注册!")
    private int age;

controller如下

传统的判断应该是这样的,这样的话比较繁琐,判断较多的话且影响代码美观和读取

if(name!=null)
	return "姓名不能为空!";

else if(age<18)
	return "未满18岁不能注册!";

但是我们既然使用了注解 就要利用起来,使用如下优化的代码

package com.wyh.controller;

import com.wyh.entity.User;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

/**
 * @description: 用户中心控制器
 * @author: 魏一鹤
 * @createDate: 2022-08-03 22:12
 **/

@RestController
public class UserController 
    @RequestMapping("save1")
    /**
     * 有的朋友可能会问 @Valid和 BindingResult result是干嘛的
     * 1 @Valid 注解 表示我们对这个对象属性需要进行验证,
     * 2 BindingResult result:既然验证,那么就肯定会有验证结果,所以我们需要用一个东西来存放验证结果,做法也很简单,在参数直接添加一个BindingResult
    **/
    public Object test1(@Valid @RequestBody User user, BindingResult result)
         //判断有没有异常错误,如果有则返回默认消息
        //所有字段是否验证通过,true:数据验证有误,false:数据验证无误
        if (result.hasErrors())
            // 如果数据验证有误,返回第一条错误信息到前端
            return  result.getFieldError().getDefaultMessage();

        
        return "注册成功";
    


这里着重说下

@Valid和 BindingResult result是做什么的?
1 @Valid 注解 表示我们对这个对象属性需要进行验证
2 BindingResult result:既然验证,那么就肯定会有验证结果,所以我们需要用一个东西来存放验证结果,做法也很简单,在参数直接添加一个BindingResult

启动项目测试接口

打开你的接口测试工具进行测试,我这里使用的是apifox,接下来就是各种测试了

首先是一个正常添加的json


  "name": "张三",
  "remark":"这是一份简介",
  "age": "20"

 然后测试name为空 直接舍弃这个字段

 还是测试name为空,这次加上name这个字段,但是值为空,发现成功了,说明@NotNull允许值为空,但是必须要有这个属性字段

 接下来测试remark为空,可以发现,不管有没有remark这个字段,有没有值,@NotBlank都是过不了验证的

 然后测试age的值  少于18的值都会被拦截

 

 那么问题来了,我当前有一个controller,需要在里面写异常捕获处理,没问题,但是如果业务比较多,难道每一个controller都要编写异常处理逻辑吗.那么肯定是不合适的,所以就要用全局异常类优化异常处理

编写全局异常类优化异常处理

创建一个新的controller用来做全局异常捕获

package com.wyh.controller;

import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @description: 全局捕获异常
 * @author: 魏一鹤
 * @createDate: 2022-08-03 22:45
 **/

@ControllerAdvice
public class ControllerException 

    private final static String EXCEPTION_MSG_KEY = "Exception message : ";

    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Object handleValidException(MethodArgumentNotValidException e) 
        //日志记录错误信息
        // log.error(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
        //将错误信息返回给前台
        // return BaseResult.fail(500, Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
        return e.getBindingResult().getFieldError().getDefaultMessage();
    


为了区分方便测试,我们再写一个测试方法

 @RequestMapping("save2")
    public Object test2(@Valid @RequestBody User user)
        System.out.println(user);
        return "注册成功";
    

还是一样的效果

到此结束,我们再也不用写一堆各种判空逻辑处理了,使用这些注解的方式可以大大的提高我们的开发效率

多个的注解复杂使用

以上我们只是通过单个注释的方式去限制字段的值,我们多加几个玩一玩

首先修改实体,加的这几个属性大家应该也能看得懂,就不解释了



@Data
public class User 
    @NotNull(message = "姓名不能为空!")
    @Length(message ="名称不能超过max个字符",max = 5)
    private String name;
    @NotBlank(message = "备注不能为空!")
    private String remark;
    @Range(message = "年龄范围应该在min到max之间",min = 1,max = 100)
    private int age;

重启测试接口

首先是名称大于5个字符

 然后删除name,发现也通过不了,说明验证了可以多个注解去做处理的

 验证age的区间 不在1-100的直接pass

 正常的age

常用部分注解

网上收集的,欢迎大家补充完善 

@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格式
 

以上是关于Java 校验注解@NotNull,@NotBlank,@Max,@Valid等注解简单使用的主要内容,如果未能解决你的问题,请参考以下文章

java 使用注释校验数据有效性

java后端进行参数校验

jsr-303 参数校验—自定义校验注解

使用oVal进行Java Bean 验证的注意事项

SpringMVC中的 JSR 303 数据校验框架说明

JSR 303标准