调用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状态码
排查修复方案
按优先级依次排查即可定位问题:
- 先验证下游接口本身是否可用:使用Postman、curl等工具直接模拟请求
POST http://localhost:8082/v1/persons/getAllIds,传入对应ids请求体和两个header参数,若直接调用也返回404,说明问题出在下游服务,否则问题在调用端配置 - 排查调用端路径拼接逻辑:打印
config.getIdURL()的实际值、WebClient初始化的全局baseUrl值,拼接后和日志中打印的请求路径对比,确认和下游服务实际暴露的路径完全一致,注意避免全局baseUrl和getIdURL()的路径重复(如baseUrl已经包含/v1/persons,getIdURL()只需配置/getAllIds即可) - 检查下游服务配置:确认服务正常启动且8082端口正常监听,接口请求方法为POST、路径完全匹配,若配置了上下文路径前缀,调用时需要同步拼接前缀
- 排查鉴权逻辑:检查传入的
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
相关产品推荐
相关产品推荐

