转:Content |
您所在的位置:网站首页 › 中文转码变成问号了 › 转:Content |
在做文件下载时,当文件名为中文时,经常会出现乱码现象。参考文章: http://blog.robotshell.org/2012/deal-with-http-header-encoding-for-file-download/ 本文就详细给出案例来解决这一乱码问题,以及还一直未解决的一个疑问,欢迎大家一起来探讨。大体的原因就是header中只支持ASCII,所以我们传输的文件名必须是ASCII,当文件名为中文时,必须要将该中文转换成ASCII。转换方式有很多:方式一:将中文文件名用ISO-8859-1进行重新编码,如headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("UTF-8"),"ISO-8859-1")+".txt");方式二:可以对中文文件名使用url编码,如headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","UTF-8")+".txt");疑问:中文文件名转换成ASCII后传给浏览器,浏览器遇到一堆ASCII,如何能正确的还原出来我们原来的中文文件名的呢? 实验案例:乱码现象如下: @RequestMapping(value="/test/httpEntity1",method=RequestMethod.GET) public HttpEntity testHttpEntity1() throws UnsupportedEncodingException{ String body="abc"; HttpHeaders headers=new HttpHeaders(); headers.add("Content-disposition","attachment;filename=中国.txt"); HttpEntity ret=new HttpEntity(body,headers); return ret; }这里的filename直接使用中文文件,然后就造成了下面的乱码现象:
原因就是header只支持ASCII,所以我们要把"中国"转换成ASCII。解决方案一:将中文文件名用ISO-8859-1进行重新编码 @RequestMapping(value="/test/httpEntity",method=RequestMethod.GET) public HttpEntity testHttpEntity() throws UnsupportedEncodingException{ String body="abc"; HttpHeaders headers=new HttpHeaders(); headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("UTF-8"),"ISO-8859-1")+".txt"); HttpEntity ret=new HttpEntity(body,headers); return ret; }chrome为: chrome解决了乱码现象,但IE没有。但是你是否想过,浏览器面对一堆Content-disposition:attachment;filename=ä¸å½.txt,它又是如何来正确显示的中文文件名"中国.txt"的呢,它肯定要对ä¸å½,重新进行UTF-8编码才能正确显示出"中国",即必须进行类似如下的操作:new String("ä¸å½".getBytes("ISO-8859-1"),"UTF-8"),才能正常显示出"中国.txt"。而IE11进行的类似操作为:new String("ä¸å½".getBytes("ISO-8859-1"),"GBK")。同样的实验,只是把UTF-8改成GBK: @RequestMapping(value="/test/httpEntity",method=RequestMethod.GET) public HttpEntity testHttpEntity() throws UnsupportedEncodingException{ String body="abc"; HttpHeaders headers=new HttpHeaders(); headers.add("Content-disposition","attachment;filename="+new String("中国".getBytes("GBK"),"ISO-8859-1")+".txt"); HttpEntity ret=new HttpEntity(body,headers); return ret; }chrome为: 接下来说说其他的解决方案:解决方案二:可以对中文文件名使用url编码 @RequestMapping(value="/test/httpEntity",method=RequestMethod.GET) public HttpEntity testHttpEntity() throws UnsupportedEncodingException{ String body="abc"; HttpHeaders headers=new HttpHeaders(); headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","UTF-8")+".txt"); HttpEntity ret=new HttpEntity(body,headers); return ret; }chrome为: 也能正常显示出"中国.txt"。然而将该方案的UTF-8换成GBK,浏览器却不支持了。如下: @RequestMapping(value="/test/httpEntity",method=RequestMethod.GET) public HttpEntity testHttpEntity() throws UnsupportedEncodingException{ String body="abc"; HttpHeaders headers=new HttpHeaders(); headers.add("Content-disposition","attachment;filename="+URLEncoder.encode("中国","GBK")+".txt"); HttpEntity ret=new HttpEntity(body,headers); return ret; }chrome为:
解决方案三:使用最新的解决方案,即filename*=charset'lang'value。charset则是给浏览器指明以什么编码方式来还原中文文件名。如filename*=UTF-8''value,其中value为原始数据的UTF-8形式的URL编码。如下: @RequestMapping(value="/HttpEntity",method=RequestMethod.GET) public HttpEntity testHttpEntity() throws UnsupportedEncodingException{ HttpHeaders headers=new HttpHeaders();//filename="+URLEncoder.encode("中国","UTF-8")+"; String body="abc"; headers.add("Content-Disposition","attachment;filename*=UTF-8''"+URLEncoder.encode("中国","UTF-8")+".txt"); HttpEntity ret=new HttpEntity(body, headers); return ret; }chrome为:
若使用headers.add("Content-disposition","attachment;filename*=GBK''"+URLEncoder.encode("中国","GBK")+".txt")chrome为:
|
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |