我正在做一個使用反應式流的Spring webflux專案。我有一個如下的用例,我想知道如何以反應式的方式來完成它。
@RestController
public class Example {
@GetMapping("/greet")
public Mono<String> Test() {
return Mono.just("Tim"/span>)
.map(s -> s.toUpperCase())
.map(s -> s.toLowerCase())
.doOnSuccess(s -> validate(s)) //usecase是在管道的中間位置驗證。
.onErrorResume(ex -> Mono.just("Guest")
.map(s -> "Hi, " s)。
}
public void validate(String s) {
if(s.length() < 5) {throw new RuntimeException("Name is short") ;}
}
}
我知道這是個矯揉造作的例子,但我有類似的東西。我以為拋出一個錯誤會導致瀏覽器螢屏上的例外,當端點被擊中時。但令我驚訝的是,它進入了onErrorResume(),我得到了Hi, Guest作為回應。我想當throw被用來在反應式管道組裝之前拋出一個例外時,它將不會使用onErrorResume()。我在這里錯過了什么?
同樣來到問題#2,如果我使用Mono.error(new RuntimeException("Name is short"))而不是throw new RuntimeException("Name is short"),我怎樣才能實作這個目標?誰能回答我的兩個問題。請提出改進代碼的建議,謝謝。
uj5u.com熱心網友回復:
我認為當throw被用來在反應式管道組裝之前拋出一個例外時 管道組裝之前,它將不會使用onErrorResume()
。
Mono::doOnSuccess在執行時間觸發,當Mono成功完成(管道已經組裝好)。
注意,在doOnNext或map這樣的中間操作中,你可以自由地拋出例外,因為Reactor可以將它們轉化為適當的錯誤信號,因為此時Mono已經在進行中。
如果我使用Mono.error(new RuntimeException("Name is short"))而不是拋出new RuntimeException("Name is short")?
你可以用doOnSuccess和map取代handle運算子:
return Mono.just("Tim" )
.handle((name, sink) -> {
if(name.length() < 5){
sink.error(new RuntimeException("Name is short") )。
} else {
sink.next(name.toLowerCase())。
}
})
uj5u.com熱心網友回復:
對于#1的問題,你可以在onErrorResume
.onErrorResume(e -> !(e instanceof RuntimeException), ex -> Mono.just("Guest" )
這樣你就可以對哪個錯誤進行過濾,你就可以回傳一個預定義的結果。
對于問題#2,你可以用flatMap代替doOnSuccess,它是一個消費者,并為validate方法回傳Mono:
public Mono<String> Test(){
return Mono.just("Tim"/span>)
.map(s -> s.toUpperCase())
.map(s -> s.toLowerCase())
.flatMap(s -> validate(s))
.onErrorResume(e -> !(e instanceof RuntimeException), ex -> Mono.just("Guest" )
.map(s -> "Hi, " s)。
}
public Mono<String> validate(String s) {
return (s.length() < 5) ?
Mono.error(() -> new RuntimeException("Name is short")) 。
Mono.just(s)。
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/324192.html
標籤:
