java自定义异常可通过添加字段和构造方法携带请求参数,推荐用map存储并提供多参构造器,spring mvc中可在controller内捕获参数后传入异常实例。

Java 自定义异常可以轻松携带请求参数,关键是在异常类中添加字段并提供构造方法接收这些参数,再在抛出时传入当前上下文数据(如 Spring MVC 中的请求参数)。
定义带参数的自定义异常类
在异常类中声明字段保存请求参数,并提供含参构造方法。推荐同时保留无参和标准 Throwable 构造方法以兼容性更好:
- 用 String 或 Map
存储参数(适合简单场景) - 用 Object[] 或封装类(如
RequestContext)支持更复杂结构 - 重写
toString()或添加getParams()方便日志或调试输出
示例:
public class BusinessException extends RuntimeException {
private final Map<string object> requestParams;
public BusinessException(String message, Map<string object> params) {
super(message);
this.requestParams = new HashMap(params);
}
public BusinessException(String message, Map<string object> params, Throwable cause) {
super(message, cause);
this.requestParams = new HashMap(params);
}
public Map<string object> getRequestParams() {
return Collections.unmodifiableMap(requestParams);
}
}
</string></string></string></string>
在 Controller 中捕获并注入请求参数
Spring MVC 下,可在方法参数中直接获取请求参数(如 @RequestParam、@RequestBody、@PathVariable),然后在抛异常时一并传入:
- 手动收集参数到 Map:适用于 GET 请求或简单表单
- 直接传
@RequestBody对象:适合 POST/PUT 的 JSON 请求 - 结合
BindingResult可同时携带校验错误信息
示例(GET 请求):
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
@GetMapping("/user")
public String getUser(@RequestParam Long id, @RequestParam String name) {
if (id == null || id params = Map.of("id", id, "name", name);
throw new BusinessException("用户ID非法", params);
}
return userService.findById(id);
}
统一异常处理中记录参数
使用 @ControllerAdvice + @ExceptionHandler 捕获自定义异常,在响应前打印或落库请求参数:
- 通过
instanceof判断是否为带参异常,安全调用getRequestParams() - 日志中格式化输出参数(注意脱敏敏感字段,如 password、idCard)
- 可将参数写入 MDC,使整条链路日志自动带上 traceId 和请求参数
示例:
@ExceptionHandler(BusinessException.class)
public ResponseEntity<map object>> handleBusinessException(BusinessException e) {
log.warn("业务异常:{},请求参数:{}", e.getMessage(), e.getRequestParams());
Map<string object> response = Map.of(
"code", 400,
"message", e.getMessage(),
"params", e.getRequestParams()
);
return ResponseEntity.badRequest().body(response);
}
</string></map>
进阶:自动绑定请求上下文(非侵入式)
若不想每个接口都手动传参,可通过 AOP 或拦截器在异常抛出前自动注入当前请求快照:
- 用
RequestContextHolder获取当前HttpServletRequest - 提取 query string、body 内容(需缓存 request input stream)、header 等
- 包装异常时自动附加,但要注意线程安全和性能开销
注意:RequestBody 只能读取一次,若已由 Spring 解析过(如 @RequestBody),需借助 ContentCachingRequestWrapper 提前缓存。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










