轉自:
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()); } }
至此參數校驗配置完畢。