JSR303统一校验和分组校验及常用注解@NotBlank@NotEmpty 的使用

JSR303-bean校验规范

JSR303常用校验注解,下面注解在JavaBean的字段上使用

注意:
(1)一般情况下使用校验注解搭配@Vaild就够了,例:@NotBlank 搭配一个 @Valid
(2) @Validated只会校验设置了分组的注解的字段,此时没有设置分组的字段是不会开启校验的
例:@NotBlank (group={xxx.class}) 搭配一个@Validation,这里可以省略 @Valid
(3)可以给注解自定义校验信息 例:@NotBlank (message=“xxx”)

  • @Null 必须为null 适合id自增这种字段,需要在新增数据时为null
  • @NotNull 不能为null 添加数字时常用,例:Integer,Long,Double
  • @NotBlank 至少有一个字符且不能为空格 添加String类型参数时常用
  • @NotEmpty 不能为空或null 适用于对象,集合,数组
  • @URL 必须是符合规范的url
  • @Pattern 自定义校验规则,可以使用正则表达式校验 ,例:@Pattern(regexp = “正则规则” , groups = {AddGroup.class, UpdateGroup.class})
  • @Min 规定最小值 例:@Min(value = 0,message = “排序必须大于0”, groups = {AddGroup.class, UpdateGroup.class})

下路两个注解在方法形参上使用

例 : public R save(@Validated(value = {AddGroup.class}) @Valid @RequestBody BrandEntity brand){

  1. @Vaild 告诉SpringMVC开启校验,只加@NotBlank不加@Vaild,那么@NotBlank无效
  2. @Validated 设置分组,根据分组(接口)类型进行校验,比如只在进行添加操作时校验或者进行修改操作时校验,添加@Validated注解如果不在校验注解(@NotBlank、@NotNull…)上设置分组,那么校验注解无效
/**
 * 品牌
 * 
 * @author durunwu
 * @email 172885308@qq.com
 * @date 2023-02-07 00:03:47
 */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 品牌id
	 */
	@NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})//id修改时不能为空
	@Null(message = "新增不能指定id",groups = {AddGroup.class})//id主键添加时必须为空
	@TableId
	private Long brandId;
	/**
	 * 品牌名
	 */
	@NotBlank(message = "品牌名不能为空",groups = {AddGroup.class, UpdateGroup.class})
	//@NotBlank必须有一个非空字符且不能是空格,message自定义报错信息
	private String name;
	/**
	 * 品牌logo地址
	 */
	@NotEmpty(groups = {AddGroup.class})
	@URL(message = "message必须是一个合法的url地址",groups = {AddGroup.class, UpdateGroup.class})
	private String logo;
	/**
	 * 介绍
	 */
	private String descript;
	/**
	 * 显示状态[0-不显示;1-显示]
	 */
	private Integer showStatus;
	/**
	 * 检索首字母
	 */
	@NotEmpty(groups = {AddGroup.class})
	@Pattern(regexp = "^[a-zA-Z]$",message = "首字母必须是a-z或A-Z之间", groups = {AddGroup.class, UpdateGroup.class})
	//@Pattern可以使用正则表达式进行 校验
	private String firstLetter;
	/**
	 * 排序
	 */
	@NotNull(groups = {AddGroup.class})
	@Min(value = 0,message = "排序必须大于0", groups = {AddGroup.class, UpdateGroup.class})
	private Integer sort;

}

在这里插入图片描述

1. 分组校验
通过@Validated规定方法属于什么类型,然后在Javabean参数上使用group来区分分组

    /**
     * 保存
     */
    @RequestMapping("/save")
    @RequiresPermissions("product:brand:save")
    //@Valid告诉spring是否开启校验,只加@NotBlank不加@Vaild,那么@NotBlank无效
    //在校验的bean后面紧跟一个BindingResult就可以获取校验的结果
    public R save(@Validated(value = {AddGroup.class}) @Valid @RequestBody BrandEntity brand){
        brandService.save(brand);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @RequiresPermissions("product:brand:update")
    public R update(@Validated(value = {UpdateGroup.class}) @RequestBody BrandEntity brand){
		brandService.updateById(brand);
        return R.ok();
    }

Javabean

/**
	 * 品牌id
	 */
	@NotNull(message = "修改必须指定品牌id",groups = {UpdateGroup.class})//id修改时不能为空
	@Null(message = "新增不能指定id",groups = {AddGroup.class})//id主键添加时必须为空
	@TableId
	private Long brandId;

2. 普通单独校验
在校验的bean后面紧跟一个BindingResult就可以获取校验的结果

/**
     * 保存
     */
    @RequestMapping("/save")
    @RequiresPermissions("product:brand:save")
    //@Valid告诉spring是否开启校验,只加@NotBlank不加@Vaild,那么@NotBlank无效
    //在校验的bean后面紧跟一个BindingResult就可以获取校验的结果
    public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
        Map<String, String> map = new HashMap<>();
        //result.hasErrors()判断校验的结果是否成功
        if (result.hasErrors()){
            //获取所有校验的错误结果并遍历
            result.getFieldErrors().forEach((item)->{
                //错误信息
                String defaultMessage = item.getDefaultMessage();
                //字段名
                String field = item.getField();
                map.put(field,defaultMessage);
            });
            return R.error(400,"提交的数据不合法").put("data",map);
        }else {
            brandService.save(brand);
            return R.ok();
        }
    }

3. 统一校验
这里需要单独写一个检验类,把之前类上的形参BindingResult去掉,在这里集中接收

//@ControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
//@ResponseBody
@Slf4j //日志记录
@RestControllerAdvice(basePackages = "com.atguigu.gulimall.product.controller")
//集中处理所有异常
public class GulimallExceptionControllerAdvice {

    //当指定的Controller抛出异常时会被这个类接收并统一处理;
    //@ExceptionHandler指定能处理那些异常
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handleVaildException(MethodArgumentNotValidException e){
      //控制台打印日志
      log.error("数据校验出现问题{},异常类型{}",e.getMessage(),e.getClass());
        Map<String, String> errorMap = new HashMap<>();
        BindingResult bindingResult = e.getBindingResult();
        bindingResult.getFieldErrors().forEach((item)->{
            errorMap.put(item.getField(),item.getDefaultMessage());
        });
        return R.error(BizCodeEnum.VAILDE_EXCEPTIPN.getCode(), BizCodeEnum.VAILDE_EXCEPTIPN.getMsg())
                .put("data",errorMap);
    }


    //Throwable类是Java语言中所有错误和异常的超类
    @ExceptionHandler(value = Throwable.class)
    public R handleException(Throwable throwable){
        return R.error(BizCodeEnum.UNKOWN_EXCEPTION.getCode(), BizCodeEnum.UNKOWN_EXCEPTION.getMsg());
    }

}
//公共异常枚举类
public enum BizCodeEnum {
    UNKOWN_EXCEPTION(10000,"未知异常"),
    VAILDE_EXCEPTIPN(10001,"参数格式校验异常");

    private Integer code;
    private String msg;

    BizCodeEnum(Integer code, String msg){
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值