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

Spring WebClient路由4xx/5xx错误响应及HTTP状态码问题

解决ProxyApp转发BusinessApp错误状态码被重置为200的问题

问题根源

你的代码里有两处直接导致错误状态码被重置的问题:

  • .onStatus(HttpStatus::isError, clientResponse -> Mono.empty()):这行代码把BusinessApp返回的错误状态码响应直接转换成空的Mono,相当于把错误“吞掉”,WebClient不会抛出异常,会继续走正常流程
  • 方法上的@ResponseStatus(HttpStatus.OK):硬编码了响应状态为200,不管实际调用BusinessApp的结果是什么,最终都会返回200

解决方案

要实现完整转发响应体和状态码,需要做以下调整:

  • 移除错误状态码的空Mono处理,改为直接捕获并处理所有状态的响应
  • 把方法返回类型从String改为ResponseEntity<String>,支持动态设置HTTP状态码
  • 用exchangeToMono替代retrieve(),直接访问完整的客户端响应信息

修改后的代码

@Operation(summary = "Some desc")
@PostMapping(value = "/", consumes = {MediaType.APPLICATION_JSON_VALUE}, produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiResponse(responseCode = "200", content = {
        @Content(mediaType = "application/json", schema = @Schema(implementation = User.class))
})
// 移除硬编码的@ResponseStatus,让ResponseEntity动态决定状态码
public ResponseEntity<String> someMethod() {

    // skipped

    return webClient.post()
            .uri(url)
            .contentType(MediaType.APPLICATION_JSON)
            .bodyValue(request)
            .exchangeToMono(clientResponse -> {
                // 统一处理所有状态码:正常响应和错误响应
                return clientResponse.bodyToMono(String.class)
                        .map(body -> ResponseEntity.status(clientResponse.statusCode()).body(body));
            })
            .onErrorMap(WebClientRequestException.class, ex -> new RestApiUnavailableException(ex,"some msg"))
            .block();
}

代码说明

  • exchangeToMono:替代retrieve()后可以直接获取完整的ClientResponse,包括状态码和响应体,不管是成功还是错误状态都能处理
  • 动态状态码:通过clientResponse.statusCode()获取BusinessApp返回的原始状态码,再将响应体封装到ResponseEntity中返回
  • 移除错误吞逻辑:不再忽略错误状态码,确保所有响应状态都能原样转发

补充:Swagger注解优化

如果需要让Swagger生成的客户端包含错误状态码的定义,可以补充对应的@ApiResponse:

@ApiResponse(responseCode = "400", content = {
        @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))
})
@ApiResponse(responseCode = "500", content = {
        @Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 02:25:04