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

调用API出现WebClientResponseException$NotFound:404错误该如何解决?

404错误根因分析

从错误日志可以确认是调用POST http://localhost:8082/v1/persons/getAllIds接口时服务端返回404状态码,常见原因如下:

  • 目标服务异常:8082端口的下游服务未启动、已崩溃,或端口监听异常
  • 路径不匹配:下游服务没有暴露POST /v1/persons/getAllIds接口,可能是路径拼写错误、大小写不匹配、缺少上下文前缀(如服务端配置了server.servlet.context-path/spring.webflux.base-path前缀未拼接)、接口请求方法实际为GET而非POST
  • 调用端配置错误:config.getIdURL()配置的路径错误,或WebClient初始化时设置的全局baseUrl和getIdURL()路径重复拼接,导致最终请求路径和服务端实际路径不一致
  • 鉴权伪装返回:下游服务接口需要鉴权,请求传入的X_APP_ID/X_API_KEY校验不通过,服务端为了防攻击故意返回404隐藏接口存在,而非标准的401/403状态码
排查修复方案

按优先级依次排查即可定位问题:

  1. 先验证下游接口本身是否可用:使用Postman、curl等工具直接模拟请求POST http://localhost:8082/v1/persons/getAllIds,传入对应ids请求体和两个header参数,若直接调用也返回404,说明问题出在下游服务,否则问题在调用端配置
  2. 排查调用端路径拼接逻辑:打印config.getIdURL()的实际值、WebClient初始化的全局baseUrl值,拼接后和日志中打印的请求路径对比,确认和下游服务实际暴露的路径完全一致,注意避免全局baseUrl和getIdURL()的路径重复(如baseUrl已经包含/v1/persons,getIdURL()只需配置/getAllIds即可)
  3. 检查下游服务配置:确认服务正常启动且8082端口正常监听,接口请求方法为POST、路径完全匹配,若配置了上下文路径前缀,调用时需要同步拼接前缀
  4. 排查鉴权逻辑:检查传入的X_APP_ID/X_API_KEY参数值是否和下游要求一致,确认是否是鉴权失败导致的伪装404

代码优化建议

当前代码对所有异常都会执行3次重试,4xx类客户端错误(如404)重试没有意义,建议调整重试逻辑只针对5xx服务端错误生效,避免不必要的资源浪费:

@Override
public Flux<Person> getByIds(List<String> ids) {
    log.info("getIds :  {}",ids);
    return webClient.post()
            .uri(uriBuilder -> uriBuilder.path(config.getIdURL()).build())
            .contentType(MediaType.APPLICATION_JSON)
            .body(Mono.just(ids), List.class)
            .header(geConstant.X_APP_ID_KEY, geConstant.X_APP_ID_VALUE)
            .header(geConstant.X_API_KEY_KEY, geConstant.X_API_KEY_VALUE)
            .retrieve()
            // 自定义4xx异常处理,避免无意义重试
            .onStatus(HttpStatus::is4xxClientError, response -> 
                response.bodyToMono(String.class)
                        .map(errMsg -> new RuntimeException("调用下游接口客户端错误:" + errMsg))
            )
            .bodyToFlux(Person.class)
            .log("Find ids : " + ids)
            // 仅对5xx服务端错误执行重试
            .retryWhen(Retry.backoff(3, Duration.ofSeconds(30))
                    .filter(e -> e instanceof WebClientResponseException 
                            && ((WebClientResponseException) e).getStatusCode().is5xxServerError())
            );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 19:39:00