From ccb74d4b3a4b8a2980e0a986d596b3f713f3eb3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Sat, 7 Jun 2025 15:30:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=84=E5=88=92=E5=AE=8C=E6=88=90=E5=85=A8?= =?UTF-8?q?=E5=B1=80=E5=BC=82=E5=B8=B8=E6=8D=95=E8=8E=B7=E6=96=B9=E6=A1=88?= =?UTF-8?q?,=20=E5=90=8E=E7=BB=AD=E6=96=B0=E5=BC=82=E5=B8=B8=E5=9C=A8?= =?UTF-8?q?=E6=AD=A4=E5=A4=84=E6=B7=BB=E5=8A=A0=E5=8D=B3=E5=8F=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 2 +- springboot-common.iml | 334 ++++++++++++++ springboot-common.ipr | 107 +++++ springboot-common.iws | 418 ++++++++++++++++++ .../java/cn/zhangdeman/context/Response.java | 13 +- .../handler/GlobalExceptionHandler.java | 64 +++ .../zhangdeman/filter/RequestInitFilter.java | 3 +- 7 files changed, 933 insertions(+), 8 deletions(-) create mode 100644 springboot-common.iml create mode 100644 springboot-common.ipr create mode 100644 springboot-common.iws create mode 100644 src/main/java/cn/zhangdeman/exception/handler/GlobalExceptionHandler.java diff --git a/pom.xml b/pom.xml index b13688f..89155a8 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ gitea - https://gitea.example.com/api/packages/java/maven + https://git.zhangdeman.cn/api/packages/java/maven diff --git a/springboot-common.iml b/springboot-common.iml new file mode 100644 index 0000000..25ec0b4 --- /dev/null +++ b/springboot-common.iml @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/springboot-common.ipr b/springboot-common.ipr new file mode 100644 index 0000000..77588ae --- /dev/null +++ b/springboot-common.ipr @@ -0,0 +1,107 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/springboot-common.iws b/springboot-common.iws new file mode 100644 index 0000000..03c854e --- /dev/null +++ b/springboot-common.iws @@ -0,0 +1,418 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/cn/zhangdeman/context/Response.java b/src/main/java/cn/zhangdeman/context/Response.java index 48a6879..d5c5860 100644 --- a/src/main/java/cn/zhangdeman/context/Response.java +++ b/src/main/java/cn/zhangdeman/context/Response.java @@ -33,12 +33,14 @@ public class Response { private Data data; // 响应数据 @JsonProperty(RecordField.RESPONSE_ERROR_DETAIL) private Object errorDetail; // 异常详情 + @JsonIgnore + private HttpStatus httpStatus = HttpStatus.OK; // 响应http状态码, 默认 200 @JsonProperty(RecordField.RESPONSE_HTTP_CODE) - private HttpStatus httpCode = HttpStatus.OK; // 响应http状态码, 默认 200 + private Integer httpCode = HttpStatus.OK.value(); // 响应http状态码, 默认 200 @JsonProperty(RecordField.RESPONSE_HEADER) - private Map header; // 响应头 + private Map header = new HashMap<>(); // 响应头 @JsonProperty(RecordField.RESPONSE_COOKIE) - private Map cookie; // 响应cookie + private Map cookie = new HashMap<>(); // 响应cookie @JsonIgnore private RuntimeContext runtimeContext; @@ -81,7 +83,7 @@ public class Response { } } // 设置响应状态码 - runtimeContext.getHttpServletResponse().setStatus(getHttpCode().value()); + runtimeContext.getHttpServletResponse().setStatus(getHttpCode()); } // 请求成功, 200 状态码 @@ -121,7 +123,8 @@ public class Response { // 任意姿势的响应 public Response any(HttpStatus httpStatus, String code, String message, Data data) { - setHttpCode(httpStatus); + setHttpStatus(httpStatus); + setHttpCode(httpStatus.value()); setCode(code); setMessage(message); setData(data); diff --git a/src/main/java/cn/zhangdeman/exception/handler/GlobalExceptionHandler.java b/src/main/java/cn/zhangdeman/exception/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..e0aa8f6 --- /dev/null +++ b/src/main/java/cn/zhangdeman/exception/handler/GlobalExceptionHandler.java @@ -0,0 +1,64 @@ +package cn.zhangdeman.exception.handler; + +import cn.zhangdeman.consts.RecordField; +import cn.zhangdeman.context.Response; +import cn.zhangdeman.context.RuntimeContext; +import cn.zhangdeman.exception.CustomException; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.context.request.WebRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +@RestControllerAdvice // 适用于REST API,返回JSON响应 +public class GlobalExceptionHandler { + // 获取runtime context + private RuntimeContext getRuntimeContext(HttpServletRequest httpServletRequest) { + Object object = httpServletRequest.getAttribute(RecordField.RUNTIME_THREAD_CONTEXT); + return (RuntimeContext) object; + } + + // 构建相应实体 + private ResponseEntity getResponseEntity(Response response) { + ResponseEntity.BodyBuilder builder = ResponseEntity.status(response.getHttpCode()); + for (Map.Entry header : response.getHeader().entrySet()) { + builder.header(header.getKey(), header.getValue()); + } + return ResponseEntity.status(response.getHttpCode()) + .body(response); + } + + // 处理自定义业务异常 + @ExceptionHandler(cn.zhangdeman.exception.CustomException.class) + public ResponseEntity handleBusinessException(CustomException customException, HttpServletRequest httpServletRequest) { + RuntimeContext runtimeContext = getRuntimeContext(httpServletRequest); + Response response = new Response<>(runtimeContext).failure(customException); + return getResponseEntity(response); + } + + // 处理参数校验异常(如@NotNull、@Size等校验失败)对应validate库 + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity handleValidationException(MethodArgumentNotValidException ex, HttpServletRequest httpServletRequest) { + List errors = new ArrayList<>(); + ex.getBindingResult().getFieldErrors().forEach(itemErr -> errors.add(itemErr.getField() + ":" + itemErr.getDefaultMessage())); + + RuntimeContext runtimeContext = getRuntimeContext(httpServletRequest); + Response response = new Response<>(runtimeContext).failure("400", String.join(" - ", errors), ex.getFieldErrors()); + return getResponseEntity(response); + } + + + // 处理其他未捕获的异常 + @ExceptionHandler(Exception.class) + public ResponseEntity handleGlobalException(Exception ex, HttpServletRequest httpServletRequest) { + RuntimeContext runtimeContext = getRuntimeContext(httpServletRequest); + Response response = new Response<>(runtimeContext).failure("500", ex.getMessage(), ex.getCause()); + return getResponseEntity(response); + } +} diff --git a/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java b/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java index 667688e..effca5e 100644 --- a/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java +++ b/src/main/java/cn/zhangdeman/filter/RequestInitFilter.java @@ -3,7 +3,6 @@ package cn.zhangdeman.filter; import cn.zhangdeman.consts.RecordField; import cn.zhangdeman.context.Request; -import cn.zhangdeman.context.Response; import cn.zhangdeman.context.RuntimeContext; import jakarta.servlet.FilterChain; import jakarta.servlet.FilterConfig; @@ -50,7 +49,7 @@ public class RequestInitFilter extends HttpFilter { httpServletRequest.setAttribute(RecordField.RUNTIME_THREAD_CONTEXT, runtimeContext); // 记录到请求上下文中 // 继续向后执行 filterChain.doFilter(httpServletRequest, httpServletResponse); - System.out.println("init request do filter 请求执行完成"); + // System.out.println("init request do filter 请求执行完成"); } // 设置基础信息