spring-webflux - 如果 Flux 有异常,如何“窥视”?
问题描述
我将 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)。
更新
我认为“偷窥” Flux 是不可能的。对于 servlet 堆栈,我真正在 Spring 中更好的 Flux 处理:https ://jira.spring.io/browse/SPR-17440
解决方案
我建议不要使用 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
推荐阅读
- pine-script - 如何在 pine 脚本中获取关闭数据子集的 stdev
- proxy - pyppeteer-install 在代理后面
- html - html页面Bootstrap顶部的白条
- pine-script - Pine Script Strategy - 当前蜡烛图的价格与前一根蜡烛图开盘时如何触发入场?
- haskell - "(<$>)" 在 Haskell 中有什么作用?
- gitlab-ci - GitLab Runner:限制允许的命令
- spring - 如何动态选择实体的特定列?JPA/查询DSL
- pine-script - Pinescript:在图上绘制一个矩形
- c++ - 制作多文件程序时如何使用cMake?
- python - http.client 由于缺少身份验证令牌而无法登录 http 网页