轉自:
https://blog.csdn.net/cp026la/article/details/86495659
扯淡:
剛開始寫代碼的時候對參數的校驗要么不做、要么寫很多類似 if( xx == null){ … }的語句,總想參數校驗可以交給前端處理(很機智),服務端對參數的校驗同樣重要。
參數校驗:
springboot需要引入spring-boot-starter-validation(使用Hibernate Validator 框架提供驗證功能) 依賴進行參數校驗,由於本項目中已經引入了spring-boot-starter-web 依賴(包含spring-boot-starter-validation依賴),就不需要重復引用了。
1、基本注解介紹:
@NotEmpty:作用在String、collection、map、數組上,不能為null,size > 0 @NotBlank: 只能用於String,不能為null,也不可以是" ",即trim()后長度大於0 @@NotNull:作用於任何類型,不能為null,可以為空 @AssertTrue:必須為true @AssertFalse:必須為false @Min(value):必須為一個數字,且值大於等於指定的值 @Max(value):必須為一個數字,且值小於等於指定的值 @Size(max,min):限制參數大小范圍 @Future:必須是一個將來的日期 @Past:必須是一個過去的日期 @Pattern(value):指定正則
2、實體類:
/**
* @Auther: xf
* @Date: 2018/11/01 23:27
* @Description:
*/
@Data
public class ValidEntity {
@NotBlank(message = "name不可以為空")
@Size(min = 2,max = 4,message = "name的長度范圍為2-4")
private String name;
@NotNull(message = "age 不能為null")
@Min(value = 0, message = "age 最小值不能小於0")
private int age;
}
3、測試Controller:
/**
* @Auther: xf
* @Date: 2018/11/01 23:35
* @Description: 測試參數校驗
*/
@RestController
@Slf4j
public class TestValidController {
@PostMapping(value = "/valid")
public ApiResult valid(@Valid @RequestBody ValidEntity validEntity) {
log.info(">>>>實體類信息為:>>>>{}", JSON.toJSONString(validEntity));
return ApiResult.ok(validEntity);
}
}
4、測試結果:
此處為POST請求,使用Postman:
4.1、正確傳參(此處為JSON格式的參數)返回結果正確。
4.2、錯誤傳參 錯誤響應信息

錯誤日志:

5、注意:
此處的日志很顯然是統一異常處理類GlobalExceptionHandler中的日志,即參數校驗不通過的時候走到了統一異常處理類中了。這里返回了所有的異常信息,顯得不優雅,我們可以在統一異常處理類中斷點調試得到該JSON格式錯誤的參數校驗不通過是使用的MethodArgumentNotValidException 返回的。

6、當我將請求參數的@RequestBody 去掉后:
@PostMapping(value = "/valid")
public ApiResult valid(@Valid ValidEntity validEntity) {
log.info(">>>>實體類信息為:>>>>{}", JSON.toJSONString(validEntity));
return ApiResult.ok(validEntity);
}
再次請求:

斷點調試得到的是BindException

於是,我們可以在統一異常處理類中添加這兩個異常的處理方法,當然也可以在原來的Exception 處理中去做判斷,這里分別添加這兩個異常的處理。
7、修改原來的全局異常處理類:
@RestControllerAdvice(annotations = {RestController.class})
@Slf4j
public class GlobalExceptionHandler {
/**
* 默認統一異常處理方法
* @ExceptionHandler 注解用來配置需要攔截的異常類型, 也可以是自定義異常
*/
@ExceptionHandler(Exception.class)
// 此處可以指定返回的狀態碼 和 返回 結果說明
// @ResponseStatus(reason = "exception",value = HttpStatus.BAD_REQUEST)
public Object runtimeExceptionHandler(Exception e) {
// 打印異常信息到控制台
e.printStackTrace();
log.error("請求出現異常,異常信息為: {}", e.getMessage());
// 使用公共的結果類封裝返回結果, 這里我指定狀態碼為 400
return ApiResult.build(400, e.getMessage());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ApiResult handleBindException(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
log.info("參數校驗異常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
return ApiResult.build(400, fieldError.getDefaultMessage());
}
@ExceptionHandler(BindException.class)
public ApiResult handleBindException(BindException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
log.info("參數校驗異常:{}({})", fieldError.getDefaultMessage(),fieldError.getField());
return ApiResult.build(400, fieldError.getDefaultMessage());
}
}
至此參數校驗配置完畢。
