如果Flux有异常,该如何“窥视”?

时间:2018-10-26 16:42:23

标签: spring-webflux project-reactor

我将Spring Webflux与Tomcat Servlet容器( spring-boot-starter-web + spring-boot-starter-webflux )结合使用,我希望获得以下内容结果:

如果立即失败,我想发送给客户端响应代码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);
 }

PS。有趣的是,v1v2与netty一起使用(仅 spring-boot-starter-webflux )。

更新

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

1 个答案:

答案 0 :(得分:0)

我建议不要使用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。 您应该使用HTTP207。https://httpstatuses.com/207