天天看點

SpirngBoot請求參數驗證及@Validated使用方法

分享知識 傳遞快樂

SpirngBoot更新到2.3之後,hibernate-validator消失,需要手動依賴spring-boot-starter-validation

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

常用限制說明

  • @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(regex=,flag=):指定的正規表達式
  • @URL:必須是一個URL
  • @Email:必須是email格式
  • @NotBlank:字元串不能為空
  • @NotEmpty:集合不能為空
  • @Length:長度必須在指定範圍内
  • @Valid:對實體類進行校驗

實體參數限制

如果成員是實體,需要帶上 @Valid注解;

@RestController
@RequestMapping("/demo")
public class SupportController {

    @Autowired
    private Demo demo;

    @PostMapping(value = "/save")
    public Result save(@Valid @RequestBody UserReq userReq) {

        return demo.save(userReq);
    }
}      

拼接參數限制

需要在控制層的類上加上 @Validated;

@RestController
@RequestMapping("/demo")
@Validated
public class DemoController {

    @Autowired
    private Demo demo;

    @PostMapping(value = "/list")
    public Result list(@NotBlank(message = "userName不能為空") String userName,
                                         @NotBlank(message = "idno不能為空") String idno) {
        return demo.list(roomid, msgtime);
    }


}      

參數嵌套驗證

@Data
@ApiModel(value = "User入參")
public class UserReqVO {

    @NotBlank(message = "使用者名稱不能為空")
    private String userName;

    @Valid
    private List<RolesReqVO> rolesReq;
}      

異常捕獲

全局異常捕獲,當出現參數校驗不合法時捕獲異常,并且傳回給前端;

@Slf4j
@RestControllerAdvice
public class DefaultExceptionAdvice {

    private Result defHandler(String msg, Exception e) {
        log.error(msg, e);
        return Result.failed(msg);
    }

    /**
     * 捕獲方法參數校驗異常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public Result constraintViolationExceptionHandler(ConstraintViolationException exception) {
        Set<ConstraintViolation<?>> message = exception.getConstraintViolations();
        HashMap<String, Object> map = new HashMap<>();
        message.stream().forEach(msg -> {
            String path = msg.getPropertyPath().toString();
            String field = path.substring(path.indexOf(".") + 1);
            map.put(field, msg.getMessageTemplate());
        });
        return Result.failed(map.toString());
    }

    /**
     * 校驗Body錯誤攔截處理
     *
     * @param exception 錯誤資訊集合
     * @return 錯誤資訊
     * 傳回狀态碼:500
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Result validationBodyException(MethodArgumentNotValidException exception) {
        FieldError error = exception.getBindingResult().getFieldError();
        String field = error.getField();
        String message = String.format("%s:%s", field, error.getDefaultMessage());
        return Result.failed(message);
    }

}      

@validated和@valid不同點

在spring項目中,@validated和@valid功能很類似,都可以在controller層開啟資料校驗功能。但是@validated和@valid又不盡相同。

有以下不同點:

  • @Validated:提供分組功能,可以在參數驗證時,根據不同的分組采用不同的驗證機制;可以用在類型、方法和方法參數上。但是不能用在成員屬性(字段)上
  • @Valid:沒有分組功能;可以用在方法、構造函數、方法參數和成員屬性(字段)上。

@validated的使用注意點

  • @validated和@valid都可以用在controller層的參數前面,但這隻能在controller層生效。
  • @validated如果要開啟方法驗證。注解應該打在類上,而不是方法參數上。
  • @validated不支援嵌套驗證。是以jsr303标準的注解修飾的對象隻能基本類型和包裝類型。其他類型隻能做到檢測是否為空,對于對象裡面的jsr303标準的注解修飾的屬性,不支援驗證。