持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第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");