网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.JavaOne2003:Less hype more fi.
.如何制作Java页面计数器.
.自我参考:Java学习的30个目标.
.方便的HQL: Hibernate查询语言.
.用JIcon装饰你的界面.
.Java中得到一个字符串中每个字符.
.Eclipse入门之使用指南及开发Ecl.
.CompareMode 属性.
.分析Hibernate的事务处理机制.
.webwork入门文章.
.JDBC基础教程之ResultSet对象.
.Java中使用正则表达式验证本地化.
.hivemind, pico, spring ioc.
.使用JWSDP完成Web Service在java.
.谈谈J2ME简表.
.如何在一个系统中设计权限控制机.
.对比两个不同版本的assertEquals.
.玩转Java的CLASSPATH.
.在java中找到需要的资源文件路径.
.细说Java之util类.

分析并修补 resin 的中文处理

发表日期:2008-1-5



  分析并修补 resin 的中文处理

请留意:以下说明基于 resin-2.1.10 ,其他版本可能并不相同。

resin 小巧,快速,稳定,广泛应用于工业强度的 web 应用。通常,大家认为是中文问题较少的一个 servlet container 。通常的解决办法是这样的,在 resin.conf 中加上:

<jsp precompile=´true´ static-encoding=´true´ recompile-on-error=´true´/>此外,在页面上,要避免使用: <%@ page contentType="text/Html; charset=GBK"%> 指定字符集

应该说,这个配置能解决大部分的中文显示问题(能解决问题,但并非真正解决了问题,细节容后再叙)。直到前不久,因为在项目中应用一个 mvc 框架,中文问题才再次不可调和的浮现出来。深入代码,发现 resin 在处理中文时,其实是存在问题的。

我们来看一下“static-encoding=´true´”和“不作字符集指定”是如何让中文正常显示的。在 WEB-INF 的 work 目录下,通常可以找到 resin 根据 jsp 生成的 Java 代码。JSP中的字符串:"中文",在生成 java 文件的时候,这个字符串的转换会有这么几种情况:

static-encoding=´false´ (缺省值)(设置字符集没有影响)

_jsp_string1 = "\u00D6\u00D0\u00CE\u00C4".toCharArray();

static-encoding=´true´ (不设置字符集)

_jsp_string1 = "\u00D6\u00D0\u00CE\u00C4".getBytes();

static-encoding=´true´ (设置字符集GBK)

_jsp_string1 = "\u00D6\u00D0\u00CE\u00C4".getBytes("GBK");

我们知道,字符串"中文"在正确的转换应该是"\u4e2d\u6587"长度为2(可以运行native2ascii 输入"中文" 进行检查),在JSP处理的第一个环节,上面各种情况下生成的 Java 代码,"中文"字符串都是被错误转换的。也就是说,在 jsp 被转换成为 java 文件的时候,出现了编码错误。那么为什么,在“static-encoding=´true´ (不设置字符集)”的情况下,它能正常显示呢?

在“static-encoding=´true´ (不设置字符集)”的情况下,采用默认的ISO-8859-1编码方式,两个双字节编码的GBK中文字符被当作四个字节处理,必须注重到,此时,一个中文字符被拆为两个“字节字符”来处理,字符串的长度是错误的。在显示的时候,按照默认的ISO-8859-1方式编码返回给浏览器。此时,单字节流被浏览器自动识别,认出是GBK格式,从而可以正常显示。也就是说,此时的正常显示实际上是利用了ISO-8859-1和UNICODE相互转换时按单字节处理的特点(不进行转码处理),将错就错的实现了中文的正常显示。

我们定位了问题,是在 jsp 被转换成为 java 文件的时候出现了编码错误。那么如何使JSP中的中文能正确的生成java文件?我跟踪了 resin 的源代码,找到了一个可行,但也许不是最好的解决办法。

JspParser.java of resin-2.1.10

///// added by jackyz private static String sysEncoding = System.getProperty("file.encoding"); Page parse(Path path, String uri, String className, String uriPwd, CaUChoRequest req, CauchoApplication app) throws Exception { ReadStream stream = path.openRead(); ///// added by jackyz stream.setEncoding(sysEncoding); try { return parse(stream, uri, className, uriPwd, path.getParent(), req, app); } catch (FileNotFoundException e) { throw e; } catch (IOException e) { if (path.isDirectory()) throw new FileNotFoundException(path.toString()); else throw e; } finally { stream.close(); } }


上一篇:分享Swing学习的一些经验 人气:796
下一篇:刚运行了 Azureus ,给我的感觉是这界面真不象是Java 写的,发誓看完这套代码! 人气:687
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