问题咨询:Mono.defaultIfEmpty在对象非空时仍被调用如何解决
Mono.defaultIfEmpty在对象非空时仍被调用
以下是代码片段:
public Mono<ResponseEntity<Response>> validateUser(@Valid @RequestBody ValidateUserRequest request, BindingResult errors){ Mono<Response> response = null; try { response = myservice.validateUser(request); return response.map(myresponse -> { if(null!=myresponse.getError()){ return ResponseEntity.status(HttpStatus.OK).body(myresponse); }).defaultIfEmpty(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(transformer.tranformDefaultResponse()); } } catch(Exception e) { return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(transformer.tranformExceptionResponse()); } }
transformDefaultResponse会在调用**myservice.validateUser(request);**后立即执行,无论response对应的Mono是否为空。如何避免这种情况?我希望仅当response为空时才调用defaultIfEmpty中的逻辑。
问题原因
你当前的写法中,transformer.tranformDefaultResponse()是立即执行的——在调用defaultIfEmpty方法时,这个方法就已经被执行并生成了默认的Response对象,而不是等到原Mono为空时才触发。这是因为defaultIfEmpty接受的是一个具体的T类型值,而非延迟计算的逻辑。
解决方案
要实现“仅当原Mono为空时才执行默认值生成逻辑”,需要使用switchIfEmpty操作符替代defaultIfEmpty。switchIfEmpty接受一个Mono<T>作为参数,只有当原Mono完成且未发出任何元素时,才会订阅传入的Mono,从而延迟执行默认值的生成逻辑。
修正后的代码如下(同时修复原代码的语法错误):
public Mono<ResponseEntity<Response>> validateUser(@Valid @RequestBody ValidateUserRequest request, BindingResult errors) { try { Mono<Response> response = myservice.validateUser(request); return response.map(myresponse -> { // 补充完整map逻辑,根据实际业务调整else分支 if (null != myresponse.getError()) { return ResponseEntity.status(HttpStatus.OK).body(myresponse); } return ResponseEntity.status(HttpStatus.OK).body(myresponse); }).switchIfEmpty(Mono.defer(() -> Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(transformer.tranformDefaultResponse())) )); } catch (Exception e) { return Mono.just(ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(transformer.tranformExceptionResponse())); } }
关键说明:
Mono.defer()用于包装默认值生成逻辑,确保transformer.tranformDefaultResponse()只有在switchIfEmpty被触发时才会执行。switchIfEmpty仅会在原Mono为空(即myservice.validateUser(request)返回的Mono无元素发出)时,执行内部的Mono逻辑。
内容的提问来源于stack exchange,提问作者Thiagarajan Ramanathan
相关产品推荐
相关产品推荐

