欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

中文乱码问题

程序员文章站 2022-07-12 22:13:51
...

一个http请求经过的几个环节:
浏览器(ie firefox)【get/post】————>Servlet服务器——————————->浏览器显示
浏览器会根据本地系统默认的字符集或者页面的设置编码对URL进行编码(前面提到),而Web容器默认采用的是IS0-8859-1(注意:Tomcat 7以下默认是ISO-8859-1,而Tomcat 8默认是UTF-8编码)对POST或Get的数据进行解析。在浏览器提交中文数据后,Web容器按照默认的编码方式来解码数据,这一环节可能会导致乱码的产生。(大多数数据库的JDBC驱动程序默认采用ISO-8859-1,与java程序之间传递数据,也有可能产生乱码)。

以下是IE6.0,Tomcat 6.0,Web请求的响应过程:

中文乱码问题

//而Tomcat 8默认是 UTF-8,,不需要解码,直接获得值
String downFilename=request.getParameter("zipName");
//但是Tomcat 7 默认是ISO-8859-1  ,需要解码: 
downFilename=new String(downFilename.getBytes("ISO-8859-1"),"UTF-8");

String.getBytes(Stringdecode)方法会根据指定的decode编码返回某字符串在该编码下的byte数组表示。而与getBytes相对的,可以通过new String(byte[], decode)的方式来还原,这个new String(byte[],decode)实际是使用指定的编码decode来将byte[]解析成字符串。

使用ISO8859-1编码再组合之后,无法还原。原因很简单,因为ISO8859-1编码的编码表根本就不包含汉字字符,当然也就无法通过”中”.getBytes(“ISO8859-1”);来得到正确的中文在ISO8859-1中的编码值了。

但是有时候为了能够下载文件,需要为了让中文字符适应某些特殊要求(如httpheader要求其内容必须为iso8859-1编码),可能会通过将中文字符按照字节方式来编码的情况,如:
String s_iso88591 = newString(“中”.getBytes(“UTF-8”),”ISO8859-1”),这样得到的s_iso8859-1字符串实际是三个在ISO8859-1中的字符,在将这些字符传递到目的地后,目的地程序再通过相反的方式Strings_utf8 = newString(s_iso88591.getBytes(“ISO8859-1”),”UTF-8”)来得到正确的中文汉字”中”,这样就既保证了遵守协议规定、也支持中文。

参考文章:1、http://www.codeweblog.com/http%E5%8D%8F%E8%AE%AEheader%E4%B8%ADcontent-disposition%E4%B8%AD%E6%96%87%E6%96%87%E4%BB%B6%E5%90%8D%E4%B9%B1%E7%A0%81/

2、http://blog.csdn.net/wienne0417/article/details/3335682

FileInputStream fis = new FileInputStream(f);

            String userAgent=request.getHeader("User-Agent");
            userAgent=userAgent.toLowerCase();
            String filename="";
            if(userAgent.indexOf("msie")!=-1){
                filename = new String(f.getName().getBytes("GBK"), "iso-8859-1"); // IE浏览器    解决中文文件名下载后乱码的问题               
            }else{
                filename = new String(f.getName().getBytes("UTF-8"), "iso-8859-1"); // 解决中文文件名下载后乱码的问题

            }

            byte[] b = new byte[fis.available()];
            fis.read(b);
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + filename + "");
            // 获取响应报文输出流对象
            ServletOutputStream out = response.getOutputStream();

针对不同的浏览器,可能也要判断不同的编码方式:

public class UserAgentUtil {
    public static String encodeFileName(HttpServletRequest request,String fileName){
        String userAgent=request.getHeader("User-Agent");
        String rtn="";
        try{
            String new_fileName=URLEncoder.encode(fileName,"UTF8");
            //如果没有userAgent,则默认使用IE进行编码
            rtn="filename=\""+new_fileName+"\"";

            if(userAgent !=null){
                userAgent=userAgent.toLowerCase();
                //IE浏览器
                if(userAgent.indexOf("msie")!=-1){
                    rtn="filename=\""+new_fileName+"\"";
                }
                //Opera浏览器
                else if(userAgent.indexOf("opera")!=-1){
                    rtn="filename*=UTF-8''"+new_fileName;       
                }
                //Safari浏览器
                else if(userAgent.indexOf("safari")!=-1){
                    rtn="filename=\""+new String(fileName.getBytes("UTF-8"),"ISO8859-1")+"\"";                  
                }
                //Chrome浏览器
                else if(userAgent.indexOf("applewebkit")!=-1){
                    new_fileName=MimeUtility.encodeText(fileName, "UTF8", "B");
                    rtn="filename=\""+new_fileName+"\"";
                }
                //firefox浏览器
                else if(userAgent.indexOf("mozilla")!=-1){
                    rtn="filename*=UTF-8''"+new_fileName;
                }


            }
        }catch(Exception e){
            e.printStackTrace();
        }
        return rtn;

    }
}

参考文章:
http://www.cnblogs.com/haitao-fan/p/3399018.html
http://www.ruanyifeng.com/blog/2010/02/url_encoding.html
http://www.360doc.com/content/09/0319/21/111235_2858598.shtml

相关标签: 乱码