中文乱码问题

来源:互联网 发布:网络爬虫技术介绍 编辑:程序博客网 时间:2024/05/21 09:31

一个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

原创粉丝点击