参考文章:
http://java-xp.iteye.com/blog/903048
http://www.iefans.net/xiazai-wenjian-http-bianma-content-disposition/ (作者:iefans)
http://tools.ietf.org/html/rfc6266
CONTENT_DISPOSITION格式
在服务端设置response的CONTENT_DISPOSITION属性后,可以让浏览器弹出文件下载框,代码如下:
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedfileName + "\"");
当encodedfileName出现中文字符时,需要针对不同的浏览器设置不同的编码方式。目前CONTENT_DISPOSITION支持以下几种编码方式:
1. UrlEncode
2. Base64
3. RFC2231
4. ISO编码
目前主流浏览器支持的格式如下(未验证过):
1. IE浏览器,采用URLEncoder编码
2. Opera浏览器,采用filename*方式
3. Safari浏览器,采用ISO编码的中文输出
4. Chrome浏览器,采用Base64编码或ISO编码的中文输出
5. FireFox浏览器,采用Base64或filename*或ISO编码的中文输出
因此,兼容所有浏览器的服务端代码如下(取自SpringSide项目):
boolean isMSIE = (agent != null && agent.toUpperCase().indexOf("MSIE") != -1);
if (isMSIE) {
encodedfileName = Encodes.urlEncode(fileName);
} else {
encodedfileName = new String(fileName.getBytes(), Charsets.ISO_8859_1);
}
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encodedfileName + "\"");
但是,根据rfc6266中推荐的范例,用filename+filename*的形式才是推荐的。根据范例,HttpHeaders.CONTENT_DISPOSITION的内容如下:
Content-Disposition: attachment;
filename="$encoded_fname";
filename*=utf-8''$encoded_fname
其中,$encoded_fname指的是将 UTF-8 编码的原始文件名按照 RFC 3986 进行百分号 urlencode 后得到的。
这几行也可以合并为一行,推荐使用一个空格隔开。