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

如何区分Apache Tomcat自身与Spring应用返回的404错误?

区分Tomcat容器404与应用自身404的优雅方案

好问题!完全没必要去解析Tomcat返回的HTML字符串来做区分,那样既脆弱又不优雅,这里有几个更靠谱的方案:

  • 响应头识别法
    Tomcat默认返回的404响应会携带特定的Server头部(比如Apache Tomcat/9.0.xx或Apache-Coyote/1.1),而你的应用自身返回404时,可以统一添加自定义响应头(比如X-App-Error: true),或者修改Server头为应用标识。在RestTemplate中捕获HttpClientErrorException.NotFound后,只需检查响应头就能快速区分:

    try {
        ResponseEntity<String> response = restTemplate.getForEntity(targetUrl, String.class);
    } catch (HttpClientErrorException.NotFound e) {
        HttpHeaders headers = e.getResponseHeaders();
        // 判断是否为Tomcat容器返回的404
        boolean isTomcat404 = headers.getFirst(HttpHeaders.SERVER) != null 
            && headers.getFirst(HttpHeaders.SERVER).contains("Tomcat");
        // 或者通过自定义头判断应用级404
        boolean isApp404 = headers.containsKey("X-App-Error");
    
        if (isTomcat404) {
            // 处理服务未部署等容器级异常
            System.out.println("容器级404:目标服务未部署或路径不存在");
        } else {
            // 处理资源不存在等应用级异常
            System.out.println("应用级404:请求的资源/账户不存在");
        }
    }
    
  • 统一错误格式校验
    让你的Web服务返回的404遵循统一的JSON格式(比如{"errorCode": "RESOURCE_NOT_FOUND", "message": "指定账户不存在"}),而Tomcat默认返回的是HTML内容。捕获异常后,尝试将响应体解析为JSON:如果解析成功,就是应用自身的404;解析失败则是Tomcat容器返回的404:

    try {
        ResponseEntity<String> response = restTemplate.getForEntity(targetUrl, String.class);
    } catch (HttpClientErrorException.NotFound e) {
        String responseBody = e.getResponseBodyAsString();
        ObjectMapper objectMapper = new ObjectMapper();
        try {
            // 解析为自定义错误对象
            AppError appError = objectMapper.readValue(responseBody, AppError.class);
            // 解析成功,处理应用级404
            System.out.println("应用级404:" + appError.getMessage());
        } catch (JsonProcessingException ex) {
            // 解析失败,说明是Tomcat的HTML 404
            System.out.println("容器级404:目标服务未部署");
        }
    }
    
    // 自定义应用错误类
    static class AppError {
        private String errorCode;
        private String message;
    
        // getter和setter省略
        public String getMessage() {
            return message;
        }
    }
    
  • 自定义Tomcat错误响应(可选)
    如果你有权限配置目标Tomcat,可以修改它的错误页面配置,让容器返回的404也输出带标识的JSON格式。比如在Tomcat的web.xml中添加:

    <error-page>
        <error-code>404</error-code>
        <location>/container-404-handler</location>
    </error-page>
    

    然后写一个简单的Servlet或Spring控制器处理/container-404-handler路径,返回类似{"errorType": "CONTAINER_NOT_FOUND", "message": "服务未部署或路径无效"}的JSON响应。这样就能和应用级404用相同的解析逻辑区分,通过errorType字段判断即可。

注意:解析HTML字符串是最不推荐的方式,因为Tomcat版本更新可能会修改默认错误页面的内容,导致你的判断逻辑失效,稳定性很差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:56:02