论坛首页 Java企业应用论坛

文件下载时文件名在ie和firefox下面表现不一致问题

浏览 18061 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (1) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-01-25  
首先文件名是是以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,不知道大家有没有遇到过类似的问题,解决之道是什么?
也许判断浏览器类型来进行不同的处理会是一种解决方案,但是这是一种个人觉得迫不得已的解决方案。
   发表时间:2007-01-25  
只能根据user-agent来:

http://forum.java.sun.com/thread.jspa?threadID=696263

http://www.blogjava.net/zamber/archive/2006/09/14/69752.html#Feedback

参考这两个:
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);
}



0 请登录后投票
   发表时间:2007-01-25  
thanks a lot
0 请登录后投票
   发表时间:2007-01-26  
MimeUtility 这个类是哪里的呀??


找到了
使用到了JavaMail中的Base64编码的类MimeUtility.

有没有同样功能的 但是不在 javamail里 的类啊?
例如 commons-codec-1.3.jar 里有没有?
0 请登录后投票
   发表时间:2007-01-26  
如果超过文件名超过 17 个中文字符,在 IE 下会有问题,详情请见:http://support.microsoft.com/?kbid=816868。下面是我专门给 IE 做的解决方案:
    /**
     * @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;
    }

0 请登录后投票
   发表时间:2007-01-26  
crofton 写道
如果超过文件名超过 17 个中文字符,在 IE 下会有问题,详情请见:http://support.microsoft.com/?kbid=816868。下面是我专门给 IE 做的解决方案:
    /**
     * @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参数是做什么的?
谢谢
0 请登录后投票
   发表时间:2007-01-26  
String codedfilename = MimeUtility.encodeText(cfrfilename, "UTF8", "B");  
这段代码我是不是可以用
String codedfilename = new String(cfrfilename.getBytes("UTF-8"), "iso-8859-1");代替?  
0 请登录后投票
   发表时间:2007-01-27  
我找到了更好的方法
	// 其中 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;
		}
	}

0 请登录后投票
   发表时间:2007-01-27  
可是这个仍然存在问题啊
1。ie文件名超长问题,可以通过crofton的方法解决。
2。ff下面文件名超长后,文件名就被自动截断了(包括文件扩展名也没了),虽然可以通过判断长度来处理,但是有没有更好的方法呢
0 请登录后投票
   发表时间: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;
}
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics