阿里云云服务器 网站配置,自己搭建环境建设网站,今天的新闻联播内容,软文是指什么1 缘起
最近在学习WebFlux#xff0c; 处理异常时遇到些问题#xff0c;比如#xff0c;Java直接抛出的异常无法直接被onErrorReturn和onErrorResume捕获#xff0c; 但是#xff0c;在map或者flatMap等方法之后的异常又可以直接被捕获#xff0c; 于是#xff0c;进行…1 缘起
最近在学习WebFlux 处理异常时遇到些问题比如Java直接抛出的异常无法直接被onErrorReturn和onErrorResume捕获 但是在map或者flatMap等方法之后的异常又可以直接被捕获 于是进行了测试发现onErrorReturn和onErrorResume可以捕获的异常是Throwable类型或者Mono或Flux包装的类型。 当我们在使用WebFlux中的onErrorReturn和onErrorResume捕获异常时有两种方式 1当原生Java运行时异常抛出时需要使用Mono或Flux包装Mono.error或FluxError 2在map或者flatMap等其他原生方法中抛出的异常可以直接被捕获无需包装。 特分享如下帮助读者轻松应对知识交流与考核。
2 异常处理
异常处理是软件开发中非常重要的一环 在业务系统中我们需要捕获异常给出合适的描述信息让调用者清晰这是哪一个环节的异常。 在计算相关的业务中通常对计算结果有更多的要求比如程序内部出现异常后不能影响计算结果的输出需要有一个保底的计算结果比如在广告推荐系统中的广告出价即使程序内部出现异常仍要返回最终的广告出价保证流程可以正常继续往下走。 当然不同的业务系统有不同的需求有的需要直接将异常暴露出去有的需要记录但是给出保底的结果但是都要都要对异常进行处理。
2.1 WebFlux异常处理
WebFlux中的异常处理与SpringMVC中的异常处理存在不同的地方 相同都可使用全局异常拦截 不同WebFlux可以使用自定义的异常处理方法如onErrorReturn和onErrorResume。 在WebFlux中onErrorReturn和onErrorResume可以处理的异常是经过Mono或Flux包装的。 可以这样理解Java直接抛出的运行时异常onErrorReturn和onErrorResume无法直接捕获需要通过Mono.error或者Flux.error包装才能被正常捕获当然如果启用了全局异常捕获则无需包装。 下面看一下onErrorReturn和onErrorResume的源码
onErrorReturn onErrorReusme 由源码可知onErrorReturn中调用了onErrorResume不同的是入参和返回值onErrorReturn入参是固定值onErrorResume入参是函数可以自定义处理逻辑。onErrorResume的参数为Functions? super Throwable, ? extends Mono由这个泛型参数可知onErrorResume只能处理Throwable类型和Mono及其子类的类型数据所以无法直接捕获Java原生运行时异常。Java可抛出异常是Error和Exception的父类因此任何运行时异常都不能被onErrorResume或者onErrorReturn捕获除非使用Mono.error或者Flux.error包装起来才能正常捕获。 Java异常关系https://blog.csdn.net/Xin_101/article/details/110210485
2.2 样例
前提条件未开启全局异常捕获
接口
GetMapping(/mathematics/operation/flow/mono)ApiOperation(连续流测试mono)public MonoResponseInteger mathematicsOperationFlowUnderMono(RequestParam Integer var1, RequestParam Integer var2) {return mathematicsOperationService.divideMono(var1, var2).onErrorReturn(10).map(addResult - {logger.info(Add result:{}, addResult);return Response.success(addResult);}).onErrorResume(ex - {logger.info(Error resume:, ex);return Mono.just(Response.fail(-100));});}2.2.1 原生运行时异常
Java原生异常即Throwable子类的错误和异常Error和Exception。 以运行时异常为例当程序出现异常时接口返回的结果是WebFlux的信息而不是开发者自定义的响应模板。
异常处理 Overridepublic MonoInteger divideMono(Integer var1, Integer var2) {try{return Mono.just(var1 / var2);} catch(Exception ex) {throw new RuntimeException(自定义运行时异常);}}返回的信息如下
2.2.2 Mono包装异常
onErrorReturn和onErrorResume可以处理Mono或Flux包装的异常 包装如下
异常处理 Overridepublic MonoInteger divideMono(Integer var1, Integer var2) {try{return Mono.just(var1 / var2);} catch(Exception ex) {return Mono.error(ex);}}包装后的异常可以被哦那Error Return捕获接口中在onErrorReturn中使用了固定数值10因此返回的结果是10结果如下
2.2.3 原生Mono异常
由上面可知WebFlux可以捕获处理Mono或Flux包装的异常信息 因此当我们使用map或者flatMap处理数据时可以直接使用onErrorReturn和onErrorResume捕获异常map和flatMap中产生的异常会被直接捕获无需进行包装。 为了测试我们在map中添加了1/0运行时会抛出异常然后在onErrorResume中捕获异常并返回-100。 GetMapping(/mathematics/operation/flow/mono)ApiOperation(连续流测试mono)public MonoResponseInteger mathematicsOperationFlowUnderMono(RequestParam Integer var1, RequestParam Integer var2) {return mathematicsOperationService.divideMono(var1, var2).onErrorReturn(10).onErrorResume(ex - {logger.info(Error resume -1:, ex);return Mono.just(-1);}).map(addResult - {logger.info(Add result:{}, addResult);int a 1/0;return Response.success(addResult);}).onErrorResume(ex - {logger.info(Error resume:, ex);return Mono.just(Response.fail(-100));});}当出现异常时onErrorResume会直接捕获并返回自定义的数据如上面的-100 结果如下图所示。 3 小结
1WebFlux处理异常可以使用onErrorReturn和onErrorResume 2onErrorReturn和onErrorResume可以处理的异常是Throwable类型以及Mono或者Flux及其子类包装的异常 3使用Mono.error和Flux.error包装异常或者在mapflatMap之后处理异常。