diff --git a/IDEA/src/main/java/com/example/api/exception/AccountAndPasswordError.java b/IDEA/src/main/java/com/example/api/exception/AccountAndPasswordError.java new file mode 100644 index 00000000..59d0bba2 --- /dev/null +++ b/IDEA/src/main/java/com/example/api/exception/AccountAndPasswordError.java @@ -0,0 +1,5 @@ +package com.example.api.exception; + +public class AccountAndPasswordError extends Exception{ + +} diff --git a/IDEA/src/main/java/com/example/api/handler/GlobalExceptionHandler.java b/IDEA/src/main/java/com/example/api/handler/GlobalExceptionHandler.java new file mode 100644 index 00000000..b8abd09e --- /dev/null +++ b/IDEA/src/main/java/com/example/api/handler/GlobalExceptionHandler.java @@ -0,0 +1,48 @@ +package com.example.api.handler; + +// 导入自定义的账户和密码错误异常类 +import com.example.api.exception.AccountAndPasswordError; +// 导入用于封装API响应结果的类 +import com.example.api.model.support.ResponseResult; +// 导入登录日志服务接口 +import com.example.api.service.LoginLogService; +// 导入SLF4J的Logger工厂,用于日志记录 +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +// 导入Spring的Autowired注解,用于依赖注入 +import org.springframework.beans.factory.annotation.Autowired; +// 导入Spring Security的访问拒绝异常类 +import org.springframework.security.access.AccessDeniedException; +// 导入Spring MVC的注解,用于定义异常处理方法和全局异常处理 +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +/** + * 捕获controller异常 + * controller抛出异常执行下边的函数 + * 返回Response写入ApiResult + */ +@ResponseBody +@RestControllerAdvice +public class GlobalExceptionHandler { + // 使用@Autowired注解注入LoginLogService + @Autowired + private LoginLogService loginLogService; + // 创建一个Logger实例,用于记录日志 + private final Logger logger = LoggerFactory.getLogger(getClass()); + + // 使用@ExceptionHandler注解定义一个方法来处理所有类型的异常 + @ExceptionHandler(value = Exception.class) + public Object handleException(Exception e) { + // 如果异常是AccessDeniedException类型,返回403状态码和相应消息 + if (e instanceof AccessDeniedException) { + return new ResponseResult<>(403, "你没有访问权限"); + } + // 记录异常信息 + logger.warn(e.getMessage()); + // 对于其他类型的异常,返回400状态码和异常信息 + return new ResponseResult<>(400, e.getMessage()); + } + +} \ No newline at end of file diff --git a/IDEA/src/main/java/com/example/api/handler/GlobalResponseHandler.java b/IDEA/src/main/java/com/example/api/handler/GlobalResponseHandler.java new file mode 100644 index 00000000..ed806544 --- /dev/null +++ b/IDEA/src/main/java/com/example/api/handler/GlobalResponseHandler.java @@ -0,0 +1,42 @@ +package com.example.api.handler; + +// 导入自定义的禁止基础响应注解 +import com.example.api.annotation.DisableBaseResponse; +// 导入用于封装API响应结果的类 +import com.example.api.model.support.ResponseResult; +// 导入Spring的MethodParameter类,用于获取方法参数信息 +import org.springframework.core.MethodParameter; +// 导入Spring的MediaType类,用于表示媒体类型 +import org.springframework.http.MediaType; +// 导入Spring的ServerHttpRequest和ServerHttpResponse类,用于处理HTTP请求和响应 +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +// 导入Spring MVC的@ControllerAdvice注解,用于定义全局的控制器增强 +import org.springframework.web.bind.annotation.ControllerAdvice; +// 导入Spring MVC的ResponseBodyAdvice接口,用于在响应写入前进行处理 +import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; + +/** + * 统一拦截Controller中所有方法的返回值 + * 封装后返回ResponseResult + */ +@ControllerAdvice(value = "com.example.api.controller") +public class GlobalResponseHandler implements ResponseBodyAdvice { + + // 实现supports方法,判断当前方法是否需要被增强 + @Override + public boolean supports(MethodParameter methodParameter, Class c) { + // 如果方法参数上有DisableBaseResponse注解,则不进行增强 + return !methodParameter.hasParameterAnnotation(DisableBaseResponse.class); + } + + // 实现beforeBodyWrite方法,在响应写入前进行处理 + @Override + public Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class aClass, + ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) { + // 如果返回值为null,则返回一个空的ResponseResult对象 + // 否则,将返回值封装在ResponseResult对象中 + return o == null ? new ResponseResult<>() : new ResponseResult<>(o); + } + +} \ No newline at end of file