SpringBoot文件的下载
简单分析如何下载
基本框架
SpringBoot1.X + Swagger
数据的来源
服务器上的文件数据的输入流
数据传递
将文件信息,通过输入流传递给reponse中的输出流,利用该输出流传输
如何让浏览器响应,下载文件
通过设置response的相关属性,来实现让浏览器下载文件
简单流程
代码实现
具体代码及实现在这里 – 记SpringBoot下载的两种方式
//代码的话我这里只放关键性代码以及一些伪代码 - 记得使用Get请求
@GetMapping(value = "*****" , headers="Accept=application/octet-stream" , produces = "application/octet-stream")
public void download(@RequestParam("path") String path, HttpServletResponse response ) throws IOException {
//创建文件对象
//获取文件名称
try {
//重置响应头信息
//设置响应字符编码
//设置下载信息 及文件名称
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "utf8"));
//设置Pragma禁用缓存
//设置Cache-Control为禁用缓存
//设置返回为流
response.setContentType("application/octet-stream;charset=UTF-8");
// 构建文件输入流
//根据文件的类型,构建相应的流,比如docx,就构建XWPFDocument对象,doc文件就构建HWPFDocument对象
//将对象中的流写出到response.getOutputStream()
//关闭用输入流创建的对应的对象,不要关闭输出流
} catch (IOException ex) {
ex.printStackTrace();
}
}
遇到的问题
使用@PostMapping注解
要下载的文件
尝试下载文件
第一种方式用swagger测试,点击下面的响应体链接
得到的文件
第一个问题:文件名称乱码(或者说未解码 , 解码后是正确的文件名称);
第二个问题:格式错误,文件打不开,并且文件变得更大。(感觉上还是浏览器解析流的时,出现的问题)。
第二个方法,直接将swagger产生的request请求直接放到新的地址栏
复制到新的窗口,回车访问
结果。。。Post请求 果然不能这么搞
又或者是直接自己输入访问地址
这次请求都没进去。。。
后台直接报错
具体是
java.lang.IllegalArgumentException: Invalid character found
in the request target. The valid characters are defined in
RFC 7230 and RFC 3986
这个报错表示的是,访问路径包括非法字符,具体大家可以用这个报错信息搜一下。
第三个方法,放到PostMan里面测试
得 后台直接请求都没收到 直接返回一个空的txt文本
第四种方法,swagger + PostMan
将swagger中的请求地址,方法PostMan里面
可以正常下载,文件内容也没问题,可是文件名乱码。
至此其实已经有点放弃了,搜了一堆资料,有的说是浏览器的问题,但我浏览器根本无法下载文件,响应头设置也是utf-8,流的设置也对。
到底是哪里出了问题?
。。。。一番百度,搜索后,有帖子说swagger有问题,还有的说是 @PostMapping的问题,用 @GetMpping就没事。
@GetMapping的尝试
尝试下载文件
直接点击swagger生成的链接
下载的文件还是乱码,文件名也是,并且打不开
将生成的请求,复制到新的窗口打开 – 问题解决了!!!
回车访问
成功了!!!!!!!!!!!!!!!!
文件名称和文件内容都没错。
至此,问题其实已经解决了。但我想@PostMapping不行,@GetMapping可以,那如果我直接用@RequestMapping会怎么样呢?
@RequestMapping尝试
总共是七个请求,我们测试Post和Get即可
POST
用上面的Get测试成功的方法,测试Post,结果是:
不过走的还是Get请求。。。
GET
再测一下Get,也没问题。
PostMan
但是用PostMan测试,还是同样的问题:文件名称乱码,文件内容倒是可以打开。
剩余的问题及原因分析
剩余的问题
剩下的应该就是这个问题了:没办法直接浏览器输入访问地址去访问请求。 比如直接输入:http://localhost:9500/xxxxx/download?path=D:\测试文件.docx
java.lang.IllegalArgumentException: Invalid character found
in the request target. The valid characters are defined in
RFC 7230 and RFC 3986
有的说是要自定义Tomcat类,设置可通过的规则,但我试了下,貌似没什么用(我的SpringBoot版本是1.x),也有的说是tomcat编码规则什么的,我设置了下,也没什么用。。。。。
原因分析
感觉还是swagger下载时,对流的解析与浏览器不同,所以才导致文件会变大,并且无法打开,文件名称不对应该是未解码(使用URL解码就是测试文档了)。
下载的实现
具体的下载我放到另一篇文章里了记SpringBoot下载的两种方式