Skip to content

Commit be221ab

Browse files
authored
Merge pull request #32 from ReLive27/main
feat: add global exception handler and unified response body wrapper
2 parents 91dfa9b + 2746cac commit be221ab

8 files changed

Lines changed: 161 additions & 0 deletions

File tree

core/src/main/java/io/github/simpleauth0/core/i18n/SimpleAuth0MessageSource.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public class SimpleAuth0MessageSource extends ResourceBundleMessageSource {
1111

1212
private SimpleAuth0MessageSource() {
1313
setBasename("io.github.simpleauth0.messages");
14+
setFallbackToSystemLocale(false);
1415
setDefaultEncoding("UTF-8");
1516
}
1617

core/src/main/resources/io/github/simpleauth0/messages.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,6 @@ auth.request.parse.failed=登录请求解析失败,请检查请求参数格式
1111
auth.credentials.missing=未提供认证凭证,禁止访问
1212
auth.provider.not-found=登录类型错误
1313
auth.service.internal-error=认证服务内部异常,请稍后重试
14+
15+
user.username.notblank=用户名不能为空
16+
server.error=系统错误,请联系管理员

core/src/main/resources/io/github/simpleauth0/messages_en.properties

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,7 @@ auth.request.parse.failed=Failed to parse login request. Please check the reques
1111
auth.credentials.missing=No authentication credentials provided
1212
auth.provider.not-found=Incorrect login type
1313
auth.service.internal-error=Internal authentication service error. Please try again later
14+
15+
16+
user.username.notblank=Username cannot be blank
17+
server.error=System error, please contact the administrator.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.github.simpleauth0.web;
2+
3+
import lombok.Data;
4+
5+
/**
6+
* @author: ReLive27
7+
* @date: 2025/11/19 23:22
8+
*/
9+
@Data
10+
public class ApiError {
11+
private Integer code;
12+
private String errorCode;
13+
private String message;
14+
private long timestamp = System.currentTimeMillis();
15+
16+
17+
public static ApiError fail(Integer code, String errorCode, String message) {
18+
ApiError error = new ApiError();
19+
error.code = code;
20+
error.errorCode = errorCode;
21+
error.message = message;
22+
return error;
23+
}
24+
25+
public static ApiError fail(Integer code, String message) {
26+
ApiError error = new ApiError();
27+
error.code = code;
28+
error.errorCode = "";
29+
error.message = message;
30+
return error;
31+
}
32+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package io.github.simpleauth0.web;
2+
3+
import lombok.Data;
4+
import org.springframework.http.HttpStatus;
5+
6+
/**
7+
* @author: ReLive27
8+
* @date: 2025/11/22 10:59
9+
*/
10+
@Data
11+
public class ApiResponse<T> {
12+
13+
private Integer code;
14+
private String message;
15+
private T data;
16+
private long timestamp = System.currentTimeMillis();
17+
18+
public static <T> ApiResponse<T> success(T data) {
19+
ApiResponse<T> apiResponse = new ApiResponse<>();
20+
apiResponse.code = HttpStatus.OK.value();
21+
apiResponse.message = "success";
22+
apiResponse.data = data;
23+
return apiResponse;
24+
}
25+
26+
public static <T> ApiResponse<T> success(String code, String message) {
27+
ApiResponse<T> apiResponse = new ApiResponse<>();
28+
apiResponse.code = HttpStatus.OK.value();
29+
apiResponse.message = message;
30+
apiResponse.data = null;
31+
return apiResponse;
32+
}
33+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.github.simpleauth0.web;
2+
3+
/**
4+
* @author: ReLive27
5+
* @date: 2025/11/22 11:06
6+
*/
7+
public class ErrorCodes {
8+
public static final String INVALID_PARAMETER = "INVALID_PARAMETER";
9+
public static final String SERVER_ERROR = "SERVER_ERROR";
10+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package io.github.simpleauth0.web;
2+
3+
import io.github.simpleauth0.core.i18n.SimpleAuth0MessageSource;
4+
import lombok.extern.slf4j.Slf4j;
5+
import org.springframework.context.i18n.LocaleContextHolder;
6+
import org.springframework.context.support.MessageSourceAccessor;
7+
import org.springframework.http.HttpStatus;
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.MethodArgumentNotValidException;
10+
import org.springframework.web.bind.annotation.ExceptionHandler;
11+
import org.springframework.web.bind.annotation.RestControllerAdvice;
12+
13+
/**
14+
* @author: ReLive27
15+
* @date: 2025/11/19 23:02
16+
*/
17+
@Slf4j
18+
@RestControllerAdvice
19+
public class GlobalExceptionHandler {
20+
private MessageSourceAccessor messageSource = SimpleAuth0MessageSource.getAccessor();
21+
22+
@ExceptionHandler(MethodArgumentNotValidException.class)
23+
public ResponseEntity<Object> handlerMethodException(MethodArgumentNotValidException e) {
24+
log.error("参数校验异常", e);
25+
String msg = e.getBindingResult().getFieldError().getDefaultMessage();
26+
return ResponseEntity.status(HttpStatus.OK)
27+
.body(ApiError.fail(HttpStatus.BAD_REQUEST.value(), ErrorCodes.INVALID_PARAMETER, msg));
28+
}
29+
30+
@ExceptionHandler(Exception.class)
31+
public ResponseEntity<Object> handlerConfusionException(Exception e) {
32+
log.error("系统异常", e);
33+
return ResponseEntity.status(HttpStatus.OK)
34+
.body(ApiError.fail(HttpStatus.INTERNAL_SERVER_ERROR.value(), ErrorCodes.SERVER_ERROR, messageSource.getMessage("server.error", "系统错误,请联系管理员", LocaleContextHolder.getLocale())));
35+
}
36+
37+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package io.github.simpleauth0.web;
2+
3+
import org.springframework.core.MethodParameter;
4+
import org.springframework.http.MediaType;
5+
import org.springframework.http.converter.HttpMessageConverter;
6+
import org.springframework.http.server.ServerHttpRequest;
7+
import org.springframework.http.server.ServerHttpResponse;
8+
import org.springframework.web.bind.annotation.RestControllerAdvice;
9+
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
10+
11+
/**
12+
* @author: ReLive27
13+
* @date: 2025/11/20 23:03
14+
*/
15+
@RestControllerAdvice
16+
public class GlobalResponseBodyAdvice implements ResponseBodyAdvice<Object> {
17+
@Override
18+
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
19+
return true;
20+
}
21+
22+
@Override
23+
public Object beforeBodyWrite(Object body,
24+
MethodParameter returnType,
25+
MediaType selectedContentType,
26+
Class<? extends HttpMessageConverter<?>> selectedConverterType,
27+
ServerHttpRequest request,
28+
ServerHttpResponse response) {
29+
30+
// 异常情况交给 GlobalExceptionHandler,不在此统一封装
31+
if (body instanceof ApiError) {
32+
return body;
33+
}
34+
35+
if (body == null) {
36+
return ApiResponse.success(null);
37+
}
38+
39+
return ApiResponse.success(body);
40+
}
41+
}

0 commit comments

Comments
 (0)