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

Spring RestController返回ByteArrayResource报错文件找不到求助

解决Spring RestController文件下载的两个核心问题

看起来你遇到的是Spring文件下载里两个非常典型的坑:一是@RestController默认把返回对象序列化JSON了,二是ByteArrayResource本身没有实际URL,调用getURL()肯定报错。我来一步步帮你解决:

问题根源拆解

  1. 下载内容变成JSON:@RestController自带@ResponseBody注解,会自动把你返回的ByteArrayResource对象序列化成JSON字符串,所以你看到了{"byteArray":"JVBERi0xLjQKJeL...."}这种格式,而不是实际的文件流。
  2. FileNotFoundException:ByteArrayResource是内存中的字节数组资源,根本没有对应的文件系统URL,所以调用它的getURL()方法必然抛出这个异常,你的代码里大概率有地方尝试获取这个资源的URL,得去掉。

正确的实现方式

用ResponseEntity<Resource>来手动构建下载响应,完全掌控响应头和返回体,避开@RestController的自动序列化。下面是修正后的完整代码示例:

@Api("products")
@RestController
@RequestMapping("/v1/products")
public class ProductController {

    @GetMapping("/download/{id}")
    public ResponseEntity<Resource> downloadFile(@PathVariable Long id) throws IOException {
        // 1. 替换成你的实际业务逻辑:从数据库/存储服务获取文件字节数组
        byte[] fileContent = fetchFileBytesById(id);
        
        // 2. 包装成ByteArrayResource
        ByteArrayResource resource = new ByteArrayResource(fileContent);
        
        // 3. 构建响应,设置正确的头信息
        return ResponseEntity.ok()
                // 根据文件类型设置ContentType,比如PDF用application/pdf,通用文件用application/octet-stream
                .contentType(MediaType.APPLICATION_PDF)
                // 设置下载头:attachment触发浏览器下载,filename指定下载后的文件名
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"product-document.pdf\"")
                // 直接返回资源对象,Spring会自动读取输入流写入响应
                .body(resource);
    }

    // 模拟获取文件字节数组的业务方法
    private byte[] fetchFileBytesById(Long id) {
        // 这里替换成你的实际逻辑:比如从数据库Blob字段读取,或者从OSS下载
        return new byte[0];
    }
}

关键注意事项

  • 不要调用resource.getURL():ByteArrayResource是内存资源,没有物理URL路径,完全不需要这个操作。
  • 匹配正确的ContentType:如果是Excel文件,用application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;Word文档用application/vnd.openxmlformats-officedocument.wordprocessingml.document;如果不确定文件类型,用通用的application/octet-stream。
  • Content-Disposition头:如果想让浏览器直接预览文件(比如图片、PDF),可以把attachment改成inline,但大部分下载场景用attachment更合适。

这样修改后,浏览器会正确触发文件下载,也不会再出现那个FileNotFoundException了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:57:44