JSR303数据校验方法

        使用JSR303做后台数据校验是有效确保非法数据绕过前端提交数据,必须确保数据的有效性和准确性。方法步骤如下:

        一、引入依赖

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

 二、在实体类上加入注解

1.@NotNull:不能为null,但可以为empty (“”,”“,”“)

2.@NotEmpty:不能为null,而且长度必须大于0 (”“,”“)

3.@NotBlank:只能作用在String上,不能为null,而且调用trim()后,长度必须大于0

/**
 * 品牌
 * 
 * @author javahorse
 * @email javahorse@gmail.com
 * @date 2022-06-22 17:30:51
 */
@Data
@TableName("pms_brand")
public class BrandEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 品牌id
	 */
	@TableId
	private Long brandId;
	/**
	 * 品牌名
	 */
	@NotBlank(message = "品牌名不能为空")
	private String name;
	/**
	 * 品牌logo地址
	 */
	@NotBlank(message = "品牌logo不能为空")
	@URL(message = "品牌logo必须是合格的http地址")
	private String logo;
	/**
	 * 介绍
	 */
	@NotBlank(message = "品牌介绍不能为空")
	private String descript;
	/**
	 * 显示状态[0-不显示;1-显示]
	 */
	@NotNull(message = "显示状态不能为空")
	@Max(value = 1, message = "显示状态不能大于1")
	@Min(value = 0, message = "显示状态不能小于0")
	private Integer showStatus;
	/**
	 * 检索首字母
	 */
	@NotBlank(message = "检索首字母不能为空")
	@Pattern(regexp = "^[a-zA-Z]$", message = "检索首字母必须是英文字母")
	private String firstLetter;
	/**
	 * 排序
	 */
	@NotNull(message = "排序不能为空")
	@Min(value = 0, message = "排序必须大于等于0")
	private Integer sort;
}

三、后台 controller 中验证提交的信息

提交参数中加入@Valid注解,并通过BindingResult收集验证错误信息。

public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
        if(result.hasErrors()){
            Map<String, String> map = new HashMap<>();
            result.getFieldErrors().forEach(item -> {
                // 获取验证不通过字段名
                String field = item.getField();
                // 获取验证不通过字段信息
                String message = item.getDefaultMessage();
                map.put(field, message);
            });
            return R.error(400, "提交数据不合法").put("data", map);
        }else{
            brandService.save(brand);
            return R.ok();
        }
    }

四、通过postman绕过前端测试

 五、为了方便在每个controller中使用校验方法,通过AOP切面将校验异常及其他异常整合成一个类。

/**
 * 集中处理 controller中的异常
 */
@Slf4j
@RestControllerAdvice(basePackages = "com.javahorse.gmall.product.controller")
public class gmallExceptionControllerAdvice {

    /**
     * 处理验证异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R handValidException(MethodArgumentNotValidException e) {
        log.error("数据校验异常:{},异常类型:{}", e.getMessage(), e.getClass());
        BindingResult bindingResult = e.getBindingResult();
        Map<String, String> errorMap = new HashMap<>();
        bindingResult.getFieldErrors().forEach(item -> {
            // 获取验证不通过字段名
            String field = item.getField();
            // 获取验证不通过字段信息
            String message = item.getDefaultMessage();
            errorMap.put(field, message);
        });
        return R.error(BizCodeEnum.VAILD_EXCEPTION.getCode(), BizCodeEnum.VAILD_EXCEPTION.getMsg()).put("data", errorMap);
    }

    /**
     * 处理不能精确匹配的其他异常
     * @param throwable
     * @return
     */
    @ExceptionHandler(value = Throwable.class)
    public R handValidException(Throwable throwable) {

        return R.error(BizCodeEnum.UNKNOW_EXCEPTION.getCode(), BizCodeEnum.UNKNOW_EXCEPTION.getMsg());
    }
}

六、设置通用的错误代码及信息枚举类

/**
 * @desc: 通用错误代码及信息类
 */
public enum BizCodeEnum {
    UNKNOW_EXCEPTION(10000, "系统未知异常"),
    VAILD_EXCEPTION(10001,"数据校验异常");

    private int code;
    private String msg;

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

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

七、修改原先的controller,由于通过AOP切面方式校验,所以不需要在controller中 BindingResult,只需要@Valid 注解就可以通过切面类捕获抛出的异常来达到校验的结果,代码修改如下:

 @RequestMapping("/save")
 public R save(@Valid @RequestBody BrandEntity brand){
    brandService.save(brand);
    return R.ok();
 }

八、测试

 msg和code已经变成切面类定义的错误信息了。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值