1. 简介

处理一段业务逻辑,首先要确保数据输入的正确性,所以需要先对数据进行检查,保证数据在语义上的正确性,再根据数据进行下一步的处理。
前端可以通过 js 程序校验数据是否合法,后端同样也需要进行校验。而后端最简单的实现就是直接在业务方法中对数据进行处理,但是不同的业务方法可能会出现同样的校验操作,这样就出现了数据的冗余。为了解决这个情况,JSR 303 出现了。
JSR 303 使用 Bean Validation,即在 Bean 上添加相应的注解,去实现数据校验。这样在执行业务方法前,都会根据注解对数据进行校验,从而减少自定义的校验逻辑,减少代码冗余。

2. springboot中JSR的使用

2.1引入依赖

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

2.2 构建一个需要校验的java Bean,通过校验注解进行对应的操作

@Null    被注释的元素必须为 null

@NotNull    被注释的元素必须不为 null

@AssertTrue    被注释的元素必须为 true

@AssertFalse    被注释的元素必须为 false

@Min(value)    被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value)    被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value)    被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value)    被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max, min)    被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction)    被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past    被注释的元素必须是一个过去的日期

@Future    被注释的元素必须是一个将来的日期

@Pattern(value)    被注释的元素必须符合指定的正则表达式

2.3 添加 @Valid 开启校验

在请求方法中,使用校验注解@Valid,开启校验

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

        return R.ok();
    }

想要自定义错误消息,可以覆盖默认的错误提示信息,在添加注解的时候,修改message:

@NotBlank(message = "品牌名必须非空")
	private String name;

2.4 BindResult(可选)

给校验的Bean后,紧跟一个BindResult,就可以获取到校验的结果。加完以后,如果参数验证不通过,那就直接进入if语句里面,在语句里面做相应的返回结果.

 @RequestMapping("/save")
    public R save(@Valid @RequestBody BrandEntity brand, BindingResult result){
        if( result.hasErrors()){
            Map<String,String> map=new HashMap<>();
            //1.获取错误的校验结果
            result.getFieldErrors().forEach((item)->{
                //获取发生错误时的message
                String message = item.getDefaultMessage();
                //获取发生错误的字段
                String field = item.getField();
                map.put(field,message);
            });
            return R.error(400,"提交的数据不合法").put("data",map);
        }else {

        }
		brandService.save(brand);

        return R.ok();
    }

2.5 定义全局异常类

使用Springboot所提供的@ControllerAdvice,通过“basePackages”能够说明处理哪些路径下的异常。

/**
 * 集中处理所有异常
 */
@Slf4j
@RestControllerAdvice(basePackages = "com.bigdata..controller")
public class GulimallExceptionAdvice {


    @ExceptionHandler(value = Exception.class)
    public R handleValidException(MethodArgumentNotValidException exception){
        Map<String,String> map=new HashMap<>();
        BindingResult bindingResult = exception.getBindingResult();
        bindingResult.getFieldErrors().forEach(fieldError -> {
            String message = fieldError.getDefaultMessage();
            String field = fieldError.getField();
            map.put(field,message);
        });

        log.error("数据校验出现问题{},异常类型{}",exception.getMessage(),exception.getClass());
        return R.error(400,"数据校验出现问题").put("data",map);
    }

}

Q.E.D.