Springboot参数校验复制即用

引入依赖

<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
    <version>2.0.1.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.20.Final</version>
</dependency>

入参校验

参数字段上使用校验注解 例: @NotNull(message = “客户id不能为空”)

@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="####", description="")
public class AddParam implements Serializable {


    @ApiModelProperty(value = "客户id")
    @NotNull(message = "客户id不能为空")
    private Long customerId;
   }

控制层使用 @Validated 注解

  @ApiOperation("####")
  @PostMapping("add")
  @Transactional
  public JsonData addMedical(@RequestBody @Validated AddParam addParam) {

    return JsonData.buildSuccess();
  }

异常处理

处理Get请求,抛出BindException异常
处理请求参数格式错误 @RequestParam上,抛出ConstraintViolationException异常
处理请求参数格式错误 @RequestBody上,抛出MethodArgumentNotValidException

@ControllerAdvice
@Slf4j
public class ExceptionHandle{
 
    /**
     * 校验错误拦截处理
     * 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ResponseBody
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public BaseResponse bindExceptionHandler(BindException exception) {
        log.error("BindException encountered: {0}", exception);
        String message =
                exception.getBindingResult().getAllErrors().stream()
                        .map(DefaultMessageSourceResolvable::getDefaultMessage)
                        .collect(Collectors.joining());
        return BaseResponse.newError("YourProjectName_BindException", message);
    }
 
    /**
     * 校验错误拦截处理
     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.ConstraintViolationException
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ResponseBody
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public BaseResponse constraintViolationHandler(ConstraintViolationException exception) {
        log.error("ConstraintViolation exception encountered: {0}", exception);
        return BaseResponse.newError("YourProjectName_ConstraintViolation", exception.getMessage());
    }
 
    /**
     * 校验错误拦截处理
     * 处理请求参数格式错误 @RequestBody上validate失败后抛出的异常是MethodArgumentNotValidException异常。
     *
     * @param exception 错误信息集合
     * @return 错误信息
     */
    @ResponseBody
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public BaseResponse methodArgumentNotValidHandler(MethodArgumentNotValidException exception) {
        log.error("MethodArgumentNotValid exception encountered: {0}", exception);
        BindingResult bindingResult = exception.getBindingResult();
        StringBuilder sb = new StringBuilder();
        for (FieldError fieldError : bindingResult.getFieldErrors()) {
            sb.append(fieldError.getField()).append(": ").append(fieldError.getDefaultMessage()).append(", ");
        }
        return BaseResponse.newError("YourProjectName_MethodArgumentNotValid", sb.toString());
    }
}

配置多个请求参数校验失败,则遇到一个校验失败就抛出异常,接下来的异常参数不做校验

@Configuration
public class ValidatorConfig {
    @Bean
    public Validator validator() {
        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
                .configure()
                //failFast的意思只要出现校验失败的情况,就立即结束校验,不再进行后续的校验。
                .failFast(true)
                .buildValidatorFactory();
 
        return validatorFactory.getValidator();
    }
 
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor methodValidationPostProcessor = new MethodValidationPostProcessor();
        methodValidationPostProcessor.setValidator(validator());
        return methodValidationPostProcessor;
    }
}

校验时常用注解

  • @Valid 递归的对关联对象进行校验,如果关联对象是个集合或者数组,那么对其中的元素进行递归校验
  • @Pattern(value) 符合指定的正则表达式(校验非法字符)
  • @NotNull 参数不为 null
  • @NotEmpty 参数不能为null,或者是空
  • @NotBlank() 参数不能为null,或者被Trim的长度是否大于0(可以用来校验全为空格字符)
  • @Min() 一个数字,值大于给定值
  • @Max() 一个数字,值小于给定值
  • @Digits (integer, fraction) 一个数字,其值必须在可接受的范围内

注解常用案例

@Pattern(regexp = "^[\\u4E00-\\u9FA5\\w\\-]{1,57}$", message = "只能包含中文字符、英文字符、数字、下划线和中横线,1~57个字符")
 
 
@Pattern(regexp = "^((?!=|\\+|-|@|>|<|%).)((?!>|<|%).){0,127}$", message = "不能以=,+,-或@开头,不能包含<,>和%字符,最长为128个字符")
 
 
@Pattern(regexp = "^(?:false|true)$", message = "只支持false/true")
 
 
@Pattern(regexp = "^[A-Za-z0-9]{32}$", message = "只能是32位的uuid(只有英文和字母)")
 
 
@Pattern(regexp = "^[\\w-.;]{1,100}$", message = "最长为100,只能包含英文、数字、“-”、“_”、“;”")
 
 
@Pattern(
        regexp = "^[/][/\\w-.]{1,254}$",
        message = "须以“/”开头,只能包含字母、数字、“/”、“_”、“-”和“.”," + "长度不少于2位,长度最长为255")
 
 
@Pattern(regexp = "^(?:A|B)$", message = "类型必须为A或者B")
 
 
@Max(value = 2_140_000_000, message = "只能大于0小于2140000")
@Min(value = 0, message = "只能大于0小于2140000")
 
 
@Max(value = 5000, message = "分页大小在【1,5000】之间")
@Min(value = 1, message = "分页大小在【1,5000】之间")
 
 
@Digits(integer = 1, fraction = 0, message = "只能为0或1")
@Max(value = 1, message = "只能为0或1")
@Min(value = 0, message = "只能为0或1")
 
@NotEmpty(message = "缺少必要的参数,数组classIds不能为null,或者长度为0")
    private List<
                    @Pattern(regexp = "^[a-zA-Z\\d]{32}$", message = "id仅由字母和数字组成,且长度为32个字符")
                    @NotEmpty(message = "id不能为null或者为空") String>
            classIds;

自定义注解

自定义注解名称

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = ParamValidator.class)
public @interface RetryTimes {
    String message() default "重试次数只能为1,2,4,8";
 
    Class<?>[] groups() default {};
 
    Class<? extends Payload>[] payload() default {};
}

实现ConstraintValidator类

public class ParamValidator implements ConstraintValidator<RetryTimes, Short> {
    private static final Pattern PATTERN = Pattern.compile("^(?:0|5|10|20|50|100)$");
 
    @Override
    public boolean isValid(Short retryTimes, ConstraintValidatorContext constraintValidatorContext) {
        return PATTERN.matcher(retryTimes.toString()).matches();
    }
}

使用注解

@RetryTimes
private short retryTimes;

你可能感兴趣的:(踩坑,spring,boot,后端,java)