首先,我知道还有一些其他问题本质上问同样的事情(How to Wrap Flux in a ResponseEntity,How to mix Flux and ResponseEntity in Spring Webflux controllers),但答案不知何故都结束了最后返回
Mono<ResponseEntity>
。
ResponseEntity<Mono<T>>
给定
Mono<Customer> getCustomer(Long customerId)
中的 CustomersService
方法,我的控制器代码将如下所示:
@Autowired CustomersService customersService;
public Mono<ResponseEntity<Customer> getCustomer(Long customerId) {
return customersService
.getCustomer(customerId)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.notFound().build())
}
ResponseEntity<Flux<T>>
现在,如果服务更改为
Flux<Customer> getCustomers(String name)
并且控制器返回类型为 ResponseEntity<Flux<Customer>>
,控制器代码应该是什么样子?
public Flux<ResponseEntity<Customer> getCustomers(String name) {
return customersService
.getCustomers(name)
...?
}
它将与您的第一个案例相同。
@Autowired
CustomersService customersService;
public Flux<ResponseEntity<Customer>> getCustomers(String name) {
return customersService.getCustomers(name)
.map(ResponseEntity::ok)
.defaultIfEmpty(ResponseEntity.noContent().build());
}
ℹ️ TL;DR:你必须使用
ResponseEntity<Flux<T>>
。
ResponseEntity
的 Flux
?HTTP 响应由一组标头和一个状态行组成,后跟一个潜在的流式正文。因此,您实际上是预先提供状态代码和 HTTP 标头,并在数据可用时提供数据流。
Flux
的 ResponseEntity
?如果您要使用
Flux<ResponseEntity<T>>
,从概念上讲,您将尝试通过单个请求/响应交互发送多个完整的 HTTP 响应(每个响应都有自己的标头、状态代码和数据)。 HTTP 不支持同一响应中多个独立的标头和状态行集,因此这种方法不能清楚地映射到 HTTP 的工作方式。
如果你很固执,仍然尝试这样做,Spring 无论如何都会抱怨并且不会让你这么做。你会得到这样的异常:
java.lang.IllegalArgumentException: Only a single ResponseEntity supported
at org.springframework.util.Assert.isTrue(Assert.java:116) ~[...]
...
查看文档。他们列出了所有可能性,虽然他们没有禁止
Flux<ResponseEntity<T>>
,但他们没有提及。