Spring中@NotNull注解@Valid注解简介及使用

前言

在开发中,为了代码的稳定性不报空指针异常,经常需要判断前端传过来的值是否为空,为空的话就返回前端值为空的提示,才能进行下一步的操作,例如登录操作需要判断传过来的登录名和密码是否为空:

    @GetMapping("login")
    public Result login(User user) {
        if (StringUtils.isEmpty(user.getUsername())) {
            return Result.fail("用户名不能为空");
        }
        if (StringUtils.isEmpty(user.getPassword())) {
            return Result.fail("密码不能为空");
        }
        //验证密码操作省略
        return Result.suc();
    }

这样的话,在每次需要验证的时候,都需要判断一遍,如果参数有十多个,那岂不是要判断写十多个判断,这样不仅加大了自己的开发工作,也让代码变得冗余,@NotNull注解就很好的解决了这个问题。

@NotNull使用步骤

  1. 实体类需要判断的字段上面加上@NotNull注解,并且message配置提示语句
@Data
public class User {

    private Integer id;
    @NotNull(message = "用户名不能为空")
    private String username;
    @NotNull(message = "密码不能为空")
    private String password;

    private String email;

    private String phone;

    private String idCard;

    private Byte sex;

    private Byte deleted;

    private Date updateTime;

    private Date createTime;
}
  1. controller接口的方法参数加入@Valid注解,表示当前的实体类接收的参数需要根据配置的@NotNull注解判断
    @GetMapping("login")
    public Result login(@Valid User user) {
		System.out.println("测试@notNull注解");
        //验证密码操作省略
        return Result.suc();
    }
  1. 接口代码中省略判断登录名和密码是否为空,现在调一次接口测试一下
    在这里插入图片描述

接口返回的数据是全局异常捕获到之后返回的数据,再看一下控制台
在这里插入图片描述
可以看到这里抛异常了,并且控制台没有打印在方法里面的设置的信息,所以可以看出方法没有走我们的业务代码,而是直接被全局异常捕获了,然后返回给了前端数据,所以需要在全局异常里面捕获一下当前异常,并且要让我们提示语句返回给前端,这样才是合理的

  1. 配置全局异常捕获
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler  {
 	
    @ExceptionHandler(Throwable.class)
    public ErrorResult handleThrowable(Throwable e, HttpServletRequest request) {
        ErrorResult error =ErrorResult.fail(ResultCode.SYSTEM_ERROR, e);
        log.error("URL:{} ,系统异常: ",request.getRequestURI(), e);
        return error;
    }

    @ExceptionHandler(BindException.class)
    public ErrorResult exceptionHandler(BindException e, HttpServletRequest request) {
        String failMsg = e.getBindingResult().getFieldError().getDefaultMessage();
        ErrorResult error = ErrorResult.fail(ResultCode.SYSTEM_ERROR, e, failMsg);
        log.error("URL:{} ,绑定异常:{} ", request.getRequestURI(),failMsg);
        return error;
    }
}

需要捕获的是BindException,所以加上,重要的是String failMsg = e.getBindingResult().getFieldError().getDefaultMessage()这句代码,这是从这个异常里面拿到我们在实体类里面配置的提示语句,至于返回的VO对象,可以根据自己项目中的VO对象灵活修改,现在再重启看一下结果
在这里插入图片描述

可以看到已经返回了我们想要的样子,再试一下填写了用户名和密码可以正常执行业务代码吗
在这里插入图片描述

在这里插入图片描述

问题

现在是登录接口我们只需要判断username和password,如果是别的接口也是用User类接收的,但是username和password可以为空怎么办?
在NotNull注解里面配置group,需要验证的时候,就在controller参数注解中加上这个groups名称

  1. 修改User类,配置了一下username内的groups为TestNotNull.class,groups里面的class需要为接口,可以用service的接口,也可以重新创建
@Data
public class User {

    private Integer id;
    @NotNull(message = "用户名不能为空",groups = {TestNotNull.class})
    private String username;
    @NotNull(message = "密码不能为空")
    private String password;

    private String email;

    private String phone;

    private String idCard;

    private Byte sex;

    private Byte deleted;

    private Date updateTime;

