我将Spring Webflux与Tomcat Servlet容器( spring-boot-starter-web + spring-boot-starter-webflux )结合使用,我希望获得以下内容结果:
如果立即失败,我想发送给客户端响应代码400
否则,我想发送响应代码200并传输通量
我尝试了不同的解决方案,但没人能解决。如果发生失败的情况,v1
和v2
没有发送预期的响应代码,则在失败的情况下,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。有趣的是,v1
和v2
与netty一起使用(仅 spring-boot-starter-webflux )。
我认为“窥视”通量是不可能的。对于Servlet堆栈,我真正在Spring中对Flux的处理更好:https://jira.spring.io/browse/SPR-17440
答案 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