繁体   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