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

Spring WebClient下载文件如何不使用CustomException记录2xx成功状态日志

实现方案

你完全不需要自定义CustomException来实现这个需求,以下是两种常用的实现方式:

方案1:使用doOnComplete钩子(推荐,符合下载成功语义)

直接在响应体流正常处理完成后触发日志打印,只有文件完整写入本地后才会输出日志,不需要修改原有请求处理逻辑:

private void dnloadFileAPI(String theId, String destination) {
    log.info("Downloading file.. " + theId);
    Flux<DataBuffer> dataBuffer = webClient
            .get()
            .uri("/some/fancy/" + theId + "/api")
            .retrieve()
            .bodyToFlux(DataBuffer.class)
            // 流无异常处理完成时触发,对应文件写入成功
            .doOnComplete(() -> log.info("{}", theId + " - File downloaded successfully"));
    DataBufferUtils.write(dataBuffer, Paths.get(destination), StandardOpenOption.CREATE).share().block();
}

方案2:使用exchangeToFlux拿到完整响应

如果需要在收到2xx状态码的第一时间就打印日志(不需要等文件写完),可以用exchangeToFlux替代retrieve,直接获取响应对象判断状态:

private void dnloadFileAPI(String theId, String destination) {
    log.info("Downloading file.. " + theId);
    Flux<DataBuffer> dataBuffer = webClient
            .get()
            .uri("/some/fancy/" + theId + "/api")
            .exchangeToFlux(response -> {
                if (response.statusCode().is2xxSuccessful()) {
                    // 收到2xx响应立刻打印日志
                    log.info("{}", theId + " - File downloaded successfully");
                    return response.bodyToFlux(DataBuffer.class);
                }
                // 非2xx状态抛出异常,和原有retrieve逻辑保持一致
                return response.createException().flatMapMany(Mono::error);
            });
    DataBufferUtils.write(dataBuffer, Paths.get(destination), StandardOpenOption.CREATE).share().block();
}

两种方案都不需要自定义异常类,你可以根据日志的触发时机要求选择对应方案即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 07:18:02