【问题标题】:How to "peep" if Flux has exception?如果 Flux 有异常,如何“窥视”?
【发布时间】:2018-10-26 16:42:22
【问题描述】:

我将 Spring Webflux 与 Tomcat servlet 容器(spring-boot-starter-web + spring-boot-starter-webflux)一起使用,我想获得以下信息结果:

如果flux of立即失败,我想发送给客户端响应码400

否则,我想发送响应代码 200 并流式传输通量

我尝试了不同的解决方案,但没有一个有效。 v1v2 不发送预期的响应代码如果失败场景,v3 不流输出是快乐的场景。

我想“窥视”failFlux 上的异常并在发送响应代码 200 之前触发异常

@RequestMapping(produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public class X {
 Flux<String> happyFlux = Flux.generate(s -> s.next("x"));  
 Flux<String> failFlux = Flux.error(new ResponseStatusException(BAD_REQUEST));

 //ok: flux is streamed

 @RequestMapping("/v1/happy")
 Flux<String> v1Happy() {
    return happyFlux;
 }

 //nok: http status code is 200

 @RequestMapping("/v1/fail")
 Flux<String> v1Fail() {
    return failFlux;
 }

 //ok: flux is streamed

 @RequestMapping("/v2/happy")
 Mono<ResponseEntity<Flux<String>>> v2Happy() {
    return Mono.just(ResponseEntity.ok().body(happyFlux));
 }

 //nok: http status code is 200

 @RequestMapping("/v2/fail")
 Mono<ResponseEntity<Flux<String>>> v2Fail() {
    return Mono.just(ResponseEntity.ok().body(failFlux));
 }

 //nok: flux is not streamed but collected on server side

 @RequestMapping("/v3/happy")
 Mono<ResponseEntity<List<String>>> v3Happy() {
    return happyFlux.collectList().map(ResponseEntity::ok);
 }

 //ok: http status code is 400

 @RequestMapping("/v3/fail")
 Mono<ResponseEntity<List<String>>> v3Fail() {
    return failFlux.collectList().map(ResponseEntity::ok);
 }

附言。有趣的是,v1v2 与 netty 一起工作(仅 spring-boot-starter-webflux)。

更新

我认为“偷窥”Flux 是不可能的。对于 servlet 堆栈,我真正需要的是在 Spring 中更好的 Flux 处理:https://jira.spring.io/browse/SPR-17440

【问题讨论】:

  • 您能详细说明一下吗?什么时候抛出异常?那是什么例外?您能否在控制器返回的通量后添加log() 运算符后提供日志?您能否展示一个 HTTP 请求和响应的示例(带有标头和正文)?
  • @BrianClozel,我完全重写了我的问题,我希望现在更清楚

标签: spring-webflux project-reactor


【解决方案1】:

我建议不要使用 collectList() ,因为这会破坏生成 Stream 的全部目的。 我相信如果出现异常消息,您应该得到 500。

例如,检查下面的代码。

public Mono<ServerResponse> listPeople(ServerRequest request) {
    int error = 10/0;
    Flux<Person> peopleFlux = this.repository.allPeople();
    peopleFlux = withDelay(peopleFlux);

    return ServerResponse.ok().contentType(MediaType.TEXT_EVENT_STREAM).body(peopleFlux, Person.class);


}

声明

int error = 10/0;

导致 500 异常,在客户端我得到 500。如果我注释掉错误语句,那么我得到 200。 所以,如果你没有得到 500,请分享你的代码。请注意,如果错误发生在服务器开始返回流中的单个事件之后,那么它不会是 500。 你应该使用 HTTP 207。https://httpstatuses.com/207

【讨论】:

  • 请再看看我的问题 - 我完全重写了它。我完全同意 collectList 是错误的方式 - 我只是展示我的实验
  • @michaldo 我同意行为必须是一致的。我会更倾向于成功代码,因为我们永远不知道 Flux 中的哪个事件可能会出错。
猜你喜欢
  • 1970-01-01
  • 2016-03-29
  • 2021-01-20
  • 2021-03-12
  • 1970-01-01
  • 1970-01-01
  • 2014-02-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多