分享知識 傳遞快樂
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标準的注解修飾的屬性,不支援驗證。