当前位置: 首页 > news >正文

自定义异常处理(全局异常处理)

基于Springboot框架来处理。
能实现的有:自定义异常、自定义全局异常、自定义有条件的异常处理、自定义含业务参数的自定义异常

单个异常处理

基于框架,简单来说就是通过@ExceptionHandler注解就能实现需求,即自定义异常。注意,需要放在Controller类中(可以专门定义一个Controller类做自定义注解)。

//注解,参数是具体的异常类
@ExceptionHandler(MissingServletRequestParameterException.class)
//这里的参数,一般就是对应的异常类,还可以传递如HttpServletRequest来实现更加复杂的业务逻辑
//返回类也允许自己定义。也可以直接返回原来的异常。
public ResponseEntity<Map<String, Object>> handleMissingParams(MissingServletRequestParameterException ex,
HttpServletRequest request) {Map<String, Object> response = new HashMap<>();response.put("status", 400);response.put("message", "必需参数缺失: " + ex.getParameterName());return ResponseEntity.badRequest().body(response);
}
全局异常

定义一个@ControllerAdvice(@RestControllerAdvice)全局处理器类,在这个类里面进行大量的需要自己处理的异常封装,不需要处理的直接省略原样返回既可。

@ControllerAdvice
public class GlobalExceptionHandler {//允许自定义状态码,将一个方法或异常类标注一个应返回的HTTP状态码(code())和原因说明(reason()//@ResponseStatus(HttpStatus.BAD_REQUEST)@ExceptionHandler(MissingServletRequestParameterException.class)public ErrorResult handleMissingParameter(MissingServletRequestParameterException e) {return new ErrorResult(400, "PARAM_MISSING", "缺少必要参数: " + e.getParameterName());}/*** 异常一*/public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException{resp.setContentType("text/html;charset=utf-8");PrintWriter out = resp.getWriter();out.write("上传文件大小超出限制!");out.flush();out.close();}/*** 异常二*/@ExceptionHandler(MissingServletRequestParameterException.class)public ErrorResult handleMissingParameter(MissingServletRequestParameterException e) {return new ErrorResult(400, "PARAM_MISSING", "缺少必要参数: " + e.getParameterName());}/*** 异常三*/@ExceptionHandler(MissingServletRequestParameterException.class)public ErrorResult handleMissingParameter(MissingServletRequestParameterException e) {return new ErrorResult(400, "PARAM_MISSING", "缺少必要参数: " + e.getParameterName());}/*** 异常四*/@ExceptionHandler(MissingServletRequestParameterException.class)public ErrorResult handleMissingParameter(MissingServletRequestParameterException e) {return new ErrorResult(400, "PARAM_MISSING", "缺少必要参数: " + e.getParameterName());}
}
自定义特定条件异常处理

实现‌仅对特定URL进行处理,即只有某些url或者某种条件下的才进行处理,需要在自定义异常中做业务处理。

@ControllerAdvice
public class SelectiveExceptionHandler {private static final Set<String> TARGET_URLS = Set.of("/api/v1/validate", "/secure/check");@ExceptionHandler(MissingServletRequestParameterException.class)public ResponseEntity<?> handleMissingParam(MissingServletRequestParameterException ex, HttpServletRequest request) {// 仅处理指定URLif (TARGET_URLS.contains(request.getRequestURI())) {return ResponseEntity.badRequest().body(Map.of("error", "参数缺失", "param", ex.getParameterName()));}// 其他URL继续抛出原始异常throw ex;}
}
自定义业务参数全局实现类。

这个方法与上面的 自定义特定条件异常处理 可以混用,即先定义一个自定义异常,在自定义异常中封装所需要的数据,然后再全局异常中,处理自定义异常。

1.自定义异常

// 定义包含业务参数的异常类
public class BusinessException extends RuntimeException {private final String errorCode;private final Map<String, Object> businessData;  // 业务参数容器public BusinessException(String code, String message, Map<String, Object> data) {super(message);this.errorCode = code;this.businessData = data;}// getters...
}

2.定义全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {//注意看这里的异常已经是自定义异常了,包括传参,这样就能在异常中通过这些业务数据进行逻辑处理@ExceptionHandler(BusinessException.class)@ResponseBodypublic ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex, HttpServletRequest request) {ErrorResponse response = new ErrorResponse(ex.getErrorCode(),ex.getMessage(),request.getRequestURI(),ex.getBusinessData()  // 将业务参数封装到响应体);return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);}
}

3.业务实际使用

throw new BusinessException("VALID_001", "参数校验失败", Map.of("field", "age", "rejectedValue", "abc"));
throw new BusinessException("AUTH_003", "权限不足",Map.of("requiredRole", "ADMIN", "currentRole", "USER"));

注意的是,我们的异常处理可能很难包含到全部,所以我们只需要处理自己关注的,常规的一些已经被框架定义好了,如果当发现某些异常不好理解的时候,做一些封装定义既可。

相关文章:

  • 用python进行OCR识别
  • 《解锁LLMs from scratch:开启大语言模型的探索之旅》
  • “生成式AI大模型、多模态技术开发与应用”学习
  • 谈谈接口和抽象类有什么区别?
  • 在 WSL 安装 OpenFOAM-12
  • stone 3d v3.3.0版本发布,含时间线和连接器等新功能
  • Coding Practice,48天强训(22)
  • Nginx通过自定义参数,实现同一域名在不同设备下访问不同站点的操作
  • RefFormer论文精读
  • 【MySQL专栏】MySQL数据库的复合查询语句
  • 用 LangChain 手搓 RAG 系统:从原理到实战
  • [AI技术(二)]JSONRPC协议MCPRAGAgent
  • Cadence学习笔记之---原理图设计基本操作
  • ValidatorUtils工具
  • 《Piper》皮克斯技术解析:RIS系统与云渲染如何创造奥斯卡级动画短片
  • 【C语言练习】002. 理解C语言的基本语法结构
  • ECMAScript 1(ES1):JavaScript 的开端
  • 基于大牛直播SDK的Android屏幕扬声器采集推送RTMP技术解析
  • 浅谈OpenAIClaude LLM Tools的额外配置
  • 计算机网络中的DHCP是什么呀? 详情解答
  • 《我的后半生》:人生下半场,也有活力重启的可能
  • 中国气象局:针对山西、广西、陕西启动抗旱四级应急响应
  • 董明珠的接班人还是董明珠
  • 被电诈100万元又要被骗71万元,女子经民警近8小时劝阻幡然醒悟
  • 去年9月就提出辞任中国乒协主席,刘国梁谈辞职原因
  • 举报人不服相关部门奖励“缺斤少两”,两地分别作出再认定