你还在用if else 校验字段?使用注解一键搞定繁琐字段校验

繁琐校验

当一个请求 使用if else校验时

     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@RequestBody BrandEntity brand){
        if (!Objects.isNull(brand.getBrandId())){
            throw new RuntimeException("新增时不允许id有值");
        }else if(StringUtils.isEmpty(brand.getName())){
            throw new RuntimeException("新增时name不允许为空");
        }else if(....){
            ....
        }else if(....){
            ....
        }else if(....){
            ....
        }
		brandService.save(brand);
        return R.ok();
    }

虽然使用这种看起来没有什么问题,但是如果这个对象有一百个添加接口,就很麻烦。

使用JSR303校验

JSR303是Java为Bean数据合法性校验提供给的标准框架,已经包含在 JavaEE6.0中,JSR303通过在Bean 属性中标注类似 @NotNull @Max 等标准的注解指定校验规则,并通过标准的验证接口对 Bean进行验证。

普通校验

注解名称功能
NotEmpty字段不能为" "和null
URL字段必须为http或https格式和null
Pattern自定义匹配规则(正则表达式)和null
Min最小
Max最大

代码

package com.atguigu.gulimall.product.entity;

import com.atguigu.common.exception.GroupInterface.InsertGroup;
import com.atguigu.common.exception.GroupInterface.UpdateGroup;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

import java.io.Serializable;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import org.hibernate.validator.constraints.URL;

import javax.validation.constraints.*;

/**
 * 品牌
 *
 * @author yangxingchen
 * @email yyyxcwl@163.com
 * @date 2023-10-07 23:19:45
 */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 品牌id
	 */
	@TableId
	@JsonSerialize(using = ToStringSerializer.class)
	private Long brandId;
	/**
	 * 品牌名
	 */
	@NotEmpty(message = "品牌名不允许为空字符串和null")
	private String name;
	/**
	 * 品牌logo地址
	 */
	@URL(message = "匹配logo地址不允许为空")
	private String logo;
	/**
	 * 介绍
	 */
	private String descript;
	/**
	 * 显示状态[0-不显示;1-显示]
	 */
	private Boolean showStatus;
	/**
	 * 检索首字母
	 */
	//Pattern是自定义规则,可以使用正则表达式
	@Pattern(regexp = "^[a-zA-Z]$",message = "首字母必须是a-z或者A-Z其中一个")
	private String firstLetter;
	/**
	 * 排序
	 */
	@Min(value = 0,message = "排序必须是从0开始得一个整数")
	private Integer sort;

}

然后在需要校验接口参数里面加上@Valid

    /**
     * 保存
     */
    @RequestMapping("/save")
    //@RequiresPermissions("product:brand:save")
    public R save(@Valid @RequestBody BrandEntity brand){
		brandService.save(brand);
        return R.ok();
    }

自定义拦截器,用来统一返回异常结果

package com.atguigu.gulimall.product.exception;

import com.atguigu.common.exception.HttpCode;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;

/*
自定义异常类
 */
@Slf4j
@RestControllerAdvice
public class GulimallExceptionControllerAdvice {
    //自定义实体类字段校验拦截器 (MethodArgumentNotValidException是自定义字段异常类)
    @ExceptionHandler(value = org.springframework.web.bind.MethodArgumentNotValidException.class)
    public R handleVaildException(org.springframework.web.bind.MethodArgumentNotValidException e){
        HashMap<String, String> errMap = new HashMap<>();
        //取方法字段校验有问题得字段集合,一个一个把他们放到map中,返回给前端
        BindingResult bindingResult = e.getBindingResult();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errMap.put(fieldError.getField(),fieldError.getDefaultMessage());
        }
        return R.error(HttpCode.FIELD_NONCOMPLIANCE.getCode(),HttpCode.FIELD_NONCOMPLIANCE.getMessage()).put("data",errMap);
    }


    //没有拦截得全部处理
    @ExceptionHandler(value = Exception.class)
    public R handleException(Exception e){
        log.error(e.getMessage(),e.getClass());
        return R.error(HttpCode.UNKNOW_EXCEPTION.getCode(),HttpCode.UNKNOW_EXCEPTION.getMessage());
    }
}

测试

在这里插入图片描述

分组校验

分组校验和普通校验最大得区别就是,可以通过不同接口做不同得校验规则,比如:添加数据接口和修改数据接口
– 添加数据:不需要指定主键ID,使用数据库自增
– 修改数据:必须要携带主键ID,不然修改不了数据

使用分组校验时需要给注解指定group属性一个分组标识符(一个空Interface接口当标识符)

  1. 创建两个空得interface接口当做新增和修改得标识符
  2. 在需要做分组字段上使用校验注解并且指定group属性一个分组标识
  3. 在接口入参添加@Validated(分组标识符),用来表示这个接口是要根据那个分组做校验

