@ControllerAdvice抛自定义异常遇ClassNotFoundException问题求助
问题解答
能不能在@ControllerAdvice中抛出新异常?
完全可以,这是Spring全局异常处理的常规用法——捕获底层异常后转抛上层自定义异常,既能隐藏底层敏感信息,也能统一异常处理逻辑。
针对ClassNotFoundException的修改方案
你遇到的com.sun.proxy.$Proxy205类找不到错误,大概率是原方法返回值为void且直接抛异常,导致Spring代理类生成逻辑出现问题。结合你的需求,给出两种可行修改方案:
方案一:直接返回统一错误响应体(推荐)
无需额外抛异常,直接给前端返回规范的非敏感错误信息,同时在后端记录完整异常日志:
@Log4j2 @ControllerAdvice public class GlobalSQLExceptionHandler { /** * 处理SQL异常,返回统一错误响应 */ @ExceptionHandler(value = SQLException.class) @ResponseBody public ResponseEntity<ErrorResponse> sqlExceptionHandler(HttpServletRequest req, SQLException e){ // 记录完整异常堆栈,方便后端排查问题 log.error("数据库操作异常,请求路径:{}", req.getRequestURI(), e); // 构造仅包含非敏感信息的响应体 ErrorResponse errorResponse = new ErrorResponse("500", "数据库操作发生异常"); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } } // 统一错误响应DTO public class ErrorResponse { private String code; private String message; public ErrorResponse(String code, String message) { this.code = code; this.message = message; } // getter、setter方法省略 }
方案二:转抛自定义ServiceException并新增对应处理器
如果需要统一处理所有自定义业务异常,可以先转抛ServiceException,再单独写处理器处理它:
@Log4j2 @ControllerAdvice public class GlobalExceptionHandler { /** * 捕获SQLException,转抛自定义异常 */ @ExceptionHandler(SQLException.class) public void handleSQLException(SQLException e) { log.error("数据库操作异常:", e); throw new ServiceException("数据库操作发生异常"); } /** * 处理自定义ServiceException,返回统一响应 */ @ExceptionHandler(ServiceException.class) @ResponseBody public ResponseEntity<ErrorResponse> handleServiceException(ServiceException e) { ErrorResponse errorResponse = new ErrorResponse("500", e.getMessage()); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } } // 自定义ServiceException(需继承RuntimeException,确保Spring能自动捕获) public class ServiceException extends RuntimeException { public ServiceException(String message) { super(message); } }
额外注意事项
- 确保
ServiceException是public修饰且继承自RuntimeException,否则Spring无法正常捕获处理; - 检查
@ControllerAdvice所在类是否被Spring扫描到(比如所在包在@SpringBootApplication的扫描范围内); - 日志记录时务必传入完整异常对象(如
log.error(..., e)),不要只记录消息,方便后续排查问题; - 打包部署时确认
ServiceException和错误响应类已被正确包含在类路径中,避免类加载问题。
内容的提问来源于stack exchange,提问作者HoshinaJiuGe
相关产品推荐
相关产品推荐

