Y
Yakuu
Unregistered / Unconfirmed
GUEST, unregistred user!
1、常见的 encoding 问题的现象
网上常出现的 JSP/Servlet encoding 问题一般都表现在 browser 或应用程序端,如:
1)浏览器中看到的 Jsp/Servlet 页面中的汉字都成了’?’
2)浏览器中看到的 Servlet 页面中的汉字都成了乱码
3)JAVA 应用程序界面中的汉字都成了方块
4)Jsp/Servlet 页面无法显示 GBK 汉字。
5)JSP 页面中内嵌在<%...%>,<%=...%>等Tag包含的 JAVA code 中的中文成了乱码,但页面的其它汉字是对的。
6)Jsp/Servlet 不能接收 form 提交的汉字。
7)JSP/Servlet 数据库读写无法获得正确的内容。
隐藏在这些问题后面的是各种错误的字符转换和处理(除第3个外,是因为 Java font 设置错误引起的)。
解决类似的字符 encoding 问题,需要了解 Jsp/Servlet 的运行过程,检查可能出现问题的各个编码方式。
2、JSP/Servlet web 编程时的 encoding具体分析
其中有字符编码转换的地方有:
1、JSP 编译。
Java 应用服务器将根据 JVM 的 file.encoding 值读取 JSP 源文件,编译生成 JAVA 源文件,
再根据 file.encoding 值写回文件系统。如果当前系统语言支持 GBK,那么这时候不会出现 encoding 问题。
如果是英文的系统,如 LANG 是 en_US 的 Linux, AIX 或 Solaris,则要将 JVM 的 file.encoding 值置成 GBK 。
系统语言如果是 GB2312,则根据需要,确定要不要设置 file.encoding,将 file.encoding 设为 GBK 可以解决潜在的 GBK 字符乱码问题。
2、Java 需要被编译为 .class 才能在 JVM 中执行。
这个过程存在与a.同样的file.encoding 问题。从这里开始 servlet 和 jsp 的运行就类似了,只不过 Servlet 的编译不是自动进行的。
对于JSP程序, 对产生的JAVA 中间文件的编译是自动进行的(在程序中直接调用sun.tools.javac.Main类). 因此如果在这一步出现问题的话,
也要检查encoding和OS的语言环境,或者将内嵌在JSP JAVA Code 中的静态汉字转为 Unicode, 要么静态文本输出不要放在 JAVA code 中。
对于Servlet, javac 编译时手工指定-encoding 参数就可以了。
3、Servlet 需要将 HTML 页面内容转换为 browser 可接受的 encoding 内容发送出去。
依赖于各 JAVA App Server 的实现方式,有的将查询 Browser 的 accept-charset 和 accept-language 参数或以其它猜的方式确定 encoding 值,有的则不管。
因此采用固定encoding 也许是最好的解决方法。对于中文网页,可在 JSP 或 Servlet 中设置 contentType="text/html;
charset=GB2312";
如果页面中有GBK字符,则设置为contentType="text/html;
charset=GBK",由于IE 和 Netscape对GBK的支持程度不一样,作这种设置时需要测试一下。
因为16位 JAVA char在网络传送时高8位会被丢弃,也为了确保Servlet页面中的汉字(包括内嵌的和servlet运行过程中得到的)是期望的内码,
可以用 PrintWriter out = res.getWriter() 取代 ServletOutputStream out = res.getOutputStream()。
PrinterWriter 将根据contentType中指定的charset作转换 (ContentType需在此之前指定!);也
可以用OutputStreamWriter封装 ServletOutputStream 类并用write(String)输出汉字字符串。
对于 JSP,JAVA Application Server 应当能够确保在这个阶段将嵌入的汉字正确传送出去。这是解释 URL 字符 encoding 问题。
4、如果通过 get/post 方式从 browser 返回的参数值中包含汉字信息, servlet 将无法得到正确的值。
SUN的 J2SDK 中,HttpUtils.parseName 在解析参数时根本没有考虑 browser 的语言设置,而是将得到的值按 byte 方式解析。
这是网上讨论得最多的 encoding 问题。因为这是设计缺陷,只能以 bin 方式重新解析得到的字符串;
或者以 hack HttpUtils 类的方式解决。不过最好将其中的中文 encoding GB2312、 CP1381 都改为 GBK,
否则遇到 GBK 汉字时,还是会有问题。
这里面有摘抄,有我的一点心得,希望对大家有帮助。
为支持大富翁的发展,以后会定期发些帖子。不要笑话。呵呵
网上常出现的 JSP/Servlet encoding 问题一般都表现在 browser 或应用程序端,如:
1)浏览器中看到的 Jsp/Servlet 页面中的汉字都成了’?’
2)浏览器中看到的 Servlet 页面中的汉字都成了乱码
3)JAVA 应用程序界面中的汉字都成了方块
4)Jsp/Servlet 页面无法显示 GBK 汉字。
5)JSP 页面中内嵌在<%...%>,<%=...%>等Tag包含的 JAVA code 中的中文成了乱码,但页面的其它汉字是对的。
6)Jsp/Servlet 不能接收 form 提交的汉字。
7)JSP/Servlet 数据库读写无法获得正确的内容。
隐藏在这些问题后面的是各种错误的字符转换和处理(除第3个外,是因为 Java font 设置错误引起的)。
解决类似的字符 encoding 问题,需要了解 Jsp/Servlet 的运行过程,检查可能出现问题的各个编码方式。
2、JSP/Servlet web 编程时的 encoding具体分析
其中有字符编码转换的地方有:
1、JSP 编译。
Java 应用服务器将根据 JVM 的 file.encoding 值读取 JSP 源文件,编译生成 JAVA 源文件,
再根据 file.encoding 值写回文件系统。如果当前系统语言支持 GBK,那么这时候不会出现 encoding 问题。
如果是英文的系统,如 LANG 是 en_US 的 Linux, AIX 或 Solaris,则要将 JVM 的 file.encoding 值置成 GBK 。
系统语言如果是 GB2312,则根据需要,确定要不要设置 file.encoding,将 file.encoding 设为 GBK 可以解决潜在的 GBK 字符乱码问题。
2、Java 需要被编译为 .class 才能在 JVM 中执行。
这个过程存在与a.同样的file.encoding 问题。从这里开始 servlet 和 jsp 的运行就类似了,只不过 Servlet 的编译不是自动进行的。
对于JSP程序, 对产生的JAVA 中间文件的编译是自动进行的(在程序中直接调用sun.tools.javac.Main类). 因此如果在这一步出现问题的话,
也要检查encoding和OS的语言环境,或者将内嵌在JSP JAVA Code 中的静态汉字转为 Unicode, 要么静态文本输出不要放在 JAVA code 中。
对于Servlet, javac 编译时手工指定-encoding 参数就可以了。
3、Servlet 需要将 HTML 页面内容转换为 browser 可接受的 encoding 内容发送出去。
依赖于各 JAVA App Server 的实现方式,有的将查询 Browser 的 accept-charset 和 accept-language 参数或以其它猜的方式确定 encoding 值,有的则不管。
因此采用固定encoding 也许是最好的解决方法。对于中文网页,可在 JSP 或 Servlet 中设置 contentType="text/html;
charset=GB2312";
如果页面中有GBK字符,则设置为contentType="text/html;
charset=GBK",由于IE 和 Netscape对GBK的支持程度不一样,作这种设置时需要测试一下。
因为16位 JAVA char在网络传送时高8位会被丢弃,也为了确保Servlet页面中的汉字(包括内嵌的和servlet运行过程中得到的)是期望的内码,
可以用 PrintWriter out = res.getWriter() 取代 ServletOutputStream out = res.getOutputStream()。
PrinterWriter 将根据contentType中指定的charset作转换 (ContentType需在此之前指定!);也
可以用OutputStreamWriter封装 ServletOutputStream 类并用write(String)输出汉字字符串。
对于 JSP,JAVA Application Server 应当能够确保在这个阶段将嵌入的汉字正确传送出去。这是解释 URL 字符 encoding 问题。
4、如果通过 get/post 方式从 browser 返回的参数值中包含汉字信息, servlet 将无法得到正确的值。
SUN的 J2SDK 中,HttpUtils.parseName 在解析参数时根本没有考虑 browser 的语言设置,而是将得到的值按 byte 方式解析。
这是网上讨论得最多的 encoding 问题。因为这是设计缺陷,只能以 bin 方式重新解析得到的字符串;
或者以 hack HttpUtils 类的方式解决。不过最好将其中的中文 encoding GB2312、 CP1381 都改为 GBK,
否则遇到 GBK 汉字时,还是会有问题。
这里面有摘抄,有我的一点心得,希望对大家有帮助。
为支持大富翁的发展,以后会定期发些帖子。不要笑话。呵呵