JSP/Servlet中的编码相关设置

在JSP和Servlet中有几个地方都可以设置编码,各个编码的功能也不一样,本文将对各个编码做一个小结。

 


各种编码一览

A. JSP/Servlet都有的编码设置

1. request.setCharacterEncoding("UTF-8")

2. response.setCharacterEncoding("UTF-8")

3. response.setContentType("text/html; charset=UTF-8");

4. response.setHeader("Content-Type", "text/html; charset=UTF-8");

B. JSP专有的编码设置

1. <%@ page pageEncoding="UTF-8" %>

2. <%@ page contentType="text/html; charset=UTF-8" %>

C. HTML页面中的编码设置

1.

 

※以下内容用到本部分编码设置时,将使用A1, A3, B2的方式。



 

浏览器如何确定编码格式来显示页面

web服务器在接收到浏览器的请求信息后,经过处理,会发送一个应答消息给浏览器。应答消息包含一般三个部分:状态行,应答首部,应答主体。下面是一个示例:

HTTP/1.0 200 OK
Last-Modified: Mon: 20 Dec 2001 23:26:42 GET
Date: Tue 11 Jan 2002 20:52:40 GMT
Status: 200
Content-Type: text/html; charset=UTF-8
Servlet-Engine: Tomcat Web Server/4.0.1
Content-Length: 59

Hello World!

 

其中,第一行是状态行,最后的一部分是应答主体,而中间的部分就是应答首部了。而应答主体部分的Content-Type中的charset就指定了浏览器应该采用什么编码格式来显示页面。如果没有指定charset的话,浏览器会根据C1(meta中的charset)来显示页面;如果C1也没有的话,就采用本地默认的编码格式显示页面(应该与客户端的操作系统有关)

★浏览器显示页面所用的格式可以通过菜单 -> 查看 -> 编码来查看具体是哪种编码格式



web服务器如何决定编码

从上面可以知道,服务器在发送给客户端的应答主体中一般会包含charset。而这个charset的值有几个来源,我们从高优先级到低优先级排列。

注:下面的结论是采用Tomcat 5.5确认的结论,不一定全部适用于其他服务器。

1. A2, A3, A4

如果你的JSP或者Servlet中包含以上3中类型的代码,那么charset就是它们。如果有多条语句设置,那么charset就是最后一条所设置的值。

2. B2

B2的代码在编译成class文件时会自动转换为A3,但是是位于所有代码的最前面部分。所以,如果JSP中包含A2, A3, A4的代码,B2就不会再起作用,如果没有的话,那么值就是B2所设定的charset的值。

3. B1

如果1和2都不存在的话,B1的值就会被采用。

4. web服务器默认值

一般是ISO-8859-1



JSP的编译过程

JSP在被访问时,需要编译成Java的bytecode才会被执行,而这个编译过程是分两步进行的。第一 步是:JSP -> Java文件的转换过程,第二步是Java -> class文件的编译过程。

其中,第一步的JSP -> Java文件的转换过程,就会使用B1和B2的两部分内容。web服务器会根据B1的pageEncoding的设置来读取jsp文件,并且把它转换为以 UTF-8格式编码的java文件。如果JSP中有汉字,而pageEncoding设置的是ISO-8859-1,或者没有设置的话,出来的java文 件中就会有乱码。至于B2呢,web服务器会把它转换为A3一样的代码,并且把它放在代码的最前面部分。

而第二步就是普通的Java文件的 编译过程,javac使用UTF-8格式读取java文件,再编译成UTF-8格式的class文件。

 

★用 过MyEclipse写JSP的可能就知道,如果你的pageEncoding设置的值与JSP文件本身的编码格式不一致的话,MyEclipse会报 错,并且无法保存成功。它这样做就可以保证你写在JSP中的文字一定能被正确解析,因为你肯定敲一堆乱码出来给自己看的。


 

其他相关知识

★上面的内容基本上都是关于页面输出时的编码,而没有输入时的编码说明,因为不是本文的重点,所以只在这里稍微补充以下。页面输入的编码主要是指用户在页面上输入一些内容,然后发送到服务器端,服务器端要采用某种编码方式来解码用户的请求。这个部分根据用户请求的类型(POST/GET)不同有不同的处理方式。

对于POST方式来说,因为客户端请求前一张页面时,就已经得到Web服务器设置的编码格式,此时用户以POST方式发送请求时,所有的数据将自动采用当前页面设置的编码格式编码。那么,服务器端只要用同样的编码格式解码就可以了。如,使用A1是可行的一种方法。

对于GET方式来说,客户端在请求时是没有使用编码格式的,Web服务器将采用默认的编码格式解码。如Tomcat 5.0中默认采用ISO-8859-1编码格式。如果需要配置成其他格式,需要修改Tomcat的配置文件中的Connector tag中的useBodyEncodingForURI或者URIEncoding。

不过在J2EE系统中,类似于A1这样的代码一般不会写在JSP/Servlet中,而是使用一个Filter类来实现。


★我们可以写java代码访问某JSP或者Servlet来查看具体的应答消息内容。

url = new URL("http://localhost:8080/Encoding/page/test.jsp");
URLConnection urlConn = url.openConnection();
System.out.println(urlConn.getHeaderFields());

输出地结果就是类似于下面这样的信息:

{Content-Length=[265], Set-Cookie=[JSESSIONID=367DB3A663B8F6B0D84C6EF3FDB1BF43; Path=/Encoding], null=[HTTP/1.1 200 OK], Date=[Sat, 06 Mar 2010 09:01:27 GMT], Server=[Apache-Coyote/1.1], Content-Type=[text/html;charset=UTF-8]}

 


 

参考资料

1. http://hi.baidu.com/evenbill/blog/item/46b90f62c955dd680d33fa48.html

2. http://wasiker.javaeye.com/blog/255062

3. http://blog.csdn.net/Jermaine/archive/2009/06/09/4255809.aspx

4. http://www.ibm.com/developerworks/cn/web/wa-lo-utf8/index.html

 

你可能感兴趣的:(Web开发,java)