SpringBoot 下载文件名空格变加号的问题【兼容正确加号】

问题来源

最近在做一个项目,里面涉及到了文件下载的功能。
测试同事在回归测试的时候反馈,文件名中有空格的文件,下载后空格变成了加号。

排查过程

数据源

首先是排查数据库中存储的文件是否正常:
SpringBoot 下载文件名空格变加号的问题【兼容正确加号】_第1张图片可以看到,当前数据库中的文件名(f001v_disk001)是正常的。那就意味着是在代码的逻辑处理中导致的。

代码逻辑

很简单的下载代码,摘取一下对应的代码片段:

String fileName = getFileNameById(id);
response.setHeader("Content-Disposition",
				"attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));

很简单:先是通过id获取文件名,然后设置返回header,使用URLEncoder转码一下。
既然原始数据没问题,而且fileName提取也没问题,那么肯定出在了转码上。

解决过程

1. 解决方法查找

在google和百度上搜索了

URLEncoder.encode转译后“空格”变“加号”的问题

这个问题,发现好多人都反馈了类似的问题:有的是上传之后报错了,有的和我一样,是在下载之后出现的问题。

2.决解方法

查询了多篇网上的解决思路,无外乎两者方法:

2.1 直接替换

使用 String.replaceAll() 方法将加号转成空格。

String fileName = getFileNameById(id);
fileName = fileName.replaceAll("\\+","%20")
response.setHeader("Content-Disposition",
				"attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));

缺点:最大的问题就是原本文件名中,如果有加号,那么替换后就变成空格了。最终导致文件夹名不一致,不满足原始要求

2.2 使用新的字符编码

String fileName = getFileNameById(id);
fileName= new String(fileName.getBytes("gbk"), "iso8859-1");
response.setHeader("Content-Disposition", "attachment;filename=" + allname);

缺点:因为是GBK编码,可能会导致某些中文不支持,导致下载的文件夹名为乱码(事实上我测试中也遇到了这种情况),还是不满足原始要求。

最终方案

经过尝试,以及分析了源码,最终的解决代码如下:

String fileName = getFileNameById(id);
response.setHeader("Content-Disposition",
				"attachment;filename="+new String(fileName).getBytes("UTF-8"),"ISO8859-1");

你可能感兴趣的:(java,spring,boot,后端,java)