springboot引入校验注解

引入依赖

  <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
  </dependency>
      <dependency>
            <groupId>jakarta.validation</groupId>
            <artifactId>jakarta.validation-api</artifactId>
            <version>2.0.1</version>
        </dependency>

常用校验注解

@Null(groups={Add.class}) 参数必须为null,group设置分组,默认为default
@NotNull 参数不为null
@NotEmpty 参数不为null 且不为空集合,集合不为空
@NotBlank 参数不为null且不为空串,只能作用字符串类型
@AssertFalse 被注释的元素必须是false
@AssertTrue 被注释的元素必须是true
@Min(value) 被注释的元素必须为一个数字 >=
@Max(value) 被注释的元素必须为一个数字 <=
@DecimalMin(“value”) >=
@DecimalMax(“value”) <=
@NegativeOrZero <=0
@Range(min,max) 被注释的元素大小必须在指定的范围内
@Size(min ,max) 被注释的元素大小必须在指定的范围内
@Email 被注释的元素必须是电子邮箱地址
@Past 被注释的元素必须是一个过去的日期
@PastOrPresent 被注释的元素必须是一个过去的时间
@Future 被注释的元素必须是一个将来的日期
@Pattern(regexp = “1(3[0-9]|4[01456879]|5[0-35-9]|6[2567]|7[0-8]|8[0-9]|9[0-35-9])\d{8}$”) 被注释的元素必须是符合指定的正则表达式
@URL 被注释的元素必须是链接地址

提示:除了@NotNull注解之外,其他参数校验注解只有参数不为空的时候才生效

一般校验注解都有一个message的属性,这个属性代表的是注解校验不通过时返回的错误提示。

在controller层方法参数使用校验注解

  1. 首先需要在controller类上面加上@Validated注解。
  2. 在参数前面加上校验注解。如@NotBlank(message = “名字不能为空”) String name

上述注解的包:
org.springframework.validation.annotation.Validated;
javax.validation.constraints.NotBlank;
注解参数:message,当不满足校验条件的时候会抛出ConstraintViolationException异常,异常中会包含该message对应的内容----名字不能为空。

import org.springframework.validation.annotation.Validated;
import java.util.*;

@RestController
@Validated
public class TestController extends JeecgController<Test, TestService> {
    @PostMapping(value = "/test")
    Result<?> test(@RequestBody @NotBlank(message = "名字不能为空") String name,
                   @NotNull(message = "年龄不能为空") @Max(value = 30,message = "最大不能超过30") @Min(value = 18,message = "最小不能小于18") Integer age) {
        return null;
    }
}
效果(已处理)

在这里插入图片描述

在controller层的DTO对象使用校验注解

  1. 首先需要在controller类上面加上@Validated注解。
  2. 在对象参数前面加上@Valid注解,并在对象内使用校验注解
  3. 如果对象参数内部还嵌套这其他对象,需要在对象属性上面加上@Valid注解(这条和第二条原理差不多)

不满足对象内的校验时,会抛出MethodArgumentNotValidException异常
上述注解的包:
org.springframework.validation.annotation.Validated;
javax.validation.Valid;

import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import java.util.*;

@RestController
@Validated
public class TestController extends JeecgController<Test, TestService> {
    @PostMapping(value = "/test")
    Result<?> test(@RequestBody @Valid TestDTO testDTO) {
        return testService.test(testDTO);
    }
}
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
@Data
@ApiModel(value = "testDTO")
public class TestDTO {
	@ApiModelProperty(value = "用户id",required = true)
	@NotBlank(message = "用户id不能为空")
	private String userId;

	@ApiModelProperty(value = "订单id列表",required = true)
	@Size(min = 1, message = "至少要选择一个订单")
	private List<String> orderIdList;

	@ApiModelProperty(value = "是否通知顾客",required = true)
	@NotNull(message = "是否通知顾客不能为空")
	private Boolean notifyCustomer;
}
效果(已处理)

在这里插入图片描述

校验失败返回

在这里插入图片描述

一般来说,项目都会定好响应体的结构,直接抛异常返回的信息和预期不太符合。
这个时候就需要我们来全局精准捕获该异常并处理异常信息,按照符合标准的方式返回。

当请求是GET请求,并且使用DTO对象接收参数时,使用方式和POST请求使用DTO对象用法一样,但是校验不通过的异常不一样。GET请求抛出的异常是BindException。

@RestControllerAdvice
@Slf4j
public class ExceptionHandler {

    /**
     * 这个异常在校验不通过的时候就会抛出
     *
     * @param e
     * @return: Result<?>
     **/
        @ExceptionHandler({MethodArgumentNotValidException.class, ConstraintViolationException.class, BindException.class})
    public Result<?> handleMethodArgumentNotValidException(Exception e) {
        log.info("全局捕获校验注解异常e={}", e.getMessage());
        Result<?> res = Result.ok();
        if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException notValidException = (MethodArgumentNotValidException) e;
            BindingResult bindingResult = notValidException.getBindingResult();
            List<FieldError> fieldErrorList = bindingResult.getFieldErrors();
            String msg = fieldErrorList.stream().map(FieldError::getDefaultMessage).collect(Collectors.joining(","));
            return res.error511(msg);
        } else if (e instanceof ConstraintViolationException) {
            ConstraintViolationException violationException = (ConstraintViolationException) e;
            Set<ConstraintViolation<?>> constraintViolations = violationException.getConstraintViolations();
            String msg = constraintViolations.stream().map(o -> String.valueOf(o.getMessage())).collect(Collectors.joining(","));
            return res.error511(msg);
        } else if (e instanceof BindException) {
            BindException bindException = (BindException) e;
            BindingResult bindingResult = bindException.getBindingResult();
            List<FieldError> fieldErrors = bindingResult.getFieldErrors();
            List<Object> collect = fieldErrors.stream().map(error -> error.getDefaultMessage()).collect(Collectors.toList());
            return res.error511(StringUtils.join(collect, ","));
        } else {
            return res.error511(e.getMessage());
        }
    }

    }

处理后:
在这里插入图片描述
参考:https://blog.csdn.net/qq_42956993/article/details/129199922

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值