浏览器测试
现在我们看到由于识别被UTF-16编码过的JSP标签失败,JSP不能支持UTF-16编码的文字字符,而servlets却没有这个问题。
且慢!为使测试更能说明问题,我们在测试代码中加入POST功能,让用户通过HTML的Form标签提交UTF-16编码的字符。从本文的资源一节中下载下面的示例程序:servlet PostForm.java和servlet ByteTest.java。Servlet PostForm.java用来输出一个用UTF-16编码的页面,它有一个用来向服务器提交数据的表单。
在ByteTest.java里,由于不能确定服务器是否配置为UTF-16编码方式,我没有用request.getParameter()方法显示浏览器提交的数据,而改用request.getInputStream()方法从请求中提取原始数据,然后打印从浏览器得到的每一个字节。
清单5
PostForm.java
public class PostForm extends HttpServlet
{
....
protected void processRequest
(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html;
charset=UTF-16");
PrintWriter out = response.getWriter();
out.println("<html><head>");
out.println("<meta content="text/html;
charset=UTF-16\" http-equiv="content-type\">"); out.println("</head><body>");
out.println("<form action=\"servlet/ByteTest\"
method=\"POST\">");
out.println("<input type=\"text\"
name=\"name\"><input type=\"submit\">"); out.println("</form></body></html>");
out.close();
}
....
} |
清单6
ByteTest.java
public class ByteTest extends HttpServlet
{
...
protected void processRequest
(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,
IOException
{
ServletInputStream in =
request.getInputStream();
response.setContentType("text/html");
PrintWriter out = response.getWriter();
byte[] postdata = new byte[50];
int size = in.read(postdata,0,50);
in.close();
out.println("<html>");
out.println("<head>");
out.println("<title>Servlet</title>");
out.println("</head>");
out.println("<body>");
printBytes(out,postdata, size,
"postdata");
out.println("</body>");
out.println("</html>");
out.close(); }...} |
在运行过程中PostForm页面显然会用UTF-16编码,而ByteTest的输出结果又会是什么呢?
· IE:尽管页面是用UTF-16编码的,浏览器对所有输入的字符都采用UTF-8编码。
· Mozilla:无论在这个UTF-16编码的页面里输入什么字符,只有“=”这个字符能显示出来,这个运行结果显然是错误的。
结论
J2EE应用只能在以下条件下使用UTF-16编码:
· 只用于servlet编程
· 浏览器只限制于用IE
· 虽然浏览器端的页面用UTF-16编码,在服务器端要用UTF-8解码
实际上,在J2EE应用中使用UTF-8编码并不困难。在Unicode3.1标准中,UTF-8编码与UTF-16编码能处理的字符数目是一样的,只是在存储和处理效率方面有差异。
结束语
由此可见,如果J2EE应用遇到了多字节字符问题,你一定要深入到开发生命周期的各个阶段,检查服务器和客户端的配置情况,并借助调试工具,这样才能找出问题的根源所在。