温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何捕获java API接口异常

发布时间:2026-09-11 20:18:41 来源:亿速云 阅读:86 作者:小樊 栏目:编程语言

在 Java 中,“捕获 API 接口异常”通常可以从代码层(try-catch)框架层(全局异常处理)网关/代理层三个维度来做。下面按常见场景给你一个系统性的说明。


一、基础方式:try-catch(接口实现内部)

适用于具体方法级别的异常捕获。

@RestController
@RequestMapping("/api")
public class UserController {

    @GetMapping("/user/{id}")
    public User getUser(@PathVariable Long id) {
        try {
            return userService.findById(id);
        } catch (UserNotFoundException e) {
            throw new ResponseStatusException(
                HttpStatus.NOT_FOUND, "用户不存在", e);
        } catch (Exception e) {
            throw new ResponseStatusException(
                HttpStatus.INTERNAL_SERVER_ERROR, "系统异常", e);
        }
    }
}

✅ 优点:直观
❌ 缺点:重复代码多,不适合大型项目


二、Spring 推荐方式:全局异常捕获(@ControllerAdvice)

最适合 RESTful API

1️⃣ 定义统一返回结构

public class ApiResult<T> {
    private int code;
    private String message;
    private T data;

    // getter/setter/构造方法
}

2️⃣ 全局异常处理器

@RestControllerAdvice
public class GlobalExceptionHandler {

    // 捕获自定义业务异常
    @ExceptionHandler(BusinessException.class)
    public ApiResult<Void> handleBusiness(BusinessException e) {
        return new ApiResult<>(e.getCode(), e.getMessage(), null);
    }

    // 捕获参数校验异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResult<Void> handleValid(MethodArgumentNotValidException e) {
        String msg = e.getBindingResult()
                      .getFieldError()
                      .getDefaultMessage();
        return new ApiResult<>(400, msg, null);
    }

    // 捕获所有未处理异常
    @ExceptionHandler(Exception.class)
    public ApiResult<Void> handleAll(Exception e) {
        e.printStackTrace();
        return new ApiResult<>(500, "系统异常", null);
    }
}

✅ 优点:

  • 集中管理
  • 接口返回统一
  • 易维护

三、接口层异常:Filter / Interceptor

如果你希望在 Controller 之前或之后统一捕获:

Filter(最底层,最通用)

@Component
public class ApiExceptionFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req,
                         ServletResponse res,
                         FilterChain chain) throws IOException {
        try {
            chain.doFilter(req, res);
        } catch (Exception e) {
            // 统一写响应
        }
    }
}

✅ 适合:

  • 跨所有接口
  • 统一日志
  • 统一错误响应格式

四、外部 API 调用异常(调用第三方接口)

如果你是调用别人 API

try {
    restTemplate.getForObject(url, String.class);
} catch (HttpClientErrorException e) {
    // 4xx
} catch (HttpServerErrorException e) {
    // 5xx
} catch (ResourceAccessException e) {
    // 超时 / 网络异常
}

或使用 WebClient(响应式):

webClient.get()
    .uri(url)
    .retrieve()
    .onStatus(HttpStatus::isError,
        resp -> Mono.error(new ApiException("调用失败")))
    .bodyToMono(String.class)
    .block();

五、异步接口异常(CompletableFuture)

CompletableFuture.supplyAsync(() -> {
    throw new RuntimeException("error");
}).exceptionally(ex -> {
    log.error("异步异常", ex);
    return null;
});

六、最佳实践总结

推荐组合方案

  • Controller 内部:少写 try-catch
  • 全局异常:@RestControllerAdvice
  • 外部调用:明确捕获 HTTP 异常
  • 日志统一:AOP / Filter

❌ 避免:

  • 捕获 Throwable
  • 吞掉异常不处理
  • 每个接口都写 try-catch

如果你能说明:

  • 用的是 Spring Boot / Spring Cloud / 原生 Servlet
  • 提供 API 还是调用 API
  • 是否使用 WebFlux / 微服务网关

我可以给你更精准的示例代码。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI