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

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

基于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"));

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

http://www.xdnf.cn/news/2063.html

相关文章:

  • Vue多地址代理端口调用
  • Promethues 普罗米修斯
  • 小刚说C语言刷题——1565成绩(score)
  • 某地农产品交易中心钢网架自动化监测项目
  • 筛法求莫比乌斯函数
  • 4月25日星期五今日早报简报微语报早读
  • ZYNQ-GPIO之MIO中断
  • 【计算机视觉】CV实战项目 - 深入解析基于HOG+SVM的行人检测系统:Pedestrian Detection
  • 管家婆财贸ERP BB103.收款单按明细核算部门项目
  • Java真的不难(五十五)Stream流的进阶用法
  • 题解:CF2106G2 Baudelaire (hard version)
  • html+servlet项目中的echart图表
  • 期刊论文发表,对重复率和AI率要求多少才合格?
  • 【MySQL数据库入门到精通-07 函数-字符串函数、数值函数、日期函数和流程函数】
  • 微差压传感器、呼吸传感器
  • C++开发未来发展与就业前景:从底层基石到未来引擎
  • 无限debugger实现原理
  • 皖维 大病救助办理手续说明
  • 分层设计数据仓库的架构和设计高效数据库系统的方法
  • 大模型应用开发之LLM入门
  • AI大模型学习十二:‌尝鲜ubuntu 25.04 桌面版私有化sealos cloud + devbox+minio对象存储测试和漫长修改之路
  • apt 源切到国内时出现证书验证不过问题
  • 异步请求池控制同一时间并发
  • [官方IP] AXI Memory Init IP
  • GAEA情感坐标背后的技术原理
  • HashMap的源码解析
  • Gradle安装与配置国内镜像源指南
  • Jira、PingCode、Redmine等18款缺陷管理工具对比评测
  • 《深入理解计算机系统》阅读笔记之第七章 链接
  • 软件工程-进度管理-PERT图Gantt图