一点总结,记下备忘。
1、Unicode是一个字符集, 可以看作为内码,是各种其它编码互相转换的一个桥梁。
2、Java编译器把java类或者JSP编译为class文件时会将转换为UTF格式保存,运行加载至内存后转换为unicode编码。
编译Java类时,如果没有指定编码默认就用系统编码如XINXP默认编码格式为GBK,相当于Java类文件(GBK)----Class文件(UTF);
容器编译JSP时,如果jsp页面中指定了pageEncoding属性,按照pageEncoding指定的编码进行转换,如果没有指定pageEncoding则按
contentType中charset指定的编码进行转换。
3、运行时,JVM加载Class文件并转换为Unicode编码,Unicode编码可以其它编码进行转换。
以System.out.println("中国")为例分析;
在Java文件中GBK编码为D6 D0 CE C4,编译为Class文件后为:E4 B8 AD E6 96 87,JVM运行时为:4E 2D 65 87
由于System.out.println("中国")是要把数据传输给输出设备,所以要转换为特定系统编码:D6 D0 CE C4
操作系统接收到这个字符流后就可以进行正确的显示了。
4、浏览器发送请求时会对请求参数非Ascii的字符进行编码(注意也会对URL路径中的中文字符进行编码,编码方式和请求参数编码有些区别,但是我们平常一般不会使用中文作为路径,所以不考虑),容器接收到后将数据封装到HttpServletRequest对象中,在使用
getParameter()获取值前要进行解码操作,如果解码和编码所使用的编码格式不一致,就会导致出现乱码。
对于GET请求,浏览器会使用系统默认编码进行编码转换,比如 lang=中文 转换为 lang=%D6%D0%CE%C4
对于POST请求,浏览器使用contentType中charset编码进行转换。
容器进行解码
对于GET请求,默认使用ISO-8859-1进行解码,但是也可以通过容器配置文件设置解码格式,如tomcat容器中可以通过URIEncoding="GBK"设置解码格式
对于POST请求,会使用request.getCharacterEncoding()返回的编码进行解码,如果返回null则使用ISO-8859-1进行解码
所以一般会用过滤器对每个请求都设置编码:request.setCharacterEncoding();