解决SpringBoot打为jar包后,通过response.getOutputStream下载文件内容为空。

背景:项目中有一个下载文件模板的功能,文件为excl表格文件。
问题是在Idea运行这个项目时,下载的文件是有内容的。但打为jar包后下载的文件是空的。

解决:
首先查找原因,
发现,一个原因是打为jar包后,路径有变,而我代码中获取文件的方式不适用于Jar包,改为this.getClass().getResourceAsStream("/templates/seatInfoTemplate.xls")解决。

但发现下载的文件还是为空,通过InputStream流对象的available方法获取长度,发现在idea运行时,是返回正常长度的,通过jar运行时,长度为0.
参考https://blog.csdn.net/Nile_Holmes/article/details/113091421得知了原因,同时又参考https://blog.csdn.net/qq_37461349/article/details/108616709明白,必须要有一个File工具类,将获取到的InputStream输入流数据,写入到一个临时文件中,然后才能通过Response的OutputStream对象输出给前端

代码如下:

        File seatInfoTemplate = File.createTempFile("seatInfoTemplate", ".xls");
        //将通过getResourceAsStream方法取得得输入流IO数据同File对象结合。
        FileUtils.copyInputStreamToFile(this.getClass().getResourceAsStream("/templates/seatInfoTemplate.xls"), seatInfoTemplate);

        try {
            //加上设置大小下载下来的.xlsx文件打开时才不会报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
            logger.warn("文件长度:"+seatInfoTemplate.length());
            response.setHeader("Content-Length", String.valueOf(seatInfoTemplate.length()));
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode("seatInfoTemplate.xls".trim(), "UTF-8"));
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();
        }
        //根据File对象实例化新的输入流IO对象
        InputStream is = new FileInputStream(seatInfoTemplate);

        //获取响应输出流对象。
        OutputStream outputStream = response.getOutputStream();

        //采用工具类,复制输入流IO对象数据至响应输出流。
        IOUtils.copy(is,outputStream );

        //输出
        outputStream.flush();
        outputStream.close();

这段代码参考:https://blog.csdn.net/lx1315998513/article/details/119699924

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果您在Spring Boot应用程序中使用了下载文件的功能并且在打包后下载文件内容为空,可能是因为在打包时文件没有被正确地打包到jar文件中。 为了解决这个问题,您需要在pom.xml文件中添加以下插件: ```xml <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <id>repackage</id> <configuration> <classifier>exec</classifier> </configuration> </execution> </executions> </plugin> </plugins> </build> ``` 这个插件的作用是重新打包应用程序,并将所有依赖包和应用程序放在一个可执行的jar文件中。 然后,您需要将您的下载文件的代码中的文件路径修改为类路径下的路径,如下所示: ```java String filePath = "/yourfile.pdf"; //类路径下的路径 InputStream inputStream = getClass().getResourceAsStream(filePath); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("yourfile.pdf", "UTF-8")); IOUtils.copy(inputStream, response.getOutputStream()); response.flushBuffer(); ``` 这样,当您打包并运行应用程序时,您应该就能够成功下载并查看您的文件了。 另外,如果您使用的是Spring Boot 2.1及以上版本,您还可以使用以下代码来下载文件: ```java String filePath = "/yourfile.pdf"; //类路径下的路径 Resource resource = new ClassPathResource(filePath); response.setContentType("application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("yourfile.pdf", "UTF-8")); IOUtils.copy(resource.getInputStream(), response.getOutputStream()); response.flushBuffer(); ``` 这个代码片段中,我们使用了Spring Framework提供的Resource对象来获取文件输入流,这样可以避免了使用getClass().getResourceAsStream()方法时可能出现的空指针异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值