1、Java编译器在对源文件编译前,会先把源文件转换为unicode编码,因为这个原因,我们在编译时一定要把源文件用的是什么编码方式正确无误的”告诉”编译器。
例如:我们的源文件是以UTF-8的方式保存的,而在编译时编译器却把它当作是用GBK方式保存的,这样编译器就会按照GBK-Unicode的编码转换方法对源文件进行转换,然后再编译,这样当然会出错,实际上编译器应当按照UTF-8-Unicode的编码转换方法来对源文件进行转换。
a.对于控制台程序,编译器会把源文件看作是由系统默认的编码类型来编码的(系统默认的编码类型取决于在控制面板区域设置里的配置,中文win2k下通常是GBK),也可以使用-encoding参数来设置,如:javac -encoding UTF-8,这样编译器就会把源文件看作是用UTF-8编码的(这只是告诉编译器源文件的编码类型,而不是对源文件转码)。在各种语言的平台上只要在编译用时-encoding指定与源文件的编码相同的编码方式,就不会存在国际化的问题了。
b.对于jsp,编译器则会根据设定的字符集来判定JSP文件使用的是什么编码方式,进而将其转换成unicode后进行编译;若JSP中未指定,编译器则会把JSP文件看作是按照系统默认的编码来保存的。在JSP2.0里新增了一个指令来通知编译器这个源文件所使用的编码方式。
2、在处理输入输出时,注重设置输入流和输出流的编码类型与用户输入时和输出设备显示时采用的编码方式一致。
由于JRE在处理输入输出时会将输入或输出的内容进行编码转换,对于输入会转换为unicode后再送入,因此要正确的匹配实际输入内容的编码方式和告知JRE的编码方式,对于输出,会由unicode转换为其他的编码再送出程序,因此要正确匹配输出设备显示时用的编码方式和告知JRE的编码方式。
例如:程序中设置输入流的编码是newInputStreamReader(System.in,"GB2312");而程序运行后用户输入时用了繁体中文的输入法,输入了BIG5编码的内容,这样JRE把BIG5编码的内容当作GB2312的进行了GB2312-unicode的编码转换,这样转换后的结果显然不是用户想要输入的内容了。
默认情况下,JRE会把输入输出的内容当作是按照系统默认编码方式编码的。
3、在Servlet中,除了一定要把源文件用的是什么编码方式正确无误的”告诉”编译器外,还要注重实际提交的URL数据、表单数据的编码格式和request中声明的编码格式一致。
客户端浏览器在通过表单和URL提交数据时,容器和JVM会将request中的数据看作是按照request所声明的编码方式来编码的,将数据由这种编码方式转换为unicode后再送入servlet(实际上容器会先将request中的数据转为一种中间编码方式,具体根据容器的配置而定,再由JVM由这种中间方式转换为unicode,通常这种中间格式是ISO)。servlet输出的unicode数据会由容器根据response中声明的编码方式进行转换,再送到客户端浏览器上。
在接收客户端输入时,用request.setCharacterEncoding()声明请求中数据的编码方式。
在向客户端输出时用response.setContentType("text/Html;charset=");声明响应的数据的编码方式,告知浏览器以哪种编码方式显示。
4、在JSP中,由于JSP本就会被JSP编译器编译为servlet来运行,因此情况与servlet相同。
这两个JSP指令声明了请求和响应的编码方式。
只要确保URL参数或表单中数据的编码方式和所声明的编码方式一致,再通过告知JSP编译器本JSP文件采用的编码方式及含有哪种字符,即可解决JSP的字符编码问题。