diff --git a/.gitignore b/.gitignore
index 5ff6309..702ebff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,4 +35,5 @@ build/
.vscode/
### Mac OS ###
-.DS_Store
\ No newline at end of file
+.DS_Store
+/logs/
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
index 928d353..143c39f 100644
--- a/.idea/dataSources.xml
+++ b/.idea/dataSources.xml
@@ -13,5 +13,19 @@
+ * 状态码封装 + *
+ * + * @author yulinling + * @since 2025/6/5 + */ +@Getter +public enum Status { + /** 操作成功 */ + OK(200, "success"), + + /** 未知异常 */ + UNKNOWN_ERROR(500, "Unknown error"); + + /** + * 状态码 + */ + private final Integer code; + + /** + * 内容 + */ + private final String message; + + Status(Integer code, String message) { + this.code = code; + this.message = message; + } + + /** + * 根据code反查枚举 + * + * @param code 状态码 + * @return Status + */ + public static Status fromCode(int code) { + for (Status status : Status.values()) { + if (status.getCode().equals(code)) { + return status; + } + } + return UNKNOWN_ERROR; + } +} diff --git a/src/main/java/asia/yulinling/workflow/controller/TestController.java b/src/main/java/asia/yulinling/workflow/controller/TestController.java index 0543736..cc6f692 100644 --- a/src/main/java/asia/yulinling/workflow/controller/TestController.java +++ b/src/main/java/asia/yulinling/workflow/controller/TestController.java @@ -1,5 +1,9 @@ package asia.yulinling.workflow.controller; +import asia.yulinling.workflow.constant.Status; +import asia.yulinling.workflow.exception.JsonException; +import asia.yulinling.workflow.exception.PageException; +import asia.yulinling.workflow.model.ApiResponse; import cn.hutool.core.lang.Dict; import cn.hutool.json.JSONUtil; import lombok.extern.slf4j.Slf4j; @@ -43,4 +47,15 @@ public class TestController { log.info(jsonStr); return Dict.create().set("json", jsonStr); } + + @GetMapping("/json") + public ApiResponse jsonException() { + throw new JsonException(Status.UNKNOWN_ERROR); + } + + @GetMapping("/page") + public ApiResponse PageException() { + throw new PageException(Status.UNKNOWN_ERROR); + } + } diff --git a/src/main/java/asia/yulinling/workflow/exception/BaseException.java b/src/main/java/asia/yulinling/workflow/exception/BaseException.java new file mode 100644 index 0000000..a20a574 --- /dev/null +++ b/src/main/java/asia/yulinling/workflow/exception/BaseException.java @@ -0,0 +1,32 @@ +package asia.yulinling.workflow.exception; + +import asia.yulinling.workflow.constant.Status; +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + *+ * 异常基类 + *
+ * + * @author yulinling + * @since 2025/6/5 + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class BaseException extends RuntimeException{ + private final Integer code; + private final String message; + + public BaseException(Status status) { + super(status.getMessage()); + this.code = status.getCode(); + this.message = status.getMessage(); + } + + public BaseException(Integer code, String message) { + super(message); + this.code = code; + this.message = message; + } +} diff --git a/src/main/java/asia/yulinling/workflow/exception/JsonException.java b/src/main/java/asia/yulinling/workflow/exception/JsonException.java new file mode 100644 index 0000000..91ae02b --- /dev/null +++ b/src/main/java/asia/yulinling/workflow/exception/JsonException.java @@ -0,0 +1,24 @@ +package asia.yulinling.workflow.exception; + +import asia.yulinling.workflow.constant.Status; +import lombok.Getter; + +/** + *+ * JSON异常 + *
+ * + * @author yulinling + * @since 2025/6/5 + */ +@Getter +public class JsonException extends BaseException { + + public JsonException(Status status) { + super(status); + } + + public JsonException(Integer code, String message) { + super(code, message); + } +} diff --git a/src/main/java/asia/yulinling/workflow/exception/PageException.java b/src/main/java/asia/yulinling/workflow/exception/PageException.java new file mode 100644 index 0000000..8d8c3f4 --- /dev/null +++ b/src/main/java/asia/yulinling/workflow/exception/PageException.java @@ -0,0 +1,23 @@ +package asia.yulinling.workflow.exception; + +import asia.yulinling.workflow.constant.Status; +import lombok.Getter; + +/** + *+ * 页面异常 + *
+ * + * @author yulinling + * @since 2025/6/5 + */ +@Getter +public class PageException extends BaseException { + public PageException(Status status) { + super(status); + } + + public PageException(Integer code, String message) { + super(code, message); + } +} diff --git a/src/main/java/asia/yulinling/workflow/handler/GlobalExceptionHandler.java b/src/main/java/asia/yulinling/workflow/handler/GlobalExceptionHandler.java new file mode 100644 index 0000000..dc40aae --- /dev/null +++ b/src/main/java/asia/yulinling/workflow/handler/GlobalExceptionHandler.java @@ -0,0 +1,52 @@ +package asia.yulinling.workflow.handler; + +import asia.yulinling.workflow.exception.JsonException; +import asia.yulinling.workflow.exception.PageException; +import asia.yulinling.workflow.model.ApiResponse; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; + +/** + *+ * 全局异常处理 + *
+ * + * @author yulinling + * @since 2025/6/5 + */ +@ControllerAdvice +@Slf4j +public class GlobalExceptionHandler { + private static final String DEFAULT_ERROR_VIEW = "error"; + + /** + * 统一 json 异常处理 + * + * @param e JsonException + * @return 统一返回 json 格式 + */ + @ExceptionHandler(Exception.class) + @ResponseBody + public ApiResponse jsonErrorHandler(JsonException e) { + log.error(e.getMessage()); + return ApiResponse.ofException(e); + } + + /** + * 统一 页面 异常处理 + * + * @param e PageException + * @return 统一跳转到异常页面 + */ + @ExceptionHandler(PageException.class) + public ModelAndView pageErrorHandler(PageException e) { + log.error(e.getMessage()); + ModelAndView view = new ModelAndView(); + view.addObject("exception", e); + view.setViewName(DEFAULT_ERROR_VIEW); + return view; + } +} diff --git a/src/main/java/asia/yulinling/workflow/mapper/UserMapper.java b/src/main/java/asia/yulinling/workflow/mapper/UserMapper.java index 5afb11c..b5a65f9 100644 --- a/src/main/java/asia/yulinling/workflow/mapper/UserMapper.java +++ b/src/main/java/asia/yulinling/workflow/mapper/UserMapper.java @@ -1,6 +1,6 @@ package asia.yulinling.workflow.mapper; -import asia.yulinling.workflow.entity.User; +import asia.yulinling.workflow.model.entity.User; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; diff --git a/src/main/java/asia/yulinling/workflow/model/ApiResponse.java b/src/main/java/asia/yulinling/workflow/model/ApiResponse.java new file mode 100644 index 0000000..a603977 --- /dev/null +++ b/src/main/java/asia/yulinling/workflow/model/ApiResponse.java @@ -0,0 +1,125 @@ +package asia.yulinling.workflow.model; + +import asia.yulinling.workflow.constant.Status; +import asia.yulinling.workflow.exception.BaseException; +import lombok.Data; + +/** + *+ * 通用API接口封装 + *
+ * + * @author yulinling + * @since 2025/6/5 + */ +@Data +public class ApiResponse { + /** + * 状态码 + */ + private Integer code; + + /** + * 返回内容 + */ + private String message; + + /** + * 返回数据 + */ + private Object data; + + /** + * 无参构造器 + */ + private ApiResponse() {} + + /** + * 全参构造器 + * + * @param code 状态码 + * @param message 返回内容 + * @param data 返回数据 + */ + private ApiResponse(Integer code, String message, Object data) { + this.code = code; + this.message = message; + this.data = data; + } + + /** + * 构造一个自定义的Api返回 + * + * @param code 状态码 + * @param message 返回内容 + * @param data 返回数据 + * @return ApiResponse + */ + public static ApiResponse of(Integer code, String message, Object data) { + return new ApiResponse(code, message, data); + } + + /** + * 构造一个成功且带数据的Api返回 + * + * @param data 返回数据 + * @return ApiResponse + */ + public static ApiResponse ofSuccess(Object data) { + return ofStatus(Status.OK, data); + } + + /** + * 构造一个成功且自定义数据的Api返回 + * + * @param message 返回内容 + * @return ApiResponse + */ + public static ApiResponse ofMessage(String message) { + return ofStatus(Status.OK, message); + } + + /** + * 构造一个有状态不带数据的Api返回 + * + * @param status 状态{@link Status} + * @return ApiResponse + */ + public static ApiResponse ofStatus(Status status) { + return ofStatus(status, null); + } + + /** + * 构造一个有状态且带数据的Api返回 + * + * @param status 状态{@link Status} + * @param data 返回数据 + * @return ApiResponse + */ + public static ApiResponse ofStatus(Status status, Object data) { + return of(status.getCode(), status.getMessage(), data); + } + + + /** + * 构造一个异常且带数据的Api返回 + * + * @param t 异常 + * @param data 返回数据 + * @return ApiResponse + * @param