@Validated与@Valid校验

痛点:开发接口的时候,对于请求参数,往往需要进行校验,这个时候可以采用如下方式校验请求参数id和number,显然这种方式难以维护,即便封装成方法,依旧麻烦。

    @PostMapping("/testValid")
    @ResponseBody
    public Object testValid(@RequestBody ValidatedTest validatedTest) {

        if (validatedTest.getId() == null) {
            return "id不能为空";
        }
        if (validatedTest.getNumber() < 0 || validatedTest.getNumber() > 120) {
            return "数量不在允许范围";
        }
        
        log.info(String.valueOf(validatedTest));

        validatedTest.setContent("接收到返回的说明,请求成功!");

        return validatedTest;

    }

解决方案:为了解决这种编码量大且难以阅读的问题,@Validated出现了。

@Validated与@Valid使用方法:

1、依赖,springboot在2.3版本之前包含对应包,可直接使用,其它版本需要引入

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

2、使用

DTO中:

@Data
public class ValidatedTest {

    @NotBlank(message = "id不能为null", groups = Add.class)
    private String id;

    @Min(value = 0, message = "数量不在允许范围")
    @Max(value = 120, message = "数量不在允许范围")
    private Integer number;

    @NotEmpty
    private String content;

    private Integer orderId;

    private List<String> testList;

    @Email(message = "邮箱有误!", groups = Up.class)
    private String email;

    private String msg;

    @AssertTrue
    private boolean bool;

    // 以下为任意接口,用来标识组,实际使用时建议在全局中创建接口
    public interface Add{

    }

    public interface Up{

    }
}

controller中:加上 @Validated({ValidatedTest.Add.class})就能生效

    @PostMapping("/testValid")
    @ResponseBody
    public Object testValid(@RequestBody @Validated({ValidatedTest.Add.class}) ValidatedTest validatedTest) {

        if (validatedTest.getId() == null) {
            return "id不能为空";
        }
        if (validatedTest.getNumber() < 0 || validatedTest.getNumber() > 120) {
            return "数量不在允许范围";
        }

        log.info(String.valueOf(validatedTest));

        validatedTest.setContent("接收到返回的说明,请求成功!");
        validatedTest.setNumber(9);

        return validatedTest;

    }

3、效果

按照上面两个步骤,接受外部请求时就会自动校验参数了,问题解决。

4、错误提示

为了给用户提示出具体是那个参数的异常,可以全局进行处理,以下给出参考:

其中  fieldError.getDefaultMessage() 有默认值,也可以自定义,只需要在DTO对应字段加上message信息,如:@NotBlank(message = "id不能为null", groups = Add.class)。

@ControllerAdvice
@Slf4j
public class ValidatedExceptionHandler {

    /**
     * 处理@Validated参数校验失败异常
     * @param exception 异常类
     * @return 响应
     */
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public BaseResult exceptionHandler(MethodArgumentNotValidException exception){
        BindingResult result = exception.getBindingResult();
        StringBuilder stringBuilder = new StringBuilder();
        if (result.hasErrors()) {
            List<ObjectError> errors = result.getAllErrors();
            errors.forEach(p -> {
                FieldError fieldError = (FieldError) p;
                log.warn("Bad Request Parameters: dto entity [{}],field [{}],message [{}]",fieldError.getObjectName(), fieldError.getField(), fieldError.getDefaultMessage());
                stringBuilder.append(fieldError.getField());
                stringBuilder.append(fieldError.getDefaultMessage());
            });
        }
        return BaseResult.validatedException(stringBuilder.toString());
    }
}

补充,@Validated与@Valid的区别:

@Validated:可以用在类型、方法和方法参数上

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
	Class<?>[] value() default {};
}

@Valid:可以用在方法、构造函数、方法参数和成员属性上。 (任意地方使用)

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Valid {
}

@Validated可以使用分组,如@Validated({ValidatedTest.Add.class}),字段上加上@NotBlank(message = "id不能为null", groups = Add.class),借助接口Add分入同一组,校验才生效。一般来说,增加和修改数据表的时候会对主键要求不一样,可以使用@Validated分组功能分别校验。

其它常用注解的含义:注解可以点开源码查看

注解限制
@Null为空
@NotNull非空
@NotBlank字符串,非空,且去掉空格后不为""
@NotEmptyObject , 非空, 且长度或者集合大小不为0
@Min(value=1)数字最小值为1
@Max(value=9)数字最大值为9
@Size(min=0, max = 10)限制字符串长度
@AssertTrue限制bool值必须为真
@AssertFalse限制bool值必须为假
@Past限制为过去的日期
@PastOrPresent限制为过去或者现在的日期
@Future限制为未来的日期
@FutureOrPresent限制为未来或者现在的日期

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值