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

使用DataBufferUtils写入响应时遇MessageBodyReader缺失问题求助

解决"Unable to find a MessageBodyReader"错误:二进制文件下载的正确姿势

问题根源

你的代码核心问题是混用了JAX-RS(Resteasy)客户端和Spring WebFlux的DataBufferUtils,且Resteasy的Rx调用逻辑错误地将二进制zip响应关联到了SSE(Server-Sent Events)处理流程:

  • 调用rx(FluxRxInvoker.class).get(DataBuffer.class)时,Resteasy的FluxRxInvoker默认会将请求关联到SSE事件流的处理,导致它尝试将application/zip类型的响应解析为SseEventInputImpl类型,但不存在对应的MessageBodyReader,因此抛出错误。
  • 你后续尝试的自定义MessageBodyReader方向完全错误:JAXB是用来解析XML的,而你下载的是二进制zip文件,用XML解析二进制流必然会出现"Content is not allowed in prolog"的XML解析错误。

正确解决方案

方案1:使用Spring WebFlux的WebClient(推荐)

既然你已经引入了spring-boot-starter-webflux,直接用WebClient来处理HTTP请求,它和DataBufferUtils天然适配,无需依赖Resteasy的JAX-RS客户端:

import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.web.reactive.function.client.WebClient;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class Downloader {
    public static void main(String[] args) {
        WebClient webClient = WebClient.create();
        
        Path path = Paths.get("sample.zip");
        
        webClient.get()
                .uri("https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-zip-file.zip")
                .retrieve()
                .bodyToFlux(org.springframework.core.io.buffer.DataBuffer.class)
                .doOnNext(dataBuffer -> DataBufferUtils.release(dataBuffer))
                .as(dataBufferFlux -> DataBufferUtils.write(dataBufferFlux, path, StandardOpenOption.CREATE))
                .block();
    }
}

方案2:如果坚持使用Resteasy客户端

需要正确获取二进制输入流,再转换为Spring DataBuffer供DataBufferUtils写入,避免触发SSE处理逻辑:

import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import reactor.core.publisher.Flux;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;

public class Downloader {
    public static void main(String[] args) {
        ResteasyClient client = new ResteasyClientBuilder().build();
        
        try (InputStream inputStream = client.target("https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-zip-file.zip")
                .request()
                .get(InputStream.class)) {
            
            DefaultDataBufferFactory bufferFactory = new DefaultDataBufferFactory();
            Flux<DataBuffer> dataBufferFlux = Flux.generate(sink -> {
                byte[] buffer = new byte[4096];
                int bytesRead;
                try {
                    if ((bytesRead = inputStream.read(buffer)) != -1) {
                        sink.next(bufferFactory.wrap(buffer, 0, bytesRead));
                    } else {
                        sink.complete();
                    }
                } catch (Exception e) {
                    sink.error(e);
                }
            });
            
            Path path = Paths.get("sample.zip");
            org.springframework.core.io.buffer.DataBufferUtils.write(dataBufferFlux, path, StandardOpenOption.CREATE).block();
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            client.close();
        }
    }
}

额外注意事项

  • 依赖清理:如果使用方案1,可以移除Resteasy相关的依赖(jboss-jaxrs-api_2.1_spec、resteasy-reactor、resteasy-jackson2-provider),避免依赖冲突。
  • 文件命名:你之前将zip文件保存为file.txt,建议改为sample.zip,避免文件格式识别问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:35:30