Java Servlet作者/Jsp多语言解决方案:vividq 本周末,我研究了Servletttet,因为我一直不相信Java会有不能混排显示多种语言的BUG。、 Jsp的多国语言显示的问题,即Servlet的多字符集,因为我对字符集的概念仍然存在 因为不太清楚,所以写出来的东西不一定准确,我是这样理解Java中的字符集的:运行时 ,存储在每个字符串对象中的代码是UNICODE内码(我认为所有的语言都是相应的 编码,因为计算机内部字符串总是用内码表示,但一般计算机语言中的单词 平台与符串编码相关,Java采用UNICODE与平台无关)。 Java从byte流中读取字符串时,将与平台相关的byte转换为与平台无关的Un icode字符串。
当Java从byte流读取一个字符串时,它会将与平台相关的byte转换为与平台无关的Un。 icode字符串。在输出时,Java将Unicode字符串转换为平台相关的byte流,如果Unicode字符串 icode字符在某个平台上不存在,将输出一个'。例如:在中文Windows中,Jav 读取“GB2312”编码的文件(可以是任何流动)到内存构建字符串对象,将GB2 312编码的文本转换为Unicode编码的字符串,如果这个字符串输出,Unicode字将再次被输出 将符串转换为GB2312的byte流或数组:“中文测试”----->"\u4e2d\u6587\u6d4b\u8bd5"-- --->"中文测试"。 如下例程: byte[] bytes = new byte[]{(byte)0xd6, (byte)0xd0, (byte)0xce, (byte)0xc4, (b yte)0xb2, (byte)0xe2, (byte)0xca, (byte)0xd4};“中文测试”///GBK编码 java.io.ByteArrayInputStream bin = new java.io.ByteArrayInputStream(bytes); java.io.BufferedReader reader = new java.io.BufferedReader(new java.io. Inpu tStreamReader (bin,"GBK")); String msg = reader.readLine(); System.out.println(msg)
这个程序可以在包含“中文测试”四个字的系统(如中文系统)中正确打印 出这些字。Unicode编码在msg字符串中包含正确的“中文测试”:“\u4e2d\u6587\u6d4 b打印时转换为操作系统的默认字符集,能否正确显示依赖操作系统的字符集 只有在支持相应字符集的系统中,我们的信息才能正确输出,否则我们将得到它 会是垃圾。 让我们来看看Servlet/Jsp中的多语言问题。
让我们来看看Servlet/JSP中的多语言问题。我们的目标是任何国家的客人 通过Form将信息发送给Server,Server将信息存储在数据库中,客户端在检索时仍然可以 足以看到你发送的正确信息。实际上,我们必须保证,当Server中的SQL句子最终被保存下来时 正确的Unicode编码包括客户端发送的文本;DBC和数据库通信中使用的编码方法可以包含客户 事实上,JDBC最好直接使用UNICODE/UTF8与数据库通信户端发送的文本信息!这样 可以保证信息不会丢失;当Server向客户端发送信息时,也应使用不丢失信息的编码方 也可以是Unicode/UTF8。
如果Form的Enctype属性没有指定,Form将按照当前页面的编码字符集输入内容 然后提交rlencode,服务器端得到urlencoding字符串。Urlencodi是通过编码获得的 ng字符串与页面编码有关,如提交“中文测试”的gb2312编码页面,获得“%D6” %D0%CE%C4%B2%E2%CA%D4",每个"%“后跟是16进制的字符串;UTF8编码时得到的 但是“%E4%B8%”AD%E6%96%87%E6%B5%8B%AF%因为GB2312编码中的一个汉字是16位的 ,UTF8中的一个汉字是24位。中国、日本和韩国的ie4以上浏览器都支持UTF8编码,这种方形 这个案子一定包含了这三种语言,所以如果我们让HTML页面使用UTF8编码,至少可以支持 三国语言。
但是,如果我们使用UTF8编码html/Jsp页面,应用程序服务器可能不知道这一点 情况,因为如果浏览器发送的信息不包括charset信息,server最多知道阅读acceptt-La nguage要求投标,我们知道浏览器使用的编码是不可能仅仅通过这个投标来获得的,所以应用程 为什么序列服务器不能正确分析提交的内容?因为Java中的所有字符串都是Unicode16位 编码的,HttpServletRequest.request(String)其功能是编辑客户端提交的Urlencode 代码信息转换为Unicode字符串,一些Server只能认为客户端的代码与Server平台相同,简 单独使用URLDecoder.decode(String)如果客户端代码与Server正好相同,则直接解码该方法 ,然后你可以得到正确的字符串,否则,如果提交的字符串包含当地字符,那么 会导致垃圾信息。
在我提出的解决方案中,UTF8编码已经被指定,因此可以避免这个问题 ,我们可以自己定制decode方法: public static String decode(String s,String encoding) throws Exception { StringBuffer sb = new StringBuffer(); for(int i=0; i
如果将其指定为UTF8,则可以指定encoding,以满足我们的需要。比如用它 分析:“%E4%B8%AD%E6%96%87%E6%B5%8B%AF%95“可以得到正确的汉字“中文测试” Unicode字符串。比如用它 分析:“%E4%B8%AD%E6%96%87%E6%B5%8%E8%AF%95“可以得到正确的汉字“中文测试” Unicode字符串。 现在的问题是,我们必须得到客户端提交的Urlencode字符串。fot,method为get。 可以使用Httpservletrequestt提交的信息.getQueryString()读取方法,但对于post方法 法律的form提交的信息只能从Servletinputstream中读取,事实上,标准的getparameter 第一次调用方法后,form提交的信息被读取,而ServletinputStream不能 重复读出。因此,在第一次使用getparameter方法之前,我们应该阅读和分析form提交的信息 。
我就是这么做的,建立一个覆盖service方法的service基类,调用父类service方法 对form提交的内容进行法前阅读和分析,请参见以下源代码: package com.hto.servlet; import javax.servlet.http.HttpServletRequest; import java.util.*; /** * Insert the type's description here. * Creation date: (2001-2-4 15:43:46) * @author: 钱卫春 */ public class UTF8ParameterReader { Hashtable pairs = new Hashtable(); /** * UTF8ParameterReader constructor comment. */ public UTF8ParameterReader(HttpServletRequest request) throws java.io.IOExce ption{ super(); parse(request.getQueryString()); parse(request.getReader().readLine()); } /** * UTF8ParameterReader constructor comment. */ public UTF8ParameterReader(HttpServletRequest request,String encoding) throw s java.io.IOException{ super(); parse(request.getQueryString(),encoding); parse(request.getReader().readLine(),encoding); } public static String decode(String s) throws Exception { StringBuffer sb = new StringBuffer(); for(int i=0; i
剩下的就是输出问题。我们需要将输出信息转换为UTF8的二进制流输出。只要我 在设置Content-Type时,将charset指定为UTF8,然后使用PrintWriter输出 是自动进行的,这样设置Servlet: response.setContentType("text/html;charset=UTF8"); 在Jsp中这样设置: <%@ page contentType="text/html;charset=UTF8"%> 这样可以保证输出是UTF8流,能否显示客户端取决于客户端。 multipart/form-我还提供了一个类别来处理dataform提交的内容 Charset可以在构造子中指定页面使用,默认为UTF-8,仅限于长度不发布源代码,如果 对mail感兴趣 to:[emailprotected]和我探讨。
![](/images/780-200-2.jpg)