2020年8月19日更新:
一种更优雅的办法参考此文:
下载的附件名总乱码?你该去读一下 RFC 文档了!
附件下载时,遇到中文附件名的兼容性问题,firefox、chrome、ie三个派系不兼容,通过分析整理,总结出处理该问题的办法,记录如下:
1、文件名编码
服务器默认使用的是ISO8859-1,而我们java代码里默认用的是UTF-8,所以需要在传给服务器时转换一下
2、浏览器对文件名的处理方式
微软在处理附件文件名时,是使用的URL解码处理,所以需要对微软系的浏览器进行单独处理
代码如下:
public String dealAttachmentName(HttpServletRequest req, String fileName) throws UnsupportedEncodingException { String userAgent = req.getHeader("user-agent"); boolean isMSBrowser = HttpUtils.isMSBrowser(userAgent); // URLEncoder 对于 空格 的转码混乱,有时转成"%20",有时转换成 "+",所以统一处理一下 return isMSBrowser ? URLEncoder.encode(fileName, "UTF-8").replaceAll("\+", "%20") : new String(fileName.getBytes("UTF-8"), "ISO8859-1"); }
/** * @description: * @projectName:mysteel-oilchem-information-columnlist * @see:com.mysteel.oilchem.cms.web.utils * @author:郑晓龙 * @createTime:2019/4/28 10:03 * @version:1.0 */ public class HttpUtils { private static String[] IEBrowserSignals = {"MSIE", "Trident", "Edge"}; /** * description 判断是否是微软的浏览器 * 微软浏览器附件名用URLencoder编码 * param [request] * return boolean * author 郑晓龙 * createTime 2019/4/28 10:05 **/ public static boolean isMSBrowser(String userAgent) { if (userAgent != null) { for (String signal : IEBrowserSignals) { if (userAgent.contains(signal)) return true; } } return false; } }
文件名编码问题处理完成后,在响应头里设置一下就可以了:
response.setHeader("Content-disposition","attachment; filename=" + realFilename);
参考: