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

Java微服务系统中错误检查位置:Service还是Controller?

错误检查的最佳实践:Service vs Controller

这是个很常见的职责划分问题,答案其实是两者都要参与,但各有侧重,核心就是遵循单一职责原则,让每层只做自己该做的事。

1. Service层:负责业务层面的错误检查与异常转化

Service的核心职责之一就是封装外部调用和业务逻辑,所以这里必须先处理外部HTTP调用的错误:

  • 发起外部调用后,立刻检查返回结果(比如非2xx状态码、错误格式的响应体),把这些底层的技术错误转化为业务层面的异常或明确的错误对象——比如把HTTP 404转化为ResourceNotFoundException,把5xx系列状态码转化为ExternalServiceUnavailableException。
  • 这么做的好处很明显:Controller不需要关心外部服务的具体细节(比如对方返回的状态码含义、接口格式),只需要处理业务相关的异常类型;同时,后续如果替换外部服务或者调整调用逻辑,错误处理的代码只需要在Service层修改,不用动Controller。
  • 举个伪代码示例(Java风格):
    public ExternalData getExternalInfo(String requestParam) {
        ResponseEntity<ExternalData> response = restTemplate.getForEntity(EXTERNAL_API_URL, ExternalData.class);
        
        if (!response.getStatusCode().is2xxSuccessful()) {
            switch(response.getStatusCode()) {
                case NOT_FOUND:
                    throw new ResourceNotFoundException("请求的外部资源不存在");
                case SERVICE_UNAVAILABLE:
                case INTERNAL_SERVER_ERROR:
                    throw new ExternalServiceUnavailableException("外部服务暂时无法访问,请稍后重试");
                default:
                    throw new BusinessException("外部调用失败,状态码:" + response.getStatusCodeValue());
            }
        }
        
        return response.getBody();
    }
    

2. Controller层:负责将错误转化为用户友好的网页响应

Controller的职责是处理请求、协调Service、返回面向用户的视图(网页),所以它的错误处理侧重在呈现:

  • 捕获Service层抛出的各类业务异常,以及未被Service覆盖的意外异常;
  • 根据不同的异常类型,返回对应的错误网页——比如给用户显示“资源不存在”的404页面、“服务暂时不可用”的提示页,或者通用的系统错误页;
  • 也可以用全局异常处理器(比如Spring的@ControllerAdvice)来统一处理,避免在每个Controller方法里重复写捕获逻辑。
  • 伪代码示例:
    @GetMapping("/show-info")
    public String showInfoPage(Model model, @RequestParam String param) {
        try {
            ExternalData data = externalService.getExternalInfo(param);
            model.addAttribute("info", data);
            return "info-detail-page";
        } catch (ResourceNotFoundException e) {
            model.addAttribute("errorMessage", e.getMessage());
            return "404-error-page";
        } catch (ExternalServiceUnavailableException e) {
            model.addAttribute("errorMessage", e.getMessage());
            return "service-unavailable-page";
        } catch (Exception e) {
            model.addAttribute("errorMessage", "系统出现未知错误,请稍后再试");
            return "general-error-page";
        }
    }
    

总结

简单来说:Service管业务逻辑层面的错误识别与转化,把底层技术错误包装成上层能理解的业务异常;Controller管面向用户的错误响应呈现,把异常转化为用户能看懂的网页。这样分工既保证了代码的内聚性,也让错误处理逻辑清晰易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:21:13