Skip to content

Commit 48e620d

Browse files
committed
feat: 引入 validation,配置统一异常处理
1 parent f7cb98e commit 48e620d

4 files changed

Lines changed: 119 additions & 2 deletions

File tree

simple-common/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@
2727
<groupId>org.springframework.boot</groupId>
2828
<artifactId>spring-boot-starter-aop</artifactId>
2929
</dependency>
30+
<!--validation-->
31+
<dependency>
32+
<groupId>org.springframework.boot</groupId>
33+
<artifactId>spring-boot-starter-validation</artifactId>
34+
</dependency>
3035
<!--Spring Security-->
3136
<dependency>
3237
<groupId>org.springframework.boot</groupId>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package top.cadecode.sra.common.enums.error;
2+
3+
import lombok.Getter;
4+
import top.cadecode.sra.common.exception.ApiErrorCode;
5+
6+
/**
7+
* @author Cade Li
8+
* @date 2022/5/30
9+
* @description 框架异常枚举
10+
*/
11+
@Getter
12+
public enum FrameErrorEnum implements ApiErrorCode {
13+
14+
VALIDATED_ERROR(1, "参数校验不通过"),
15+
REQ_PARAM_INVALID(2, "请求参数无效"),
16+
REQ_BODY_INVALID(3, "请求体无效"),
17+
MEDIA_TYPE_NO_SUPPORT(4, "MediaType 不被支持"),
18+
PARAM_TYPE_CONVERT_ERROR(4, "参数类型转换错误"),
19+
;
20+
21+
private final String code;
22+
23+
private final String message;
24+
25+
FrameErrorEnum(int code, String message) {
26+
this.code = "FRAME_" + code;
27+
this.message = message;
28+
}
29+
}

simple-framework/src/main/java/top/cadecode/sra/framework/exception/ApiExceptionAdvisor.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import lombok.extern.slf4j.Slf4j;
44
import org.springframework.web.bind.annotation.ExceptionHandler;
5-
import org.springframework.web.bind.annotation.ResponseBody;
65
import org.springframework.web.bind.annotation.RestControllerAdvice;
76
import top.cadecode.sra.common.exception.ApiErrorCode;
87
import top.cadecode.sra.common.exception.ApiException;
@@ -30,7 +29,6 @@ public ApiResult<Object> handleApiException(ApiException e) {
3029
* 兜底处理一般异常
3130
*/
3231
@ExceptionHandler(Exception.class)
33-
@ResponseBody
3432
public ApiResult<Object> handleException(Exception e) {
3533
log.error("Exception =>", e);
3634
return ApiResult.error(ApiErrorCode.UNKNOWN).moreInfo(e.getMessage());
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package top.cadecode.sra.framework.exception;
2+
3+
import lombok.extern.slf4j.Slf4j;
4+
import org.springframework.beans.TypeMismatchException;
5+
import org.springframework.core.Ordered;
6+
import org.springframework.core.annotation.Order;
7+
import org.springframework.http.converter.HttpMessageNotReadableException;
8+
import org.springframework.validation.BindException;
9+
import org.springframework.web.HttpMediaTypeNotSupportedException;
10+
import org.springframework.web.bind.ServletRequestBindingException;
11+
import org.springframework.web.bind.annotation.ExceptionHandler;
12+
import org.springframework.web.bind.annotation.RestControllerAdvice;
13+
import top.cadecode.sra.common.enums.error.FrameErrorEnum;
14+
import top.cadecode.sra.common.exception.ApiErrorCode;
15+
import top.cadecode.sra.common.response.ApiResult;
16+
import top.cadecode.sra.common.response.ApiStatus;
17+
18+
import javax.servlet.http.HttpServletRequest;
19+
import java.util.HashMap;
20+
import java.util.Map;
21+
import java.util.Map.Entry;
22+
import java.util.stream.Collectors;
23+
24+
/**
25+
* @author Cade Li
26+
* @date 2022/5/30
27+
* @description 框架异常处理器
28+
*/
29+
@Slf4j
30+
@RestControllerAdvice
31+
@Order(Ordered.HIGHEST_PRECEDENCE)
32+
public class FrameExceptionAdvisor {
33+
34+
/**
35+
* 处理参数校验异常
36+
*/
37+
@ExceptionHandler(value = BindException.class)
38+
public ApiResult<Object> handleValidationException(BindException e, HttpServletRequest request) {
39+
log.error("Validation Exception =>", e);
40+
// 获取错误信息,并拼接
41+
String msg = e.getBindingResult().getFieldErrors().stream()
42+
.map(o -> "[" + o.getField() + "]" + o.getDefaultMessage())
43+
.collect(Collectors.joining(","));
44+
return ApiResult.of(ApiStatus.BAD_REQUEST, FrameErrorEnum.VALIDATED_ERROR, null)
45+
.moreInfo(msg).path(request.getRequestURI());
46+
}
47+
48+
/**
49+
* Spring MVC 异常类型和错误枚举的映射
50+
*/
51+
private static final Map<Class<?>, ApiErrorCode> MVC_EXP_CODE_MAP = new HashMap<Class<?>, ApiErrorCode>() {{
52+
// 请求参数错误
53+
put(ServletRequestBindingException.class, FrameErrorEnum.REQ_PARAM_INVALID);
54+
// 请求体错误
55+
put(HttpMessageNotReadableException.class, FrameErrorEnum.REQ_BODY_INVALID);
56+
// content-type 错误
57+
put(HttpMediaTypeNotSupportedException.class, FrameErrorEnum.MEDIA_TYPE_NO_SUPPORT);
58+
// 参数类型转换错误
59+
put(TypeMismatchException.class, FrameErrorEnum.PARAM_TYPE_CONVERT_ERROR);
60+
}};
61+
62+
/**
63+
* 处理 Spring MVC 参数异常
64+
*/
65+
@ExceptionHandler({
66+
ServletRequestBindingException.class,
67+
HttpMessageNotReadableException.class,
68+
HttpMediaTypeNotSupportedException.class,
69+
TypeMismatchException.class
70+
})
71+
public ApiResult<Object> handleMvcException(Exception e, HttpServletRequest request) {
72+
log.error("Spring MVC Exception Handler =>", e);
73+
String requestURI = request.getRequestURI();
74+
// 根据异常类型查找 map 中的 code 枚举
75+
ApiErrorCode errorCode = MVC_EXP_CODE_MAP.entrySet()
76+
.stream()
77+
.filter(o -> o.getKey().isAssignableFrom(e.getClass()))
78+
.map(Entry::getValue)
79+
.findFirst()
80+
.orElse(ApiErrorCode.UNKNOWN);
81+
return ApiResult.of(ApiStatus.BAD_REQUEST, errorCode, null)
82+
.moreInfo(e.getMessage())
83+
.path(requestURI);
84+
}
85+
}

0 commit comments

Comments
 (0)