You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot 2.0 WebClient如何在流水线中提前处理404错误

处理WebFlux API流水线中的404错误

看起来你在Spring WebFlux的链式调用里遇到了类型不匹配的问题——当你尝试在flatMap里处理404状态码时,后续的map操作期望的是Mono类型,但你的处理逻辑可能打破了这个响应式类型链。别担心,这里有两种靠谱的解决方案:

方案一:用onStatus直接拦截404状态码

这是最简洁的方式,WebClient的onStatus方法可以专门针对特定状态码做拦截,直接抛出Spring的ResponseStatusException,框架会自动帮你转换成对应的HTTP响应:

@PostMapping(path = ["/customers/{customerId}/place"])
fun create(@PathVariable customerId: String): Mono<ResponseEntity<OrderPlacedResponse>> {
    return webClient
        .get()
        .uri("/{customerId}/cart", customerId) // 用占位符写法更规范
        .retrieve() // 用retrieve替代exchange,简化响应处理
        .onStatus(HttpStatus.NOT_FOUND::equals) { _ ->
            Mono.error(ResponseStatusException(HttpStatus.NOT_FOUND, "Customer $customerId not found"))
        }
        .bodyToMono(Cart::class.java) // 假设Cart是你接收的购物车实体类
        .flatMap { cart ->
            // 这里编写你的下单逻辑,比如生成订单、转换响应
            val orderResponse = OrderPlacedResponse(/* 填充响应参数 */)
            Mono.just(ResponseEntity.ok(orderResponse))
        }
}

为什么这个方案可行?

  • retrieve()会自动处理2xx状态码,非2xx的异常状态可以通过onStatus精准拦截
  • 捕获到404时直接用Mono.error()抛出异常,会终止整个流水线,后续操作不会执行,完美符合你“遇到404就终止并返回404”的需求

方案二:如果必须保留exchange()处理响应

如果你因为某些业务需求要使用exchange(),可以用exchangeToMono来确保整个流程的类型一致性:

@PostMapping(path = ["/customers/{customerId}/place"])
fun create(@PathVariable customerId: String): Mono<ResponseEntity<OrderPlacedResponse>> {
    return webClient
        .get()
        .uri("/{customerId}/cart", customerId)
        .exchangeToMono { response ->
            if (response.statusCode() == HttpStatus.NOT_FOUND) {
                Mono.error(ResponseStatusException(HttpStatus.NOT_FOUND, "Customer $customerId not found"))
            } else {
                response.bodyToMono(Cart::class.java)
                    .flatMap { cart ->
                        // 处理下单逻辑
                        val orderResponse = OrderPlacedResponse(/* 填充响应参数 */)
                        Mono.just(ResponseEntity.ok(orderResponse))
                    }
            }
        }
}

关键注意点

  • exchangeToMono替代exchange().flatMap(),它强制要求返回Mono类型,从根源避免了类型不匹配问题
  • 无论状态码是否为404,都要确保返回的是Mono:404时返回Mono.error(),正常情况返回处理后的Mono<ResponseEntity<...>>

你之前的编译失败大概率是因为在flatMap里没有正确用Mono包裹处理结果——比如直接抛出普通异常而非Mono.error(),或者返回了非Mono类型的对象,导致后续操作的类型链断裂。上面两种方案都严格遵循了WebFlux的响应式编程规范,应该能解决你的问题。

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

火山引擎 最新活动