# 版本
2.5.2
# 依赖
implementation 'org.springframework.boot:spring-boot-starter-web' | |
implementation 'org.springframework.boot:spring-boot-starter-validation' |
# 全局异常配置
@ControllerAdvice | |
public class ExceptionHandlerAdvice { | |
/** | |
* 全局异常兜底处理 | |
*/ | |
@ExceptionHandler(Exception.class) | |
@ResponseBody | |
public ApiData<Void> handleException(Exception e) { | |
ApiData<Void> apiData = new ApiData<>(); | |
apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
apiData.setMsg(e.getMessage()); | |
return apiData; | |
} | |
/** | |
* 业务异常消息 | |
*/ | |
@ExceptionHandler(ServiceException.class) | |
@ResponseBody | |
public ApiData<Void> handleException(ServiceException e) { | |
ApiData<Void> apiData = new ApiData<>(); | |
apiData.setCode(e.getStatusCode()); | |
apiData.setMsg(e.getMessage()); | |
return apiData; | |
} | |
/** | |
* [@RequestParam] 注解的参数不存在 | |
*/ | |
@ExceptionHandler(MissingServletRequestParameterException.class) | |
@ResponseBody | |
public ApiData<Void> handleException(MissingServletRequestParameterException e) { | |
ApiData<Void> apiData = new ApiData<>(); | |
apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
apiData.setMsg(MessageFormat.format("缺少参数{0},类型[{1}]", e.getParameterName(), e.getParameterType())); | |
return apiData; | |
} | |
/** | |
* [POST/GET] 单参数验证未通过,必须在 Controller 类上加上 @Validated 注解,否则在参数上无效 | |
*/ | |
@ExceptionHandler(ConstraintViolationException.class) | |
@ResponseBody | |
public ApiData<Void> handleException(ConstraintViolationException e) { | |
ApiData<Void> apiData = new ApiData<>(); | |
apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
apiData.setMsg(e.getMessage()); | |
return apiData; | |
} | |
/** | |
* [GET] 对象参数验证未通过 | |
*/ | |
@ExceptionHandler(BindException.class) | |
@ResponseBody | |
public ApiData<Void> handleException(BindException e) { | |
ApiData<Void> apiData = new ApiData<>(); | |
apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
apiData.setMsg(parseErrors(e.getBindingResult()).toString()); | |
return apiData; | |
} | |
/** | |
* [POST] 对象参数验证未通过 | |
*/ | |
@ExceptionHandler(MethodArgumentNotValidException.class) | |
@ResponseBody | |
public ApiData<Void> handleException(MethodArgumentNotValidException e) { | |
ApiData<Void> apiData = new ApiData<>(); | |
apiData.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); | |
apiData.setMsg(parseErrors(e.getBindingResult()).toString()); | |
return apiData; | |
} | |
private Map<String, String> parseErrors(BindingResult bindingResult) { | |
return bindingResult.getAllErrors().stream().collect(Collectors.toMap(objectError -> ((FieldError) objectError).getField(), objectError -> { | |
if (objectError.getDefaultMessage() != null) { | |
return objectError.getDefaultMessage(); | |
} else { | |
return "参数校验失败"; | |
} | |
})); | |
} | |
} |
# 使用
# 单参数验证
/** | |
* 必须在 Controller 类上加上 @Validated 注解,加在参数上无效 | |
*/ | |
@RequestMapping("validate") | |
public void validate(@RequestParam @Min(10) Long id) { | |
System.out.println(id); | |
} |
如果参数不加
@RequestParam
注解,前端请求未携带id
的话,会打印出null
,携带id
的话,会校验参数是否符合条件(会触发ConstraintViolationException
),但是如果加了@NotNull
注解的话,也能拦截到为null
的情况,会触发ConstraintViolationException
。如果参数加了@RequestParam
注解的话,前端请求未携带id
的话,会触发MissingServletRequestParameterException
。@Validated
注解必须要加在Controller
类上,否则校验无效。
# POST 对象
/** | |
* 必须在参数上加上注解 @Validated,类上的无效 | |
*/ | |
@PostMapping("validatePost") | |
public void validatePost(@RequestBody @Validated Parameter parameter) { | |
System.out.println(parameter.toString()); | |
} |
@Validated
注解必须要加在参数上,否则即使Controller
类上加了也无效。@RequestBody
注解,加了的话,MethodArgumentNotValidException
会获取到所有属性的校验错误信息,未加的话,会触发BindException
,只会知道第一个未满足校验条件的属性报错信息。
# GET 对象
/** | |
* 必须在参数上加上注解 @Validated,类上的无效 | |
*/ | |
@GetMapping("validateGet") | |
public void validateGet(@Validated Parameter parameter) { | |
System.out.println(parameter); | |
} |
@Validated
注解必须要加在参数上,否则即使Controller
类上加了也无效。
# 待补充
分组校验的内容 Spring Boot 参数校验以及分组校验的使用
# 总结
- 单参数加
@RequestParam
,@Validated
加在类上 POST
对象加@RequestBody
,@Validated
加在参数上GET
对象不加@RequestBody
,@Validated
加在参数上