这篇博客,主要是了解一下关于java在console控制台、Servlet类、数据库行运行时的编解码过程。


        我们总是用一个java类文件和用户进行最直接的交互(输入、输出),这些交互内容包含的文字可能包含英文,但是更加需要我们关注的可能是包含中文。无论java类是与数据库交互还是与前端页面交互,他们的生命周期都是这样的:

1.  程序员在操作系统上通过编辑器编写的代码并且保存在本地以.java的格式保存,这些文件成为源文件。(windows默认以GBK的编码格式保存,但是我在Myeclipse中设置了我的源文件保存以UTF-8的形式保存。)

2.  通过JDK的javac.exe 编译这些源文件形成.class的类文件。

3.  直接运行这些类文件或则部署在 WEB容器中运行,得到输出结果。

        这些过程是从宏观上来了解的,但是我们得深入到里面java的编解码过程。

第一步:

System.out.println(System.getProperty("file.encoding"));由于我在eclipse里面已经设置了源文件以UTF-8编码保存,所以我的输出是UTF-8。


第二步:


第三步:   JDK将上面编译好的且保存在内存中信息写入class文件中,形成.class文件。此时.class文件是Unicode编码的,也就是说我们常见的.class文件中的内容无论是中文字符还是英文字符,他们都已经转换为Unicode编码格式了。

                         在这一步中对对JSP源文件的处理方式有点儿不同:WEB容器调用JSP编译器,JSP编译器首先会查看JSP文件是否设置了文件编码格式,如果没有设置则JSP编译器会调用调用JDK采用默认的编码方式将JSP文件转化为临时的servlet类,然后再编译为.class文件并保持到临时文件夹中。


第四步:

                                 1、直接在console上运行。

                                 2、JSP/Servlet类。

                                 3、java类与数据库之间。

                          这三种情况每种情况的方式都会不同,

1. Console上运行的类

        这种情况下,JVM首先会把保存在操作系统中的class文件读入到内存中,这个时候内存中class文件编码格式为Unicode,然后JVM运行它。如果需要用户输入信息,则会采用file.encoding编码格式对用户输入的信息进行编码同时转换为Unicode编码格式保存到内存中。程序运行后,将产生的结果再转化为file.encoding格式返回给操作系统并输出到界面去。整个流程如下:

Java 日文乱码问题_编码格式

2. Servlet类

        由于JSP文件最终也会转换为servlet文件(只不过存储的位置不同而已),所以这里我们也将JSP文件纳入其中。

WEB容器会调用它的JVM来运行Servlet。首先JVM会把servlet的class加载到内存中去,内存中的servlet代码是Unicode编码格式的。然后JVM在内存中运行该Servlet,在运行过程中如果需要接受从客户端传递过来的数据(如表单和URL传递的数据),则WEB容器会接受传入的数据,在接收过程中如果程序设定了传入参数的的编码则采用设定的编码格式,如果没有设置则采用默认的ISO-8859-1编码格式(这个地方需要指定输入字符串的编码格式),接收的数据后JVM会将这些数据进行编码格式转换为Unicode并且存入到内存中。运行Servlet后产生输出结果,同时这些输出结果的编码格式仍然为Unicode。紧接着WEB容器会将产生的Unicode编码格式的字符串直接发送置客户端,如果程序指定了输出时的编码格式,则按照指定的编码格式输出到浏览器,否则采用默认的ISO-8859-1编码格式(这个地方需要指定输出字符串的编码格式)。整个过程流程图如下:

Java 日文乱码问题_数据库_02

2. 数据库部分

        我们知道java程序与数据库的连接都是通过JDBC驱动程序来连接的,而JDBC驱动程序默认的是ISO-8859-1编码格式的,也就是说我们通过java程序向数据库传递数据时,JDBC首先会将Unicode编码格式的数据转换为ISO-8859-1的编码格式,然后在存储在数据库中,即在数据库保存数据时,默认格式为ISO-8859-1。(但是在实际中我们在安装数据库时一般默认设置编码格式是UTF-8)

Java 日文乱码问题_数据库_03