Spring Webflux:如何将Mono中的UUID验证异常映射为其他异常
问题原因分析
你现在的代码有个核心问题:UUID.fromString("123")是同步执行的——在调用Mono.just()的时候,这个方法就已经执行了,异常直接在主线程抛出,根本没进入Reactive流的上下文。所以后面的doOnError、onErrorMap这些错误处理操作符完全没机会捕获这个异常。
正确实现方式
要让异常进入Reactive流,必须把可能抛出异常的代码延迟执行,直到Mono被订阅时才触发。可以用Mono.fromSupplier或者Mono.defer来实现:
方式1:使用Mono.fromSupplier
public class Main { public static void main(String[] args) { Mono.fromSupplier(() -> UUID.fromString("123")) .onErrorMap(IllegalArgumentException.class, e -> new AssertionError("无效的UUID格式", e)) .subscribe( uuid -> System.out.println("有效UUID: " + uuid), error -> System.err.println("错误: " + error.getMessage()) ); } }
方式2:使用Mono.defer
public class Main { public static void main(String[] args) { Mono.defer(() -> Mono.just(UUID.fromString("123"))) .onErrorMap(IllegalArgumentException.class, e -> new AssertionError("无效的UUID格式", e)) .subscribe(); } }
原理说明
Mono.fromSupplier:接收一个Supplier接口实现,只有当Mono被订阅时,才会调用Supplier.get()方法执行UUID解析逻辑,此时抛出的异常会被Reactive框架捕获,进入流的错误处理链路。Mono.defer:延迟创建Mono实例,同样是在订阅时才执行内部的Mono.just(UUID.fromString(...)),让异常进入流中。
Spring Webflux端点中的应用示例
在实际的Webflux接口中,可以这样写:
@RestController public class UuidController { @GetMapping("/uuid/{uuidStr}") public Mono<UUID> validateAndReturnUuid(@PathVariable String uuidStr) { return Mono.fromSupplier(() -> UUID.fromString(uuidStr)) .onErrorMap(IllegalArgumentException.class, e -> new AssertionError("传入的字符串不是合法UUID: " + uuidStr, e)); } }
内容的提问来源于stack exchange,提问作者Giustiniano
相关产品推荐
相关产品推荐

