You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不修改返回类型的前提下重构基于Mono的服务方法重复逻辑

解决方案:适配EitherMono的通用服务调用处理

你的核心问题是服务层返回的EitherMono<ResourceError, ?>无法直接适配原重构方法的Mono<T>参数,同时要保留控制器方法的返回类型不变。下面是针对性的重构方案:

1. 先实现针对Void响应的专用处理方法

针对deleteUser和deleteTnC这类返回Mono<ResponseEntity<Void>>的场景,我们可以封装一个专用的可复用方法,直接适配EitherMono类型:

private Mono<ResponseEntity<Void>> handleVoidDeleteServiceCall(
    EitherMono<ResourceError, ?> serviceCall,
    String errorLogTemplate
) {
    HttpHeaders responseHeaders = createJsonHeaders();
    return serviceCall.fold(
        error -> {
            log.error(errorLogTemplate, error);
            return Mono.just(new ResponseEntity<>(null, responseHeaders, error.getStatusCode()));
        },
        unused -> Mono.just(new ResponseEntity<>(HttpStatus.NO_CONTENT))
    );
}

简化后的控制器方法

现在两个删除方法可以大幅简化,完全消除重复代码:

@Override
public Mono<ResponseEntity<Void>> deleteUser(String userId, ServerWebExchange exchange) {
    return handleVoidDeleteServiceCall(
        userService.deleteUser(userId, exchange),
        "Error in deleteUser: {}"
    );
}

@Override
public Mono<ResponseEntity<Void>> deleteTnC(String version, ServerWebExchange exchange) {
    return handleVoidDeleteServiceCall(
        tncService.deleteTnC(version, exchange),
        "Error in deleteTnC: {}"
    );
}

2. 扩展通用方法支持更多场景

如果要适配其他服务调用(比如updateDomainsVerificationToken这类需要返回具体响应体的方法),可以写一个更通用的版本,支持自定义成功状态码和响应转换逻辑:

private <T, R> Mono<ResponseEntity<R>> handleServiceCall(
    EitherMono<ResourceError, T> serviceCall,
    String errorLogTemplate,
    HttpStatus successStatus,
    Function<T, R> responseTransformer
) {
    HttpHeaders responseHeaders = createJsonHeaders();
    return serviceCall.fold(
        error -> {
            log.error(errorLogTemplate, error);
            return Mono.just(new ResponseEntity<>(null, responseHeaders, error.getStatusCode()));
        },
        response -> Mono.just(new ResponseEntity<>(
            responseTransformer.apply(response),
            responseHeaders,
            successStatus
        ))
    );
}

适配有返回体的服务调用示例

比如updateDomainsVerificationToken方法可以这样使用:

public Mono<ResponseEntity<VerificationTokenDto>> updateDomainsVerificationToken(
    String domainId, 
    VerificationTokenRequest request,
    ServerWebExchange exchange
) {
    return handleServiceCall(
        verificationService.updateToken(domainId, request, exchange),
        "Error updating verification token: {}",
        HttpStatus.OK,
        token -> new VerificationTokenDto(token.getValue(), token.getExpiryDate())
    );
}

关键说明

  • 不需要修改服务层方法的返回类型:直接基于EitherMono的fold方法封装逻辑,完全兼容原有服务接口。
  • 消除重复逻辑:把响应头创建、错误日志、响应实体构建这些重复代码统一收敛到可复用方法中。
  • 保持控制器方法返回类型不变:所有重构后的方法依然返回Mono<ResponseEntity<...>>,符合原有接口定义。

内容的提问来源于stack exchange,提问作者user1314601

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:15:21