zoukankan      html  css  js  c++  java
  • javaEE杂项 --下载文件乱码的不同解决方案

    在下载文件时,常见的方法:

    1. publicvoid getuseopdoc(HttpServletResponse response)throwsException{
    2. try{
    3. String filename ="某某文件";
    4. InputStream inputStream = getClass().getResourceAsStream("/doc/"+filename+".doc");
    5. response.reset();
    6. response.setCharacterEncoding("utf-8");
    7. response.setContentType("application/x-msdownload");
    8. response.setHeader("Content-Disposition","attachment; filename="+filename+".doc");
    9. IOUtils.copy(inputStream, response.getOutputStream());
    10. response.flushBuffer();
    11. inputStream.close();
    12. }catch(Exception e){
    13. log.debug("Request could not be completed at this moment. Please try again.");
    14. e.printStackTrace();
    15. }
    16. }
     
    • 客户端得到的几乎都会是乱码, 因为filename是UTF8编码,它被设置为attachment属性值,然后通过HTTP传输到请求端浏览器,但是,HTTP的传输编码是ISO 8859-1(java的网络传输标准编码). 用ISO8859-1传输utf8字符串肯定不兼容导致乱码或者某些错误字符.
    • 所以这时候我们想到把utf8字符串转换成iso8859-1的编码方法,传输到客户端后再用UTF8解码:
     
    1. publicvoid getuseopdoc(HttpServletResponse response)throwsException{
    2. try{
    3. String filename ="重庆水库大坝安全监测信息管理平台操作手册(业务版)";
    4. InputStream inputStream = getClass().getResourceAsStream("/doc/"+filename+".doc");
    5. response.reset();
    6. response.setCharacterEncoding("utf-8");
    7. response.setContentType("application/x-msdownload");
    8. response.setHeader("Content-Disposition","attachment; filename="+newString(filename.getbytes("utf-8"),"iso8859-1")+".doc");
    9. IOUtils.copy(inputStream, response.getOutputStream());
    10. response.flushBuffer();
    11. inputStream.close();
    12. }catch(Exception e){
    13. log.debug("Request could not be completed at this moment. Please try again.");
    14. e.printStackTrace();
    15. }
    16. }
    字符编码的更多信息可以查看http://blog.csdn.net/robertcpp/article/details/7837712.
    utf8是Unicode编码的一种优化版,因为unicode对所有字符都编码为2个字节,这导致了标准unicode编码不和任何其他编码兼容. utf-8在Unicode基础上做了一定的修改,对属于ascii的字符依然采用1个字节编码,而其他的字符则采用更多的字节. 这也被称为变长字节编码. utf8这样处理就使得它与iso8859-1兼容了. 然后说说gb2312/gbk. 二者差别在于后者可以表示繁体字,可以看作前者超集. gb2312是中文编码的国标,对所有中文采用2字节编码,相对utf-8来说,他可能还更加的节省空间.
    笔者在测试上面代码的时候,IE下文件名依然乱码, 原因未知. 不过我在把转换的编码从utf-8改为gb2312后就好了. 
    • 在求助google后,找到下面这段代码(依赖了spring的包):
      1. protectedString getFileName(String filename){
      2. try{
      3. HttpServletRequest request =((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
      4. if(request.getHeader("User-Agent").indexOf("MSIE")!=-1){
      5. return'"'+ java.net.URLEncoder.encode(filename,"UTF-8")+'"';
      6. }
      7. byte[] bytes = filename.getBytes("UTF-8");
      8. StringBuilder buff =newStringBuilder(bytes.length <<2);
      9. buff.append("=?UTF-8?Q?");
      10. for(byte b : bytes){
      11. int unsignedByte = b &0xFF;
      12. buff.append('=').append(HEX_CHARS[unsignedByte >>4]).append(HEX_CHARS[unsignedByte &0xF]);
      13. }
      14. return buff.append("?=").toString();
      15. }catch(UnsupportedEncodingException e){
      16. return filename;
      17. }
      18. }
      这段代码对文件名并区分ie和其他浏览器,然后设置不同的编码格式.
      测试在不同的环境下都可以用
        
     
     





    I see I come I conquer.
  • 相关阅读:
    Thinking in Java 第十六章学习笔记----数组
    Thinking in Java第十五章学习笔记----泛型
    Thinking in Java第十四章学习笔记----类型信息
    Thinking in Java第十三章学习笔记----字符串
    Kaggle竞赛--Titanic:Machine Learning from Disaster
    sklearn 常用算法参数设置与选择
    Pandas 入门知识
    机器学习常用数据集
    感知机PLA
    决策树CART--原理与实现
  • 原文地址:https://www.cnblogs.com/yTPety/p/6484434.html
Copyright © 2011-2022 走看看