设置utf8编码问题

it2022-05-05  193

注意:乱码和request的具体实现类有关,现在已经查到的是RequestDispatcher.forward调用前使用的是org.apache.catalina.connector.RequestFacade类而RequestDispatcher.forward调用后使用的是org.apache.catalina.core.ApplicationHttpRequest,他们内部在ParseParameter的时候, 用来解码的默认的编码逻辑不同,使用不同的协议时,影响乱码的因素不同! 具体参考:Tomcat源码分析--ServletRequest.getParameterValues内部分析,Request字符集&QueryStringEncoding 乱码的产生 譬如汉字“中”,以UTF-8编码后得到的是3字节的值中,然后通过GET或者POST方式把这3个字节提交到Tomcat容器,如果你不告诉Tomcat我的参数是用UTF-8编码的,那么tomcat就认为你是用ISO-8859-1来编码的,而ISO8859-1(兼容URI中的标准字符集US-ASCII)是兼容ASCII的单字节编码并且使用了单字节内的所有空间,因此Tomcat就以为你传递的用ISO-8859-1字符集编码过的3个字符,然后它就用ISO-8859-1来解码,得到中-,解码后。字符串中-在Jvm是以Unicode的形式存在的,而HTTP传输或者数据库保存的其实是字节,因此根据各终端的需要,你可以把unicode字符串中-用UTF-8编码后得到相应的字节后存储到数据库(3个UTF-8字符),也可以取得这3个字符对应的ISO-8859-1的3个字节,然后用UTF-8重新编码后得到unicode字符“中”(特性:把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题),然后用response传递给客户端(根据你设置的content-type不同,传递的字节也是不同的!) 总结: 

1,HTTP GET或者POST传递的是字节?数据库保存的也是字节(譬如500MB空间就是500M字节)2,乱码产生的原因是编码和解码的字符集(方式)不同导致的,即对于几个不同的字节,在不同的编码方案下对应的字符可能不同,也可能在某种编码下有些字节不存在(这也是乱码中?产生的原因)3,解码后的字符串在jvm中以Unicode的形式存在4,如果jvm中存在的Unicode字符就是你预期的字符(编码,解码的字符集相同或者兼容),那么没有任何问题,如果jvm中存在的字符集不是你预期的字符,譬如上述例子中jvm中存在的是3个Unicode字符,你也可以通过取得这3个unicode字符对应的3个字节,然后用UTF-8对这3个字节进行编码生成新的Unicode字符:汉字“中”5,ISO8859-1是兼容ASCII的单字节编码并且使用了单字节内的所有空间,在支持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。换言之,把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题。

下面的代码显示,使用不同的编码来Encoder会得到不同的结果,同时如果Encoder和Decoder不一致或者使用的汉字在编码ISO-8859-1中不存在时,都会表现为乱码的形式! 

Java代码   try {              // 汉字“中”用UTF-8进行URLEncode的时候,得到中(对应的ISO-8859-1的字符是中)          String item = new String(new byte[] { (byte) 0xe4, (byte) 0xb8, (byte) 0xad }, "UTF-8");          // 中          System.out.println(item);            item = new String(new byte[] { (byte) 0xe4, (byte) 0xb8, (byte) 0xad }, "ISO-8859-1");          // 中          System.out.println(item);            System.out.println(new BigInteger("253").toByteArray());          System.out.println(Integer.toBinaryString(253));            // 中          item = new String(item.getBytes("ISO_8859_1"), "UTF-8");          System.out.println(item);          // 中          item = new String(item.getBytes("UTF-8"), "ISO_8859_1");          System.out.println(item);            // 汉字中以UTF-8编码为     中(3字节)          System.out.println(URLEncoder.encode("中", "UTF-8"));            // 汉字中以UTF-8编码为     ?      (1字节 这是由于汉字在ISO-8859-1字符集中不存在,返回的是?在ISO-8859-1下的编码)          System.out.println(URLEncoder.encode("中", "ISO-8859-1"));            // 汉字中以UTF-8编码为     
转载请注明原文地址: https://win8.8miu.com/read-6204.html

最新回复(0)