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 请求执行完成"); } // 设置基础信息