文件下载时文件名在ie和firefox下面表现不一致问题
首先文件名是是以utf-8编码保存在数据库中,文件名暂定为1_中文文件123.txt,然后作如下处理来下载
response.setContentType("application/octet-stream;charset=UTF-8");
fileName=java.net.URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
此时在ie下面点击文件下载的时候能够正确显示中文名称1_中文文件123.txt%0A,但是文件名的结尾却出现%0A字符(个人猜测是结束符的utf-8编码);但是此时在firefox下面却显示1_%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6123.txt%0A
然后我又试了另一种方案
response.setContentType("application/octet-stream;charset=UTF-8");
fileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");
response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
此时在ie下面下载的时候弹chu的文件名是乱码;而在firefox下面却正确显示1_中文文件123.txt。
我想要的是不管是ie还是firefox都正确显示1_中文文件123.txt,不知道大家有没有遇到过类似的问题,解决之道是什么?
也许判断浏览器类型来进行不同的处理会是一种解决方案,但是这是一种个人觉得迫不得已的解决方案。
String agent = request.getHeader("USER-AGENT");if (null != agent && -1 != agent.indexOf("MSIE")){String codedfilename = URLEncoder.encode(cfrfilename, "UTF8");response.setContentType("application/x-download");response.setHeader("Content-Disposition","attachment;filename=" + codedfilename);}else if (null != agent && -1 != agent.indexOf("Mozilla")){ String codedfilename = MimeUtility.encodeText(cfrfilename, "UTF8", "B");response.setContentType("application/x-download");response.setHeader("Content-Disposition","attachment;filename=" + codedfilename);}else {response.setContentType("application/x-download");response.setHeader("Content-Disposition","attachment;filename=" + cfrfilename);}
/** * @author crofton@citiz.net * @param fileName name of downloaded file without extention * @param extension extension of downloaded file with dot character * @return encoded fileName for IE * @throws UnsupportedEncodingException never happened */ public static String encodeFileName(String fileName, String extension) throws UnsupportedEncodingException { //UTF8 URL encoding only works in IE fileName = URLEncoder.encode(fileName, "UTF-8"); //Bug of IE (http://support.microsoft.com/?kbid=816868) //Encoded fileName cannot be more than 150 int limit = 150 - extension.length(); if (fileName.length() > limit) { //because the UTF-8 encoding scheme uses 9 bytes to represent a single CJK character fileName = URLEncoder.encode(prefix.substring(0, Math.min(prefix.length(), limit / 9)), "UTF-8"); } return fileName + extension; }
/** * @author crofton@citiz.net * @param fileName name of downloaded file without extention * @param extension extension of downloaded file with dot character * @return encoded fileName for IE * @throws UnsupportedEncodingException never happened */ public static String encodeFileName(String fileName, String extension) throws UnsupportedEncodingException { //UTF8 URL encoding only works in IE fileName = URLEncoder.encode(fileName, "UTF-8"); //Bug of IE (http://support.microsoft.com/?kbid=816868) //Encoded fileName cannot be more than 150 int limit = 150 - extension.length(); if (fileName.length() > limit) { //because the UTF-8 encoding scheme uses 9 bytes to represent a single CJK character fileName = URLEncoder.encode(prefix.substring(0, Math.min(prefix.length(), limit / 9)), "UTF-8"); } return fileName + extension; }
这个方法不能单独提出来用阿 那个prefix是什么?
还有那个extension参数是做什么的?
谢谢// 其中 Base64 类来自 org.apache.commons.codec 组件 一个40多k的jar 要比javamail里的那个简洁很多public static String encodeFileName(HttpServletRequest request, String fileName) throws UnsupportedEncodingException {String agent = request.getHeader("USER-AGENT");if (null != agent && -1 != agent.indexOf("MSIE")) {return URLEncoder.encode(fileName, "UTF8");}else if (null != agent && -1 != agent.indexOf("Mozilla")) {return "=?UTF-8?B?"+(new String(Base64.encodeBase64(fileName.getBytes("UTF-8"))))+"?=";} else {return fileName;}}
8 楼 eddysheng 2007-01-27 可是这个仍然存在问题啊
1。ie文件名超长问题,可以通过crofton的方法解决。
2。ff下面文件名超长后,文件名就被自动截断了(包括文件扩展名也没了),虽然可以通过判断长度来处理,但是有没有更好的方法呢 9 楼 eddysheng 2007-01-29 已经解决,方案如下:
private String processFileName(String fileName,String agent) throws IOException{
String codedfilename = null;
if (null != agent && -1 != agent.indexOf("MSIE")){
String prefix = fileName.lastIndexOf(".")!=-1?fileName.substring(0,fileName.lastIndexOf(".")):fileName;
String extension = fileName.lastIndexOf(".")!=-1?fileName.substring(fileName.lastIndexOf(".")):"";
String name = java.net.URLEncoder.encode(fileName, "UTF8");
if(name.lastIndexOf("%0A")!=-1){
name = name.substring(0,name.length()-3);
}
int limit = 150 - extension.length();
if (name.length() > limit) {
name = java.net.URLEncoder.encode(prefix.substring(0, Math.min(prefix.length(), limit / 9)), "UTF-8");
if(name.lastIndexOf("%0A")!=-1){
name = name.substring(0,name.length()-3);
}
}
codedfilename = name + extension;
} else if (null != agent && -1 != agent.indexOf("Mozilla")) {
codedfilename = "=?UTF-8?B?"+(new String(org.apache.commons.codec.binary.Base64.encodeBase64(fileName.getBytes("UTF-8"))))+"?=";
}else {
codedfilename = fileName;
}
return codedfilename;
} 10 楼 fins 2007-01-29 究竟文件名过长时候出现什么问题呢?
我用这么个名字:
列表5345用户列表用户列表12323用户列表用列表5345用户列表用户列表12323用户列表用列表5345用户列表用户列表12323用户列表用户列表5345用户列表用户列表12323列表用户列表5345用户列表用户列表12323asdasdasd.xls
够长了吧? 在ie6 和 ff下都没有出现任何问题
不明白那个 截短文件的操作有什么用?
我看那个bug了 在ie5.01就解决了 我决定没有必要截取
否则结果就是 你为了迁就少部分的5.0用户 使得大部分的6.0的用户得不到完整的ie名,除非 你再判断一下ie版本 但是怎么判断ie是否已经打过补丁了呢? 即使是5.0版本 如果打了补丁 同样不会出现这个问题啊
11 楼 manyinjin 2007-04-27 文件名过长的问题在IE7中依然存在。