You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

非HTTP内部调用如何复用@ControllerAdvice异常处理逻辑

核心问题

是否存在无需发起真实HTTP请求,直接在代码内部生成API端点被调用时返回的JSON响应的方案?
期望实现效果为:应用内部直接调用自身Controller方法,直接生成JSON格式响应字符串,不经过HTTP调用流程。
直接调用Controller方法后通过ObjectMapper序列化返回值,可以正常获取成功场景的响应结果,但如果方法执行抛出异常,异常会直接向外抛出,无法触发@ControllerAdvice中定义的异常处理器生成对应的标准错误响应。需要确认:是否可以在应用内部(不发起HTTP请求)将捕获到的异常交给@ControllerAdvice定义的异常处理器处理,生成和真实接口调用完全一致的错误响应?

当前开发场景为批量API功能:用户无需多次调用单个API,只需将多个请求载荷组成列表传入批量API即可,内部需要将每个子请求的响应结果持久化到批量API对应的数据库实体中,因此要求每个子请求返回的JSON响应和原API被真实HTTP调用时完全一致。如果单独为批量API编写异常处理逻辑,会和@ControllerAdvice中已有的异常处理代码重复,且后续新增异常类型时容易出现漏处理的问题。

原有实现的问题

原有Controller Advice代码

@ExceptionHandler(ConversionFailedException.class)
public ResponseEntity<ErrorResponse> handleConversionFailedException(final ConversionFailedException e) {
    return buildResponseEntity(HttpStatus.BAD_REQUEST, e);
}

@ExceptionHandler(value = {ActionNotFoundException.class})
public ResponseEntity<ErrorResponse> handleActionNotFoundException(ActionNotFoundException e) {
    return buildResponseEntity(HttpStatus.NOT_FOUND, e);
}


// 后续新增的异常处理逻辑
@ExceptionHandler(value = {NewRuntimeException.class})
public ResponseEntity<ErrorResponse> handleNewRuntimeException(NewRuntimeException e) {
    return buildResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR, e);
}

原有批量API异常处理代码

try {
    // 子请求调用逻辑
}catch(ConversionFailedException e){
    return buildResponseEntity(HttpStatus.BAD_REQUEST, e);
}catch(ActionNotFoundException e){
    return buildResponseEntity(HttpStatus.NOT_FOUND, e);
}
// 此处遗漏了NewRuntimeException的处理逻辑

该实现的问题为:当@ControllerAdvice新增NewRuntimeException的处理逻辑时,批量API的catch块很容易遗漏对应异常的处理,导致返回结果和真实接口调用不一致。

当前临时方案

调整后的Controller Advice

@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAllExceptions(final Exception e) {
    return ExceptionHandlerUtil.funcA(e);
}

新增ExceptionHandlerUtil工具类

private ResponseEntity<ErrorResponse> funcA(Exception e) {
    if (e instanceof ConversionFailedException) {
        return buildResponseEntity(HttpStatus.BAD_REQUEST, e);
    }
    else if (e instanceof ActionNotFoundException) {
        return buildResponseEntity(HttpStatus.NOT_FOUND, e);
    }
    // 后续新增异常类型统一在此处添加,两处调用逻辑均可复用处理能力
}

调整后的批量API异常处理代码

try {
    // 子请求调用逻辑
}catch(Exception e){
    return ExceptionHandlerUtil.funcA(e);
}

该方案虽然解决了代码重复问题,但需要将原有分散的@ExceptionHandler方法全部移除,统一走工具类做类型判断,期望找到更优雅的原生方案,直接复用@ControllerAdvice的异常处理能力。


内容的提问来源于stack exchange,提问作者Saif

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:48:26