做项目遇到了个比较有代表性的问题,就是我们经常讨论的下载时中文文件名乱码,为什么说该问题有代表性呢,因为该问题在三家(Firefox,IE,Chrome)主流的浏览器中均出现了。
问题现象:
1、在最开始的时候,没有对文件名进行编码,结果文件名是乱码,乱的是面目全非,那么用下面一句将文件名进行编码,问题解决了。。可是,可恶的客户外语实在是太好了,用的竟然是英文版的Chrome,那对于文件名是不支持GBK解析的,将我的汉字按ISO8859-1来进行解析,结果可以想象是什么样的乱码了;
总的解决方案,没有一句话就能接解决所有浏览器下载文件名乱码的问题,所以就只能通过判断浏览器的厂家来解决乱码!
*该段代码依赖org.apache.commons.lang.StringUtils.contains方法
问题现象:
1、在最开始的时候,没有对文件名进行编码,结果文件名是乱码,乱的是面目全非,那么用下面一句将文件名进行编码,问题解决了。。可是,可恶的客户外语实在是太好了,用的竟然是英文版的Chrome,那对于文件名是不支持GBK解析的,将我的汉字按ISO8859-1来进行解析,结果可以想象是什么样的乱码了;
fileName = new String(fileName.getBytes("GBK"), "ISO8859-1");
2、客户的习惯我们不能改变,那么改吧,将上面的GBK换成UTF-8,这回你没理由不支持了吧,代码就成了下面这个样子;在网上找了个英文版的Chrome测试,完美简体;但是问题总是不让人消停,在IE写又乱了,还跟IE版本无关;看乱码的样子是,本来应该是以UTF-8来解析的却被IE按GBK来解析了,这怎么行;
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
3、问题还得解决,不能用上面的GBK(Chrome乱),也不能用UTF-8(IE乱);在网上搜了下可以用下面方法解决IE文件名乱码;结果,我猜到了,果然是Firefox又不乐意了,汉字被编码了,一个汉字变成了三个%FF的形式;(在CSDN下下载文件会出现Firefox乱码)
fileName = URLEncoder.encode(fileName,"UTF8");
总的解决方案,没有一句话就能接解决所有浏览器下载文件名乱码的问题,所以就只能通过判断浏览器的厂家来解决乱码!
public void writeFileToClient(HttpServletRequest request, HttpServletResponse response)
throws IOException {
// 要写到客户端的文件名
String fileName = "这是个中文文件名文件.xsl";
// 请求客户端操作系统的信息
final String userAgent = request.getHeader("USER-AGENT");
if(StringUtils.contains(userAgent, "MSIE")){ //IE浏览器
fileName = URLEncoder.encode(fileName,"UTF8");
}else if(StringUtils.contains(userAgent, "Mozilla")){ //Chrome,Firefox浏览器
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
}else{ //其他浏览器
fileName = URLEncoder.encode(fileName,"UTF8");
}
// 服务器端的文件
InputStream inputStream = new FileInputStream("d:/file/abc.xsl");
response.reset();
response.setContentType("application/vnd.ms-excel; charset=UTF-8");
response.addHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
byte[] b = new byte[100];
int len;
while ((len = inputStream.read(b)) > 0) {
response.getOutputStream().write(b, 0, len);
}
inputStream.close();
}
*该段代码依赖org.apache.commons.lang.StringUtils.contains方法