簡體   English   中英

Spring Webflux - 拋出已檢查的自定義異常(不是 RuntimeException)的正確方法

[英]Spring Webflux - Proper way to throw checked custom exception (not RuntimeException)

請問在Spring webflux中拋出已檢查的自定義異常的正確方法是什么? 我想堅持,它是關於已檢查的自定義異常,比如 MyException.java,而不是類似 RuntimeException 的東西,它是關於拋出異常,而不是處理異常。

我嘗試了以下方法:

@Controller
@SpringBootApplication
public class QuestionHowToThrowException {

    public static void main(String[] args) {
        SpringApplication.run(QuestionHowToThrowException.class);
    }

    @PostMapping(path = "/question", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
    public Mono<ResponseEntity<QuestionResponse>> question(@RequestBody QuestionRequest questionRequest) {
        Mono<FirstStep> firstStepMono = WebClient.create().post().uri("http://firstWebService:8111/getFirstStep")
                .body(questionRequest.getThing(), String.class).retrieve().bodyToMono(FirstStep.class);
        Mono<SecondStep> secondStepMono = firstStepMono.map(oneFirstStep -> getSecondStepFromFirstStepAfterCheck(oneFirstStep));
        return secondStepMono.map(oneSecondStep -> ResponseEntity.ok(new QuestionResponse(oneSecondStep.getSecondThing())));
    }

    private SecondStep getSecondStepFromFirstStepAfterCheck(FirstStep firstStep) throws MyException {
        if (firstStep.getThingNeedsToCheckCanThrowException().equals("exception")) {
            throw new MyException("exception");
        } else {
            return new SecondStep(firstStep.getThingNeedsToCheckCanThrowException() + "good");
        }
    }

    public class QuestionRequest {
        private String thing;
        public String getThing() {
            return thing;
        }
    }

    public class QuestionResponse {
        private String response;
        public QuestionResponse(String response) {
            this.response = response;
        }
    }

    public class FirstStep {
        private String thingNeedsToCheckCanThrowException;
        public String getThingNeedsToCheckCanThrowException() {
            return thingNeedsToCheckCanThrowException;
        }
    }

    public class SecondStep {
        private String secondThing;
        public SecondStep(String secondThing) {
            this.secondThing = secondThing;
        }
        public String getSecondThing() {
            return secondThing;
        }
    }

}

這是不可能的,因為在 getSecondStepFromFirstStepAfterCheck 方法中有一個未處理的異常。

如果我拋出並傳播,私有 SecondStep getSecondStepFromFirstStepAfterCheck(FirstStep firstStep) 拋出 MyException lambda 調用方方法不滿意。

請問在 webflux 中拋出自定義異常的最干凈和正確的方法是什么?

謝謝

對於我們的應用程序,我們從 RuntimeException 擴展了我們的自定義基本異常。 然后我們有標准的異常處理,在將結果返回給最終用戶之前,它會查找我們的自定義異常以進行特殊處理。 這允許我們使用正常的 throws 機制,因為我們希望拋出的所有異常都在調用的頂層波動。

對於性能問題,webflux 和reactive 在每次調用的基礎上性能略低,尤其是對於不需要進行任何並行化的調用。 然而,一旦加載到系統上,它就會變得更加性能,主要與垃圾收集有關。 map 和 flatMap 之間差異的開銷最好可以忽略不計。

通讀您的示例代碼,您似乎正在嘗試在Mono上引入一些錯誤處理。

您可以通過擴展RuntimeException類來創建未經檢查的異常。 如果你想要一個強制處理的檢查異常,你可以簡單地擴展Exception

public class MyException extends RuntimeException {
    public MyException(String msg) {
       super(s);
    }
}

使用 Reactor 項目拋出異常的最簡潔方法實際上只是拋出它。 有一些錯誤處理功能允許您為某些錯誤情況提供不同的流程。

好消息是您有幾個選項可以為錯誤處理提供一些流量控制。

Project Reactor 在Mono對象上提供了幾個這樣的方法。

doOnError() , onErrorContinue() , onErrorReturn() , onErrorStop() , onErrorMap()

我不完全確定您要使用以下示例代碼實現什么目標。

 return Mono.error(new MyException("exception"));
        } else {
 return Mono.just(new SecondStep(firstStep.getThingNeedsToCheckCanThrowException() + "good"));

但這對於onErrorMap()來說似乎是一個很好的例子,因為看起來您正在嘗試在這里翻譯一些異常

return Mono.just(new SecondStep(firstStep.getThingNeedsToCheckCanThrowException() + "good")
   .onErrorMap(e -> "translated result");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM