Spring Boot 优雅地实现接口参数校验

今天继续为大家分享在工作中如何优雅的校验接口的参数的合法性以及如何统一处理接口返回的json格式 。每个字都是干货,原创不易,分享不易 。

Spring Boot 优雅地实现接口参数校验

文章插图
 
validation主要是校验用户提交的数据的合法性,比如是否为空,密码是否符合规则,邮箱格式是否正确等等,校验框架比较多,用的比较多的是hibernate-validator,也支持国际化,也可以自定义校验类型的注解,这里只是简单地演示校验框架在Spring Boot中的简单集成,要想了解更多可以参考 hibernate-validator 。
1. pom.xml<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>2. dtopublic class UserInfoIDto {private Long id;@NotBlank@Length(min=3, max=10)private String username;@NotBlank@Emailprivate String email;@NotBlank@Pattern(regexp="^((13[0-9])|(15[^4,\D])|(18[0,3-9]))\d{8}$", message="手机号格式不正确")private String phone;@Min(value=https://www.isolves.com/it/cxkf/kj/2020-11-19/18)@Max(value = 200)private int age;@NotBlank@Length(min=6, max=12, message="昵称长度为6到12位")private String nickname;// Getter & Setter}3. controllerimport org.springframework.validation.BindingResult;import org.springframework.validation.FieldError;@RestControllerpublic class SimpleController {@PostMApping("/users")public String register(@Valid @RequestBody UserInfoIDto userInfoIDto, BindingResult result){if (result.hasErrors()) {FieldError fieldError = result.getFieldError();String field = fieldError.getField();String msg = fieldError.getDefaultMessage();return field + ":" + msg;}System.out.println("开始注册用户...");return "success";}}
Spring Boot 优雅地实现接口参数校验

文章插图
 
4. 去掉BindingResult参数每个接口都需要BindingResult参数,而且每个接口都需要处理错误信息,这样增加一个参数也不优雅,处理错误信息代码量也很重复 。如果去掉BindingResult参数,系统就会报错MethodArgumentNotValidException,我们只需要使用全局异常来捕获该错误,处理一下就可以省略传BindingResult参数了 。
@RestControllerpublic class SimpleController {@PostMapping("/users")public String register(@Valid @RequestBody UserInfoIDto userInfoIDto){System.out.println("开始注册用户...");return "success";}}@RestControllerAdvice 用于拦截所有的@RestController
@RestControllerAdvicepublic class GlobalExceptionHandlerAdvice {@ExceptionHandler(MethodArgumentNotValidException.class)public String methodArgumentNotValidException(MethodArgumentNotValidException e) {// 从异常对象中拿到ObjectError对象ObjectError objectError = e.getBindingResult().getAllErrors().get(0);// 然后提取错误提示信息进行返回return objectError.getDefaultMessage();}}
Spring Boot 优雅地实现接口参数校验

文章插图
 
5. 统一返回格式错误码枚举
@Getterpublic enum ErrorCodeEnum {SUCCESS(1000, "成功"),FAILED(1001, "响应失败"),VALIDATE_FAILED(1002, "参数校验失败"),ERROR(5000, "未知错误");private Integer code;private String msg;ErrorCodeEnum(int code, String msg) {this.code = code;this.msg = msg;}}【Spring Boot 优雅地实现接口参数校验】自定义异常 。
@Getterpublic class APIException extends RuntimeException {private int code;private String msg;public APIException(ErrorCodeEnum errorCodeEnum) {super(errorCodeEnum.getMsg());this.code = errorCodeEnum.getCode();this.msg = errorCodeEnum.getMsg();}}定义返回格式 。
@Getterpublic class Response<T> {/*** 状态码,比如1000代表响应成功*/private int code;/*** 响应信息,用来说明响应情况*/private String msg;/*** 响应的具体数据*/private T data;public Response(T data) {this.code = ErrorCodeEnum.SUCCESS.getCode();this.msg = ErrorCodeEnum.SUCCESS.getMsg();this.data = https://www.isolves.com/it/cxkf/kj/2020-11-19/data;}public Response(int code, String msg) {this.code = code;this.msg = msg;}}全局异常处理器增加对APIException的拦截,并修改异常时返回的数据格式 。
@RestControllerAdvicepublic class GlobalExceptionHandlerAdvice {@ExceptionHandler(MethodArgumentNotValidException.class)public Response<String> methodArgumentNotValidException(MethodArgumentNotValidException e) {// 从异常对象中拿到ObjectError对象ObjectError objectError = e.getBindingResult().getAllErrors().get(0);// 然后提取错误提示信息进行返回return new Response<>(ErrorCodeEnum.VALIDATE_FAILED.getCode(), objectError.getDefaultMessage());}@ExceptionHandler(APIException.class)public Response<String> APIExceptionHandler(APIException e) {return new Response<>(e.getCode(), e.getMsg());}}


推荐阅读