    private Date createTime;
}
  1. controller中,没有使用@Valid注解了,而是要使用@Validated,里面value代表的是,在User类里面@NotNull注解里面配置了groups里面有TestNotNull.class的字段判断会生效
    那么当前配置的话,就只会判断username是否为空,而password因为没有配置同样的groups属性,所以不会生效
    @GetMapping("test")
    public Result test(@Validated(value = {TestNotNull.class}) User user) {
        System.out.println("测试@notNull注解");
        //验证密码操作省略
        return Result.suc();
    }
  1. 测试是否不传password参数,代码会不会抛异常
    在这里插入图片描述
    这里没有传password,代码没有抛异常,说明@Validated注解不会判断groups属性没有当前class的注解,再试一下不传username会不会抛异常
    在这里插入图片描述
    这里没有传username,返回的是用户名不能为空,说明配置成功了,如果以后开发中,在多个接口中有不同的判断体系,可以用groups的方式分组

其他注解

springboot中除了@NotNull注解外,还有其他的注解可以判断其他的格式,如下:

//被注释的元素必须为null
@Null  
//被注释的元素不能为null
@NotNull  
//被注释的元素必须为true
@AssertTrue  
//被注释的元素必须为false
@AssertFalse  
//被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Min(value)  
//被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Max(value)  
//被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMin(value)  
//被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMax(value)  
//被注释的元素的大小必须在指定的范围内。
@Size(max,min) 
//被注释的元素必须是一个数字,其值必须在可接受的范围内
@Digits(integer,fraction) 
//被注释的元素必须是一个过去的日期 
@Past  
//被注释的元素必须是一个将来的日期
@Future  
//被注释的元素必须符合指定的正则表达式。
@Pattern(value) 
//被注释的元素必须是电子邮件地址
@Email 
//被注释的字符串的大小必须在指定的范围内
@Length 
//被注释的字符串必须非空
@NotEmpty  
//被注释的元素必须在合适的范围内
@Range  

以@Email举例,在email字段上面加入@Email注解并写上提示信息

@Data
public class User {

    private Integer id;
    
    private String username;
    
    private String password;
    @Email(message = "邮箱格式不正确")
    private String email;

    private String phone;

    private String idCard;

    private Byte sex;

    private Byte deleted;

    private Date updateTime;

    private Date createTime;
}

测试:
在这里插入图片描述
可以看到返回信息说邮件格式不正确,再试试正确的邮箱格式
在这里插入图片描述
输入正确的格式后,可以看到校验通过了,说明配置成功了
另外补充一点,只用@Email注解email字段的话,只会判断格式对不对,如果不传值也是可以的,如果想要这个字段判断是不是邮箱,而且又不能为空的话,那么必须加上@NutNull注解,如果还有别的判断的话,也需要加别的注解,灵活运用

  • 61
    点赞
  • 162
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
@NotNull注解用于标记一个字段或方法参数不能为null。然而,如果@NotNull注解不起作用,可能有几个原因。 首先,确保你的代码正确引入了@NotNull注解的包。例如,在使用javax.validation.constraints.NotNull时,需要确保正确导入了javax.validation.constraints包。 其次,@NotNull注解需要与其他注解一起使用,如@Valid或@Validated,以确保注解的生效。在控制器层的接口参数使用@NotNull注解时,需要在该方法的控制器类上添加@Validated注解。这样,Spring框架会自动处理验证逻辑,并确保@NotNull注解的生效。 另外,对于@NotNull使用场景还有一点需要注意。如果你在实体类使用了@NotNull注解,需要在Controller接口的方法参数加入@Valid注解。这样,Spring框架会在调用该方法时执行验证,并确保@NotNull注解的生效。 如果以上步骤都已正确执行,但@NotNull注解仍然不起作用,可能是由于其他因素导致。这时,你可以考虑检查你的验证框架配置,或者查阅相关的文档或论坛来解决该问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [注解@NotNull失效问题解决方法【导致原因:实体类循环嵌套】](https://blog.csdn.net/J0304/article/details/129873373)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [@NotNull注解放在实体类或者Controller层不生效解决方案](https://blog.csdn.net/cm15835106905/article/details/124638774)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值