SpringBoot的请求参数校验及全局异常处理
适用场景
- 请求路径参数的校验
- JSON类型的请求参数校验
- 异常处理
环境搭建
工程构建
- 使用IDEA快速构建一个SpringBoot工程,并引入以下依赖:
<!--Spring Web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--数据校验--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
- 封装返回对象
状态枚举类
响应结果public enum ResponseCodeEnum { /** * 成功 */ SUCCESS(0), /** * 失败 */ FAIL(1); private Integer value; ResponseCodeEnum(Integer value) { this.value = value; } public Integer getValue() { return value; } }
public class ResponseData<T> implements Serializable { private static final long serialVersionUID = 20220510L; /** * 状态 0 成功 1 失败 */ private int code; /** * 响应信息 */ private String message; /** * 响应数据 */ private T data; public ResponseData() { } public ResponseData(int code, String message) { this.code = code; this.message = message; } public ResponseData(int code, String message, T data) { this.code = code; this.message = message; this.data = data; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public T getData() { return data; } public void setData(T data) { this.data = data; } public static <T> ResponseData<T> ok(String message) { return new ResponseData<T>(ResponseCodeEnum.SUCCESS.getValue(), message); } public static <T> ResponseData<T> ok(String message, T data) { return new ResponseData<T>(ResponseCodeEnum.SUCCESS.getValue(), message, data); } public static <T> ResponseData<T> fail(String message) { return new ResponseData<T>(ResponseCodeEnum.FAIL.getValue(), message); } }
- 自定义异常
public class DbManagementException extends RuntimeException { /** * 错误信息 */ private String errorMsg; public DbManagementException(String errorMsg) { this.errorMsg = errorMsg; } public String getErrorMsg() { return errorMsg; } public void setErrorMsg(String errorMsg) { this.errorMsg = errorMsg; } }
- 创建异常处理器
@RestControllerAdvice public class GlobalExceptionHandler { /** * Slf4j日志记录 */ private static Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class); /** * 处理自定义业务异常 * * @param exception * @return */ @ExceptionHandler(value = DbManagementException.class) public ResponseData dbManagementExceptionHandler(DbManagementException exception) { logger.error(exception.getMessage(), exception); return ResponseData.fail(exception.getErrorMsg()); } /** * 参数校验不通过异常处理 * * @param exception * @return * @see RequestBody */ @ExceptionHandler(value = MethodArgumentNotValidException.class) public ResponseData methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException exception) { StringBuffer errStr = new StringBuffer(); BindingResult bindingResult = exception.getBindingResult(); boolean hasErrors = bindingResult.hasErrors(); if (hasErrors) { List<ObjectError> allErrors = bindingResult.getAllErrors(); for (ObjectError allError : allErrors) { FieldError err = (FieldError) allError; String field = err.getField(); String defaultMessage = allError.getDefaultMessage(); errStr.append("[").append(field) .append("]:") .append(defaultMessage) .append(";"); } } logger.error(exception.getMessage(), exception); return ResponseData.fail(errStr.toString()); } /** * required参数缺失异常 * * @param exception * @return * @see RequestParam */ @ExceptionHandler(value = MissingServletRequestParameterException.class) public ResponseData missingServletRequestParameterException(MissingServletRequestParameterException exception) { String parameterName = exception.getParameterName(); String parameterType = exception.getParameterType(); StringBuffer errStr = new StringBuffer(); errStr.append("[").append(parameterName) .append("]") .append(":") .append("is required,") .append("type") .append(":") .append(parameterType); logger.error(exception.getMessage(), exception); return ResponseData.fail(errStr.toString()); } /** * 其它异常处理器 * * @param exception * @return */ @ExceptionHandler(value = Exception.class) public ResponseData otherExceptionHandler(Exception exception) { logger.error(exception.getMessage(), exception); return ResponseData.fail("系统异常"); } }
- 测试
用于演示json类型的请求参数public class JsonParam { /** * id */ @NotNull(message = "id不能为空") private Long id; /** * 姓名 */ @Length(message = "姓名长度不在有效范围", max = 6, min = 2) @NotBlank(message = "姓名不能为空") private String name; /** * 地址 */ @NotBlank(message = "地址不能为空") private String address; /** * 好友 */ @Size(message = "好友列表长度不在有效范围内", min = 1, max = 3) @NotEmpty(message = "好友列表不能为空") private List<String> friends; public JsonParam() { } public JsonParam(Long id, String name, String address, List<String> friends) { this.id = id; this.name = name; this.address = address; this.friends = friends; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<String> getFriends() { return friends; } public void setFriends(List<String> friends) { this.friends = friends; } @Override public String toString() { return "JsonParam{" + "id=" + id + ", name='" + name + '\'' + ", address='" + address + '\'' + ", friends=" + friends + '}'; } }
@Validated @RequestMapping("/demo") @RestController public class DemoController { /** * json格式参数 * * @param params * @return */ @RequestMapping("/json") public ResponseData jsonCheck(@RequestBody @Valid JsonParam params) { return ResponseData.ok("Success", params); } /** * 路径参数 * * @param username * @param password * @return */ @RequestMapping("/path") public ResponseData pathCheck(@RequestParam("username") String username, @RequestParam("password") String password) { return ResponseData.ok("Success", username + ":" + password); } /** * 自定义异常演示 * * @return */ @GetMapping("/customize") public ResponseData customize() { throw new DbManagementException("自定义异常"); } /** * 其它业务异常演示 * * @return */ @GetMapping("/other") public ResponseData other() { int i = 1 / 0; return ResponseData.ok("Success"); } }