况,运行该类首先需要 JVM 支持,即操作系统中必须安装有 JRE。运行过程是这样的:首先 java 启动 JVM,此时 JVM 读出操作系统中保存的 class 文件并把内容读入内存中,此时内存中为 UNICODE 格 式的 class 类,然后 JVM 运行它,如果此时此类需要接收用户输入,则类会默认用 file.encoding 编码格式 对用户输入的串进行编
码并转化为 unicode 保存入内存(用户可以设置输入流的编码格式)。程序运行后, 产生的字符串(UNICODE 编码的)再回交给 JVM,最后 JRE 把此字符串再转化为 file.encoding 格式(用户 可以设置输出流的编码格式)传递给操作系统显示接口并输出到界面上。 对于这种直接在 console 上运行的类,它的转化过程可用图 1 更加明确的表示出来: 图1
以上每一步的转化都需要正确的编码格式转化,才能最终不出现乱码现象。
类和不可以直接运行的支持类( b) EJB 类和不可以直接运行的支持类(如 JavaBean 类)
由于 EJB 类和不可以直接运行的支持类,它们一般不与用户直接交互输入和输出,它们常常与其它的 类进行交互输入和输出,所以它们在第二步被编译后,就形成了内容是 UNICODE 编码的类保存在操作系 统中了,以后只要它与其它的类之间的交互在参数传递过程中没有丢失,则它就会正确的运行。 这种 EJB 类和不可以直接运行的支持类, 它的转化过程可用图 2 更加明确的表示出来: 图2
c) JSP 代码和 Servlet 类
经过第二步后,JSP 文件也被转化为 Servlets 类文件,只不过它不像标准的 Servlets 一校存在于 classes 目录中,它存在于 WEB 容器的临时目录中,故这一步中我们也把它做为 Servlets 来看。 对于 Servlets,客户端请求它时,WEB 容器调用它的 JVM 来运行 Servlet,首先,JVM 把 Servlet 的 class 类从系统中读出并装入内存中,内存中是以 UNICODE 编码的 Servlet 类的代码,然后 JVM 在内存中运行 该 Servlet 类,如果 Servlet 在运行的过程中,需要接受从客户端传来的字符如:表单输入的值和 URL 中传 入的值,此时如果程序中没有设定接受参数时采用的编码格式,则 WEB 容器会默认采用 ISO-8859-1 编码 格式来接受传入的值并在 JVM 中转化为 UNICODE 格式的保存在 WEB 容器的内存中。 Servlet 运行后生成
输出,输出的字符串是 UNICODE 格式的,紧接着,容器将 Servlet 运行产生的 UNICODE 格式的串(如 html 语法,用户输出的串等)直接发送到客户端浏览器上并输出给用户,如果此时指定了发送时输出的编 码格式,则按指定的编码格式输出到浏览器上,如果没有指定,则默认按 ISO-8859-1 编码发送到客户的浏 览器上。这种 JSP 代码和 Servlet 类,它的转化过程可用图 3 更加明确地表示出来: 图3
d) Java 程序和数据库之间
对于几乎所有数据库的 JDBC 驱动程序, 默认的在 JAVA 程序和数据库之间传递数据都是以 ISO-8859-1 为默认编码格式的,所以,我们的程序在向数据库内存储包含中文的数据时,JDBC 首先是把程序内部的 UNICODE 编码格式的数据转化为 ISO-8859-1 的格式,然后传递到数据库中,在数据库保
存数据时,它默 认即以 ISO-8859-1 保存,所以,这是为什么我们常常在数据库中读出的中文数据是乱码。 对于 JAVA 程序和数据库之间的数据传递,我们可以用图 4 清晰地表示出来 图4
3. 分析常见的 JAVA 中文问题几个必须清楚的原则
首先,经过上面的详细分析,我们可以清晰地看到,任何 JAVA 程序的生命期中,其编码转换的关键 程序的生命期中, 任何 过程是在于: 文件的转码和最终向用户输出的转码过程。 过程是在于:最初编译成 class 文件的转码和最终向用户输出的转码过程。 其次,我们必须了解 JAVA 在编译时支持的、
常用的编码格式有以下几种: *ISO-8859-1,8-bit, 同 8859_1,ISO-8859-1,ISO_8859_1 等编码 *Cp1252,美国英语编码,同 ANSI 标准编码 *UTF-8,同 uni