代码

  • 两个分组空接口标识符
package com.atguigu.common.exception.GroupInterface;

public interface DeleteGroup {
}
package com.atguigu.common.exception.GroupInterface;

public interface InsertGroup {
}

  • 实体类表示校验规则和分组标识符
	package com.atguigu.gulimall.product.entity;

	import com.atguigu.common.exception.GroupInterface.InsertGroup;
	import com.atguigu.common.exception.GroupInterface.UpdateGroup;
	import com.baomidou.mybatisplus.annotation.TableId;
	import com.baomidou.mybatisplus.annotation.TableName;

	import java.io.Serializable;

	import com.fasterxml.jackson.databind.annotation.JsonSerialize;
	import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
	import lombok.Data;
	import org.hibernate.validator.constraints.URL;

	import javax.validation.constraints.*;

	/**
	 * 品牌
	 *
	 * @author yangxingchen
	 * @email yyyxcwl@163.com
	 * @date 2023-10-07 23:19:45
	 */
	@Data
	@TableName("pms_brand")
	public class BrandEntity implements Serializable {
		private static final long serialVersionUID = 1L;

		/**
		 * 品牌id
		 */
		@TableId
		@JsonSerialize(using = ToStringSerializer.class)
		//groups 表示controller上表示那个规则到这个里面就根据那个规则校验
		@Null(message = "新增时品牌ID必须为空",groups = {InsertGroup.class})
		@NotNull(message = "修改时品牌ID不能为空",groups = {UpdateGroup.class})
		private Long brandId;
		/**
		 * 品牌名
		 */
		@NotBlank(message = "品牌名name不允许为空和null",groups = {InsertGroup.class,UpdateGroup.class})
		private String name;
		/**
		 * 品牌logo地址
		 */
		@NotNull(message = "修改时logo不能为空",groups = {InsertGroup.class,UpdateGroup.class})
		@URL(message = "这个logo必须是一个合法的url",groups = {InsertGroup.class,UpdateGroup.class})
		private String logo;
		/**
		 * 介绍
		 */
		private String descript;
		/**
		 * 显示状态[0-不显示;1-显示]
		 */
		private Boolean showStatus;
		/**
		 * 检索首字母
		 */
		@NotEmpty
		@Pattern(regexp = "^[a-zA-Z]$",message = "检索首字母必须是a-z字母",groups = {InsertGroup.class,UpdateGroup.class})
		private String firstLetter;
		/**
		 * 排序
		 */
		@Min(value = 0,message = "排序必须大于0")
		private Integer sort;

	}

  • controller接口指定这个方法根据那个分组规则进行校验参数
  /**
     * 保存
     */
    @RequestMapping("/save")
    //根据InsertGroup.class进行校验分组规则
    public R save(@Validated(InsertGroup.class) @RequestBody BrandEntity brand){
		brandService.save(brand);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    //根据UpdateGroup.class进行校验分组规则
    public R update(@Validated(UpdateGroup.class)@RequestBody BrandEntity brand){
		brandService.updateById(brand);

        return R.ok();
    }

自定义拦截器,用来统一返回异常结果

package com.atguigu.gulimall.product.exception;

import com.atguigu.common.exception.HttpCode;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;

/*
自定义异常类
 */
@Slf4j
@RestControllerAdvice
public class GulimallExceptionControllerAdvice {
    //自定义实体类字段校验拦截器 (MethodArgumentNotValidException是自定义字段异常类)
    @ExceptionHandler(value = org.springframework.web.bind.MethodArgumentNotValidException.class)
    public R handleVaildException(org.springframework.web.bind.MethodArgumentNotValidException e){
        HashMap<String, String> errMap = new HashMap<>();
        //取方法字段校验有问题得字段集合,一个一个把他们放到map中,返回给前端
        BindingResult bindingResult = e.getBindingResult();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            errMap.put(fieldError.getField(),fieldError.getDefaultMessage());
        }
        return R.error(HttpCode.FIELD_NONCOMPLIANCE.getCode(),HttpCode.FIELD_NONCOMPLIANCE.getMessage()).put("data",errMap);
    }


    //没有拦截得全部处理
    @ExceptionHandler(value = Exception.class)
    public R handleException(Exception e){
        log.error(e.getMessage(),e.getClass());
        return R.error(HttpCode.UNKNOW_EXCEPTION.getCode(),HttpCode.UNKNOW_EXCEPTION.getMessage());
    }
}

测试

新增分组校验结果

在这里插入图片描述

修改分组校验结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值