`

【java】Java编码字符集与字符集编码入门(七) JSP页面编译成Servlet类文件过程中所涉及到的编码问题

    博客分类:
  • java
 
阅读更多

当请求一个JSP页面时,一般的都需要经历下面几个阶段:

1、应用服务器根据JSP页面生成一个Java文件

 

2、应用服务器调用java.exe将Java文件编译成一个Servlet对应的class文件

 

3、用户的浏览器请求JSP对应的Servlet,Web容器起一个线程执行Servlet,将数据返回给客户端浏览器

 

4、用户的IE根据返回的数据,将结果显示给用户。 

 

  • 服务器读取JSP页面时,是如何选择解码方案的

    第一步中应用服务器根据Jsp页面生成一个Java文件时,需要读取源Jsp页面到内存中,然后以某种编码方式生成Servlet类文件,这一读的过程会涉及到采用什么编码方式来读取的问题?这里先看一下结论:如页面中设置了pageEncoding="XX",则服务器在读取Jsp页面时,就会使用上面设置的XX来读取,如果没有设置,再看是否设置了contentType="text/html; charset=XXX" ,如果设置了,则用charset中指定的编码方式来读取。如果这两个都没有指定时,则使用默认的编码方式ISO8859-1来读取 。

    以上是读取的过程,当把Jsp页面读取到内存后,在内存中以Unicode编码存在,这时需要根据Jsp文件生成Servlet类文件,既然要定文件,这里又会涉及到编码问题,这里该使用什么编码方式来输出到文件呢?先看结论:Tomcact是使用UTF-8编码方式来输出的 ,这也是理所当然的,因为页面上会有不同的各种语言。

 

    下面来证实上面的两个结论。

    首先我们写一个Jsp页面gbk.jsp,从文件名就可知我们创建一个以GBK编码方式保存的Jsp文件。

    下面是我创建并设置好编码方式的过程: 

 

<%@ page language="java" %>
<html>
	<body>
		<form name=form1 action="" method="get">
			<input type="text" name="textParam1" size="50 px" value="國a">
			<br>
			<input type="file" name="fileParam" size="50 px" value="">
			<br>
			<input type="button" value="submit" onclick="submitForm()">
		</form>
		<script type="text/javascript"> 
			function submitForm(){ 
				//注释
				var str ="國a"; 
				form1.action = "http://localhost:8088/gb2312rs.jsp?qryParam1=" +
				 encodeURIComponent(str) + "&qryParam2="+  encodeURIComponent(form1.textParam1.value) ;
				form1.submit(); 
			} 
		</script>
	</body>
</html>

 

 

      保存后,我们开始访问一下,浏览器显示如下:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

    从上图看出浏览器使用的是ISO编码方式,所以上面文本框里显示正常才怪呢~!但当我们把浏览器的编码方式换成GBK时,看是什么样,~!~#@!¥,晕~!找了半天浏览器上面根本就没有GBK这一编码方式,中文的就只有GB2312,我们就选一下GB2312试试看,如下图:

 

    咦~!我们选择是GB2312怎么也可显示出繁体字啊?其实浏览器中的GB2312就是用的操作系统默认的编码GBK来显示的,至于解释请看《Java中的字符集编码入门(三)GB2312,GBK与中文网页 》。好奇心没有后继续往下看。

 

    我们打开服务器帮我们生成的Servlet类文件,其中输出中文的地方代码片断如下: 

http://dl2.iteye.com/upload/attachment/0016/5327/e7389077-2e8b-3092-ae93-be642b647a8d.gif

 

    我们发现中文“注释”与“國”字,都变成了乱码。既我们知道了上面结论:Tomcat是使用UTF-8编码输出的,所以该文件是UTF-8编码格式的,那我就以UTF-8来读读这个文件,读代码如下:

String fileName = "E:/tomcat-5.5.23/work/Catalina/localhost/HttpStream/org/apache/jsp/gbk_jsp.java";
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream("e:/tmp/gbk_jsp.java"), "UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(
		new​ FileInputStream(fileName), "utf-8"));
String readContent = null;
while ((readContent = br.readLine()) != null) {
	pw.write(readContent+"\r\n");
	pw.flush();				
}
pw.close();

 

    读出的文件片断如下: 

http://dl2.iteye.com/upload/attachment/0016/5327/e7389077-2e8b-3092-ae93-be642b647a8d.gif

 

    从上面输出的结果可以进一步证明生成的Sevlet就是UTF-8编码方式的存储的,因为这两个文件内容乱码显示的样子都是一样的。

 

    从最开始来看在浏览器中能正常显示,那说明生成的Servlet类文件真实的内容没有毁坏,不然不可能在浏览器中能正常显示的,我们要坚信这一点。那既然文件内容没有毁坏,为什么生成的Servlet类文件却显示的是乱码呢?

 

    经过我的一些分析,原因大致如下:

    服务器在读取Jsp源文件时是采用的ISO8859-1来读取的(这是因为页没有配置任何编码信息),而Jsp源文件本身却又是GBK编码的,这一读的过 程为字符解码过程,且又是以ISO8859-1来解的(会把GBK编码每个字节映射到ISO8859-1字符集下,因为ISO8859-1编码方案每个字符只需要1字节,而每个字节的大小为0-255,所以在 ISO8859-1字符集里是可以找到对应的字符来替代的),这一转换过程并不会丢失任何字节信息,只是每个字节对应不同的字符集所展示的内容不一样而已(由于在Java中统一会映射成Unicode字符集展示,且Unicode可以表示所有字符,所以并任何信息丢失)

    而在读取完后放在内存里以Unicode形式存在(即ISO字符以Unicode编码存储,而非原来ISO编码,这一过程由Java完成,但ISO的编码实质上与Unicode编码是一样的,只是编码所占字节数不一样而已),再以UTF-8编码输出时,由于这些字符在Unicode字符集编码里是存在的,那些字符实质上就是ISO字符集中的字符,所以再次证明,不会造成编码信息丢失。

    既然我们知道了是这样一过程:GBK编码文件——》以ISO8859-1来读(解码)——》以UTF-8输出(编码),那我现在还她一个眉目清秀,先以 UTF-8来读生成的Servlet类文件(解码),然后以ISO8859-1来编码(这样就回到了服务器以ISO8859-1读取JSP时的内容了),最后以GBK来解码(就回到了最原始的JSP文件了),最后...当然是现原型了(狐狸精一个啊,不过还是挺美的哦),一切显示正常,回到了过去。

 

    以下是代码实现:

String fileName = "E:/tomcat-5.5.23/work/Catalina/localhost/HttpStream/org/apache/jsp/gbk_jsp.java";
PrintWriter pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(
		"e:/tmp/gbk_jsp.java"), "UTF-8"));
BufferedReader br = new BufferedReader(new InputStreamReader(
		new FileInputStream(fileName), "utf-8"));
String readContent = null;
while ((readContent = br.readLine()) != null) {
	pw.write(new String(readContent.getBytes("iso8859-1"), "gbk") + "\r\n");
	pw.flush();
}
pw.close();

 

     结果如何,看看下面小小的截图就知道了:

http://dl2.iteye.com/upload/attachment/0016/5342/6b9b7504-75c7-3887-84e9-5e17bb41465a.gif

 

    最后总结一下思路,如果遇到乱码问题(乱码肯定是因为编码与解码不一致才导致的),先思考一下乱码原因,把编码解码的流程图画出来,按照反方向走回去就能还原文件了。

 

    思路图如下,红色为导致乱码的编码解码流程,蓝色为还原流程:

blob.png

分享到:
评论

相关推荐

    java字符编码转换详细过程

    在这个过程中,涉及到多种字符编码的转换,以确保程序能够正确地处理各种字符集,特别是中文字符。接下来,我们将详细介绍这一过程。 #### 二、编写Java源代码 在编写Java源代码的过程中,开发者通常会在特定的...

    java中文乱码解决之道(7)JSP页面编码过程Java开

    这篇"java中文乱码解决之道(7)JSP页面编码过程"的主题深入探讨了如何有效地解决这个问题,提供了宝贵的Java经验和技巧。这里我们将详细解析JSP页面编码过程中的关键点,以及如何避免和解决中文乱码。 首先,理解...

    JSP和Servlet中的几个编码的作用及原理

    ### JSP与Servlet中的编码机制详解 #### 一、引言 在Web开发中,特别是使用Java Server Pages (JSP) 和 Servlet 技术时,处理字符编码问题至关重要。不当的编码设置会导致用户界面上出现乱码,影响用户体验。本文...

    java中文乱码字符集解决大全.pdf

    - **JSP与Servlet**:在JSP中,可以使用`&lt;%@ page pageEncoding="GBK" %&gt;`指定页面编码;对于Servlet,可以在HTTP响应头中设置`Content-Type: text/html; charset=GBK`。 4. 跨平台移植和浏览器支持 Java程序需要...

    Java Web开发常见问题.pdf

    为了解决这些问题,开发者需要在各个关键环节确保使用相同的字符集,如在JSP页面、表单处理、数据库连接以及参数传递中明确指定字符编码,并尽可能选择支持多语言的编码格式,如UTF-8。此外,编写专门用于字符编码...

    java中文乱码字符集解决大全

    3. **文件存储和读取时的编码差异**:当Java程序读写文件时,如果文件的实际编码与程序读取时所假设的编码不符,也会引发乱码问题。 4. **数据库连接的编码配置问题**:在处理来自数据库的数据时,如果数据库和Java...

    字符集--Java编码相关.doc

    Java字符集与编码问题在编程实践中经常遇到,尤其是在处理中文字符时。Java系统内部以UTF-8编码进行字符串运算,但字符串的初始编码则取决于操作系统的默认编码。这意味着,如果Java程序的输入、输出以及操作系统三...

    java中文乱码字符集.pdf

    Java中的中文乱码问题主要源于字符编码的不匹配,这是由Java编程语言本身的特性以及不同操作系统和环境的差异所导致的。Java程序设计时,默认使用Unicode编码,这是一种双字节编码,可以支持世界上多种语言,包括...

    免费 java中文乱码字符集处理大全.docx

    本文深入探讨了Java编译器对Java源文件和JVM对class文件的编码/解码过程,以及Java编程中中文问题的根本原因。 首先,中文乱码的来源主要有以下几个方面: 1. 计算机操作系统通常支持单字节编码,如ASCII,而...

    解决JSP页面中文乱码问题

    2. **Web容器对JSP文件的编译**:Web容器会将JSP文件编译成Servlet类文件。编译过程中,Web容器需要根据一定的规则来识别JSP文件的编码方式。 3. **HTTP请求中的编码**:浏览器向服务器发送请求时,数据(如表单数据...

    java文件JSP文件乱码汇总

    综上所述,解决Java与JSP文件乱码问题的关键在于统一字符集设置、正确处理各种请求和响应的编码,以及确保数据库和服务器环境的编码一致。通过上述措施,可以有效避免乱码现象,提高应用程序的稳定性和兼容性。

    怎么解决JSP页面中文问题20100901

    如果没有其他指定,则JSP编译后的Servlet也会使用该编码格式来读取JSP文件。此外,还可以指定: ```jsp ;charset=UTF-8" %&gt; ``` 这一行指定了服务器返回给客户端的HTML文档的编码格式,即解码格式。当这两行都...

    java中文乱码字符集[参照].pdf

    Java中的中文乱码问题主要源于字符编码的不匹配,这是由计算机历史背景和Java本身的特性决定的。在早期,计算机系统普遍使用单字节编码,如ASCII,来处理英文字符。随着多语言需求的增加,Unicode编码应运而生,它以...

    java编码格式(对常见的java中文乱码作出分析及提出解决方案)

    Java编程中的中文乱码问题是一个常见但棘手的挑战,主要源于编码格式的不匹配和转换过程中的错误。本文深入探讨了这个问题,并提供了解决方案。 首先,我们要理解中文字符编码的历史背景。早期的计算机系统主要支持...

    JSP程序设计从入门到精通

    此外,JSP页面中的Java代码可以很容易地与后端的JavaBean和Servlet交互,形成一个强大的Web应用体系结构。 ### JSP环境安装配置 #### Tomcat下JSP环境的配置 要在Tomcat服务器下配置JSP环境,首先需要下载并安装...

    动态网页(JSP+Servlet)教程

    1. 编译: JSP 文件首先被编译成 Servlet 类。 2. 加载: 编译后的 Servlet 类被加载到内存中。 3. 执行: 客户端请求触发 Servlet 的执行,动态生成 HTML 内容。 **4.5 JSP的优点** - **内容生成与表示相分离** - ...

    JSP在Servlet中的几个编码的作用及原理 .txt

    这意味着JSP页面在编译成Servlet时会使用UTF-8编码进行源代码的读取与保存。这对于避免中文乱码至关重要,特别是在处理用户输入的数据时。 #### 2. contentType 属性 `contentType`属性主要用于设置HTTP响应的内容...

    Java中文问题及最优解决方法

    - **JDK(Java Development Kit)**:包含了编译Java源代码所需的工具和库文件,如`javac`命令用于将`.java`文件编译成`.class`文件。 - **JVM(Java Virtual Machine)**:负责执行编译后的Java字节码(`.class`...

    Java servlet过滤器配置详解

    这行代码告诉服务器此JSP页面的字符集为UTF-8,确保JSP编译后的HTML页面在浏览器中正确显示。 接下来,我们转向`web.xml`文件的配置,这是部署描述符,用来定义Servlet和过滤器的映射关系。配置`EncodingFilter`...

Global site tag (gtag.js) - Google Analytics