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

Spring Boot从外部URL下载文件报No converter found错误如何解决

问题解决与优化方案

报错根因

你直接把Apache HttpClient返回的EofSensorInputStream输入流作为响应体返回,Spring MVC默认没有适配该输入流实现类的消息转换器,无法完成序列化输出,因此抛出该异常。除此之外原有代码还存在资源未主动释放、响应头配置缺失、错误场景处理不规范的问题。

优化后的实现代码

import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
import java.io.InputStream;

public ResponseEntity<InputStreamResource> downloadAsset() throws IOException {
    final String username = "abd";
    final String password = "rewf";
    String url = "https://www.clickdimensions.com/links/TestPDFfile.pdf";
    String fileName = "TestPDFfile.pdf";

    // 配置Basic认证,无需手动编码Base64
    CredentialsProvider credsProvider = new BasicCredentialsProvider();
    credsProvider.setCredentials(AuthScope.ANY,
            new UsernamePasswordCredentials(username, password));

    // try-with-resources自动释放HttpClient资源
    try (CloseableHttpClient httpClient = HttpClients.custom()
            .setDefaultCredentialsProvider(credsProvider)
            .build()) {
        HttpGet request = new HttpGet(url);
        HttpResponse response = httpClient.execute(request);

        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode == HttpStatus.OK.value()) {
            InputStream inputStream = response.getEntity().getContent();
            // 封装输入流为Spring可识别的Resource类型
            InputStreamResource resource = new InputStreamResource(inputStream);

            // 配置下载响应头
            HttpHeaders headers = new HttpHeaders();
            headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + fileName);
            headers.add(HttpHeaders.CONTENT_TYPE, "application/pdf");

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentLength(response.getEntity().getContentLength())
                    .body(resource);
        }
        // 非200响应返回对应错误状态码
        return ResponseEntity.status(statusCode).build();
    }
}

优化点说明

  • 用Spring内置的InputStreamResource封装外部返回的输入流,Spring自带对应消息转换器,直接解决序列化报错问题
  • 内置Basic认证配置,无需手动处理Base64编码,逻辑更规范
  • 使用try-with-resources语法自动释放HTTP连接相关资源,避免资源泄漏
  • 补充了下载必备的响应头配置,支持浏览器直接触发文件下载,也可根据实际业务调整Content-Type值
  • 错误场景直接返回对应HTTP状态码,符合接口设计语义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 23:15:00