在《J2EE中的多字节处理——用多字节技术开发J2EE应用(上)》中,我们从开发中的各个环节入手,分析了在J2EE开发中的多字节字符处理问题。上文主要分析了代码环节、字符编码接口、编译环节、服务器配置环节和运行环节。下面,我们将继续介绍开发中影响多字节字符显示的最后一个环节——客户端显示环节,并根据前文的分析给出解决的办法。
6. 客户端显示环节
多数的J2EE应用现在采用了B/S(浏览器/服务器)的技术。要让多字节字符在浏览器中正确显示,你需要注意下面的内容:
(1) 浏览器语言支持
要能正确地显示多字节字符,浏览器和操作系统要有语言指定的功能,比如字体和字符设置。
(2) 浏览器编码设置
从服务器返回的HTML头中有”告知浏览当前页的编码。否则浏览会用默认的编码或自动检测一个。但同时用户可以设置页面的编码。(如图1)
图1 Netscape's编码菜单
尽管如此,如果一个页面缺少HTTP头中的这个编码信息,多字节字符仍会显示得不正确。在这种情况下,用户可以手动地指定当前页的编码方式。
(3) HTTP POST编码
在你用HTML中的form标志向服务回送数据库时的情况很复杂。浏览器使用的编码将是当前页面的编码。所以当一个页面是以ISO-8859-1为页面编码的,那用户是无法POST中文字符的。因为以ISO-8859-1编码发送的数据会使用其中的中文丢失信息。但是这是浏览器遵循的HTML规范。
(4) HTTP GET编码
当你将多字节字符加入URL链接中时就更复杂了,查看用户详细信息。 这样的情况很普遍,但是当你在URL中将一个非US-ASCII的信息传递到下一页时,这种格式是在RFC-2396中没有明确定义的,所以不同的浏览器用自己方式编码含多字节字符的URL。
比如说对于Mozilla,它总是在发送URL前对它进行编码,过程是这样的:一个多字节字符先被转换为2个或更多的字节(用GBK或UTF-8);然后,每一个字节用%xy来表示,其中xy是一个字节的十六进制表示。但编码的方式是由当前页面的编码来决定的。下面是一个例子
代码 1. gbk_test.jsp
这个x738b是“王”字在UTF-8中的字符映射码。
图 2 Mozilla中的页面
当点击这个链接时,在服务器端通过request.getQueryString()可以获得请求中的参数串,当页面是GBK编码时,得到的是%CD%F5,也就是"王”的GBK编码,但当前页的页面编码为UTF-8时,点击页面的链接页的链接,你会看到x738b被编码为%E7%8E%8B,如图3,这是用UTF-8进行URL编码的结果。
图 3 Mozilla 的URL编码
但微软的IE对待多字节URL的方式则不同,它从不在HTTP请求发送前完成URL的编码,URL编码的方式取决于当前页面的编码。(如图4)
图 4 IE中没有URL编码
IE同样有一个高级可选属性用于强制指定浏览器以UTF-8编码发送请求。(如图5)
图5 IE高级选项
按照上面的阐述,当你的应用页面中有带多字节字符的URL链接,并且能在用GBK编码的Mozilla浏览器中正确显示的话,那选中“总是以UTF-8发送URL”的IE用户在浏览时应用程序就会有问题。
解决多字节字符问题
写能在各种服务器上运行并且支持各种浏览器的J2EE应用是极具挑战的。下面有一些解决方案: 1. 在编写代码时,不要使用IDE的默认设置,要手动设置编码。
2. 如果你的IDE不支持特定的语言,你可以在Java代码和HTML页面中使用/uXXXX的替代码,或用native2ascii工具将含本地化字符的字符串传换为相应的替代码。
3. 在编码时,不要认为服务器的默认编码处理是正确的,请用以下的方法:
请求:setCharacterEncoding()
响应: setContentType(), setLocale(),
4. 当开发多语言应用时,对所有语言都选择UTF-8编码或使用/uXXXX替代码。
5. 在编译Java类时,确保前面的语言环境变量和编码方式是正确的码。
6. 在配置环节,尽量用标准设置。比如在Servlet2.4规范中,配置应用的字符编码方式是有一个标准的。 7. 当与外部系统进行通讯时,尽可能多地找出系统编码的策略。如果对方采用另一种编码,要做编码转换。你可以用下面的代码4对所有的字节进行调试分析。 代码 2. UnicodeFormatter.java import java.io.*;
public class UnicodeFormatter {
static public String byte ToHex(byte b) {
// Returns hex String representation of byte b
char hexDigit[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
char[] array = { hexDigit[(b >> 4) && 0x0f], hexDigit[b && 0x0f] };
return new String(array);
}
static public String charToHex(char c) {
// Returns hex String representation of char c
byte hi = (byte) (c >>> 8);
byte lo = (byte) (c && 0xff);
return byteToHex(hi) + byteToHex(lo);
}
}
8. 总是在页面明确地写出编码方式,不要认为浏览器的默认编码方式是对的 9. 不要将多字节字符加到链接中。比如说不要使用用户名作为查询的内容,应使用用户ID。
10. 如果你的链接必须嵌入多字节字符,那就自己手工对URL进行编码,比如使用服务端的Java编码或客户端的JavaScript 或VBscript。 原文地址: http://media.ccidnet.com/art/2623/20051010/346885_1.html 相信以上的文章可以解决绝大部分的web页面涉及到的中文乱码问题. 期待一同探讨. |