??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲中文字幕无码爆乳av中文,亚洲高清视频免费,亚洲国产成人久久综合http://www.tkk7.com/renyangok/category/17020.htmlzh-cnWed, 01 Aug 2007 10:38:01 GMTWed, 01 Aug 2007 10:38:01 GMT60英文变ؕ?WindowsC本再度“闹鬼?/title><link>http://www.tkk7.com/renyangok/archive/2007/08/01/133806.html</link><dc:creator>保尔?/dc:creator><author>保尔?/author><pubDate>Wed, 01 Aug 2007 06:59:00 GMT</pubDate><guid>http://www.tkk7.com/renyangok/archive/2007/08/01/133806.html</guid><wfw:comment>http://www.tkk7.com/renyangok/comments/133806.html</wfw:comment><comments>http://www.tkk7.com/renyangok/archive/2007/08/01/133806.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/renyangok/comments/commentRss/133806.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/renyangok/services/trackbacks/133806.html</trackback:ping><description><![CDATA[<div>q记?a target="_blank"><font color="#0000cc"><strong>Windows</strong></font></a>C本程序与“联?#8221;之间?#8220;闚w事g”么?现在又有人发CcM的现象,q次C本连英文也不认识了?/div> <div>Wincustomise提供的方法如下:<!-- 正文늽Md? --><br><br>1、打开Windowspȝ中的C本程?不是写字板也不是Word)?/div> <div>2、输?#8220;this <a target="_blank"><font color="#0000cc"><strong>ap</strong></font></a>p <a target="_blank"><font color="#0000cc"><strong>ca</strong></font></a>n break”(不含引号)?/div> <div>3、以L文g名将其保存到<a target="_blank"><font color="#0000cc"><strong>盘</strong></font></a>上?/div> <div>4、关闭记事本?/div> <div>5、再ơ用记事本打开保存的文档?/div> <div>怎么P看到的还是英文么Q怎么成了q了?</div> <div>其实Q和此前“联?#8221;?#8220;黑色实心方块”一PC本如?#8220;闚w”都是Z同一bug。默认情况下Q记事本是以ANSI~码保存文本文档的,? 是这U编码导致了上述怪现象。如果选择Unicode、Unicode(big endian)、UTF-8~码保存正怺。此外,如果以ANSI~码保存含有某些Ҏ(gu)W号的文本文档,再次打开后符号也会变成英文问受?/div> <div><br>                                <img src="http://news1.mydrivers.com/pages/images/20060615163230_80118.jpg" alt="bug,C? border="0"><br>                                                                英文变ؕ?br><br>                                <img src="http://news1.mydrivers.com/pages/images/20060615163233_30084.jpg" alt="bug,C? border="0"><br>                                                                 联通变方块<br><br>              <img src="http://news1.mydrivers.com/pages/images/20060615163235_66785.jpg" alt="bug,C? border="0"><br>                                                               都是~码惹的?/div><img src ="http://www.tkk7.com/renyangok/aggbug/133806.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/renyangok/" target="_blank">保尔?/a> 2007-08-01 14:59 <a href="http://www.tkk7.com/renyangok/archive/2007/08/01/133806.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unicode,ANSI,UTF-8的故事(转)http://www.tkk7.com/renyangok/archive/2007/07/31/133666.html保尔?/dc:creator>保尔?/author>Tue, 31 Jul 2007 14:35:00 GMThttp://www.tkk7.com/renyangok/archive/2007/07/31/133666.htmlhttp://www.tkk7.com/renyangok/comments/133666.htmlhttp://www.tkk7.com/renyangok/archive/2007/07/31/133666.html#Feedback0http://www.tkk7.com/renyangok/comments/commentRss/133666.htmlhttp://www.tkk7.com/renyangok/services/trackbacks/133666.html 

很久很久以前Q有一hQ他们决定用8个可以开合的晶体来l合成不同的状态,
以表CZ界上的万物。他们看?个开关状态是好的Q于是他们把q称?字节"?
再后来,他们又做了一些可以处理这些字节的机器Q机器开动了Q可以用字节来组
合出很多状态,状态开始变来变厅R他们看到这h好的Q于是它们就q机器称?
计算??

开始计机只在国用。八位的字节一共可以组合出256(2?ơ方)U不同的状态?
他们把其中的~号?开始的32U状态分别规定了Ҏ(gu)的用途,一但终端、打印机?br>上约定好的这些字节被传过来时Q就要做一些约定的动作。遇?0x10, l端换行,
遇上0x07, l端向Z嘟嘟叫,例好遇上0x1b, 打印机就打印反白的字Q或者终端就
用彩色显C字母。他们看到这样很好,于是把q些0x20以下的字节状态称?控制??

他们又把所有的I格、标点符受数字、大写字母分别用连l的字节状态表C,
一直编CW?27Pq样计算机就可以用不同字节来存储p的文字了。大家看?br>q样Q都感觉很好Q于是大安把这个方案叫?ANSI ?Ascii"~码QAmerican
Standard Code for Information InterchangeQ美国信息互换标准代码)?br>当时世界上所有的计算机都用同LASCIIҎ(gu)来保存英文文字?

后来Q就像徏造巴比u塔一P世界各地的都开始用计机Q但是很多国家用?br>不是英文Q他们的字母里有许多是ASCII里没有的Qؓ了可以在计算Z存他们的?br>字,他们军_采用127号之后的IZ来表C些新的字母、符Pq加入了很多画表
格时需要用下到的横Uѝ竖Uѝ交叉等形状Q一直把序号~到了最后一个状?55?br>?28?55q一늚字符集被U?扩展字符?。从此之后,贪婪的hcd没有新的?br>态可以用了,帝国主义可能没有想到还有第三世界国家的Z也希望可以用到计机吧!
 
{中国h们得到计机Ӟ已经没有可以利用的字节状态来表示汉字Q况且有6000
多个常用汉字需要保存呢。但是这难不倒智慧的中国人民Q我们不客气地把那些127
号之后的奇异W号们直接取消掉, 规定Q一个小?27的字W的意义与原来相同,?br>两个大于127的字W连在一hQ就表示一个汉字,前面的一个字节(他称之ؓ高字
节)?xA1用到0xF7Q后面一个字节(低字节)?xA1?xFEQ这h们就可以l?br>合出大约7000多个体汉字了。在q些~码里,我们q把数学W号、罗马希腊的?br>母、日文的假名们都~进MQ连?ASCII 里本来就有的数字、标炏V字母都l统?br>新编了两个字节长的编码,q就是常说的"全角"字符Q而原来在127号以下的那些?br>?半角"字符了?

中国人民看到q样很不错,于是把q种汉字Ҏ(gu)叫做 "GB2312"。GB2312 是对
ASCII 的中文扩展。但是中国的汉字太多了,我们很快就发现有许多h的h名没?br>办法在这里打出来Q特别是某些很会ȝ别h的国安gh。于是我们不得不l箋
?GB2312 没有用到的码位找出来老实不客气地用上?

后来q是不够用,于是q脆不再要求低字节一定是127号之后的内码Q只要第一个字
节是大于127固定表C是一个汉字的开始,不管后面跟的是不是扩展字W集里的
内容。结果扩展之后的~码Ҏ(gu)被称?GBK 标准QGBK 包括?GB2312 的所有内?br>Q同时又增加了近20000个新的汉字(包括J体字)和符受?br> 
后来数民族也要用电脑了Q于是我们再扩展Q又加了几千个新的少数民族的字,
GBK 扩成?GB18030。从此之后,中华民族的文化就可以在计机时代中传承了?
中国的程序员们看到这一pd汉字~码的标准是好的Q于是通称他们叫做 "DBCS"
QDouble Byte Charecter Set 双字节字W集Q。在DBCSpd标准里,最大的特点是两?br>节长的汉字字W和一字节长的英文字符q存于同一套编码方案里Q因此他们写的程
序ؓ了支持中文处理,必须要注意字串里的每一个字节的|如果q个值是大于127
的,那么pZ个双字节字符集里的字W出C。那时候凡是受q加持,会编E?br>的计机僧G们都要每天念下面q个咒语数百遍:
"一个汉字算两个英文字符Q一个汉字算两个英文字符……"

因ؓ当时各个国家都像中国q样搞出一套自q~码标准Q结果互怹间谁也不?br>谁的~码Q谁也不支持别h的编码,q大陆和台湾q样只相隔了150里Q用着?br>一U语a的兄弟地区,也分别采用了不同?DBCS ~码Ҏ(gu)——当时的中国人想让电
脑显C汉字,必装上一?汉字pȝ"Q专门用来处理汉字的昄、输入的问题Q?br>但是那个台湾的愚昧封Zh士写的算命程序就必须加装另一套支?BIG5 ~码的什?
倚天汉字pȝ"才可以用Q装错了字符pȝQ显C就会ؕ了套Q这怎么办?而且世界
民族之林中还有那些一时用不上电脑的穷苦h民,他们的文字又怎么办?
真是计算机的巴比伦塔命题啊!

正在q时Q大天加百列及时出C——一个叫 ISO Q国际标谁化l织Q的国际l织
军_着手解册个问题。他们采用的Ҏ(gu)很简单:废了所有的地区性编码方案,?br>新搞一个包括了地球上所有文化、所有字母和W号的编码!他们打算叫它"Universal
Multiple-Octet Coded Character Set"Q简U?UCS, 俗称 "UNICODE"?

UNICODE 开始制订时Q计机的存储器定w极大地发展了Q空间再也不成ؓ问题了?br>于是 ISO q接规定必ȝ两个字节Q也是16位来l一表示所有的字符Q对?br>ascii里的那些“半角”字符QUNICODE 包持其原~码不变Q只是将光度由原来??br>扩展?6位,而其他文化和语言的字W则全部重新l一~码。由?半角"英文W号?br>需要用C8位,所以其?位永q是0Q因此这U大气的Ҏ(gu)在保存英文文本时会多
费一倍的I间?

q时候,从旧C会里走q来的程序员开始发C个奇怪的现象Q他们的strlen函数?br>不住了,一个汉字不再是相当于两个字W了Q而是一个!是的Q从 UNICODE 开始,
无论是半角的英文字母Q还是全角的汉字Q它们都是统一?一个字W?Q同Ӟ也都
是统一?两个字节"Q请注意"字符"?字节"两个术语的不同,“字节”是一?位的?br>理存贮单元,?#8220;字符”则是一个文化相关的W号。在UNICODE 中,一个字W就是两
个字节。一个汉字算两个英文字符的时代已l快q去了?br> 
从前多种字符集存在时Q那些做多语a软g的公叔R上过很大ȝQ他们ؓ了在?br>同的国家销售同一套YӞ׃得不在区域化软g时也加持那个双字节字W集咒语
Q不仅要处处心不要搞错Q还要把软g中的文字在不同的字符集中转来转去?br>UNICODE 对于他们来说是一个很好的一揽子解决Ҏ(gu)Q于是从 Windows NT 开始,
MS 机把它们的操作pȝ改了一遍,把所有的核心代码都改成了?UNICODE 方式
工作的版本,从这时开始,WINDOWS pȝl于无需要加装各U本土语apȝQ就
可以昄全世界上所有文化的字符了?

但是QUNICODE 在制订时没有考虑与Q何一U现有的~码Ҏ(gu)保持兼容Q这使得
GBK 与UNICODE 在汉字的内码~排上完全是不一LQ没有一U简单的术Ҏ(gu)?br>以把文本内容从UNICODE~码和另一U编码进行{换,q种转换必须通过查表来进行?

如前所qͼUNICODE 是用两个字节来表CZؓ一个字W,他d可以l合?5535不同
的字W,q大概已l可以覆盖世界上所有文化的W号。如果还不够也没有关p,ISO
已经准备了UCS-4Ҏ(gu)Q说单了是四个字节来表CZ个字W,q样我们可以组
合出21亿个不同的字W出来(最高位有其他用途)Q这大概可以用到银河联邦成立
那一天吧Q?

UNICODE 来到Ӟ一起到来的q有计算机网l的兴vQUNICODE 如何在网l上传输
也是一个必考虑的问题,于是面向传输的众?UTFQUCS Transfer FormatQ标准出
CQ顾名思义QUTF8是每次8个位传输数据Q而UTF16是每次16个位Q只不过
Z传输时的可靠性,从UNICODE到UTF时ƈ不是直接的对应,而是要过一些算?br>和规则来转换?br> 
受到q网l编E加持的计算机僧侣们都知道,在网l里传递信息时有一个很重要?br>问题Q就是对于数据高低位的解L式,一些计机是采用低位先发送的Ҏ(gu)Q例
如我们PC机采用的 INTEL 架构Q而另一些是采用高位先发送的方式Q在|络中交?br>数据ӞZ核对双方对于高低位的认识是否是一致的Q采用了一U很便的Ҏ(gu)
Q就是在文本的开始时向对方发送一个标志符——如果之后的文本是高位在位,?br>发?FEFF"Q反之,则发?FFFE"。不信你可以用二q制方式打开一个UTF-X格式
的文Ӟ看看开头两个字节是不是q两个字节?

讲到q里Q我们再Z说说一个很著名的奇怪现象:当你?windows 的记事本里新
Z个文Ӟ输入"联?两个字之后,保存Q关闭,然后再次打开Q你会发现这两个
字已l消׃Q代之的是几个ؕ码!呵呵Q有q就是联通之所以拼不过Ud?br>原因?
其实q是因ؓGB2312~码与UTF8~码产生了编码冲撞的原因?
从网上引来一D从UNICODE到UTF8的{换规则:

Unicode
UTF-8

0000 - 007F
0xxxxxxx

0080 - 07FF
110xxxxx 10xxxxxx

0800 - FFFF
1110xxxx 10xxxxxx 10xxxxxx

例如"?字的Unicode~码?C49?C49?800-FFFF之间Q所以要?字节模板Q?br>1110xxxx 10xxxxxx 10xxxxxx。将6C49写成二进制是Q?110 1100 0100 1001Q将q个比特?br>按三字节模板的分D|法分?110 110001 001001Q依ơ代替模板中的xQ得刎ͼ1110
-0110 10-110001 10-001001Q即E6 B1 89Q这是其UTF8的编码?
而当你新Z个文本文件时Q记事本的编码默认是ANSI, 如果你在ANSI的编码输入汉
字,那么他实际就是GBpd的编码方式,在这U编码下Q?联?的内码是Q?
c1 1100 0001
aa 1010 1010
cd 1100 1101
a8 1010 1000
注意C吗?W一二个字节、第三四个字节的起始部分的都?110"?10"Q正好与
UTF8规则里的两字节模板是一致的Q于是再ơ打开C本时Q记事本p认ؓq是
一个UTF8~码的文Ӟ让我们把W一个字节的110和第二个字节?0LQ我们就?br>C"00001 101010"Q再把各位对齐,补上前导?Q就得到?0000 0000 0110 1010"Q?br>不好意思,q是UNICODE?06AQ也是写的字?j"Q而之后的两字节用UTF8?br>码之后是0368Q这个字W什么也不是。这是只有"联?两个字的文g没有办法在记
事本里正常显C的原因?
而如果你?联?之后多输入几个字Q其他的字的~码不见得又恰好?10?0开?br>的字节,q样再次打开ӞC本就不会坚持q是一个utf8~码的文Ӟ而会用ANSI
的方式解MQ这时ؕ码又不出C?

好了Q终于可以回{NICO的问题了Q在数据库里Q有n前缀的字串类型就是UNICODE
cdQ这U类型中Q固定用两个字节来表CZ个字W,无论q个字符是汉字还是英
文字母,或是别的什么?
如果你要试"abc汉字"q个串的长度Q在没有n前缀的数据类型里Q这个字串是7?br>字符的长度,因ؓ一个汉字相当于两个字符。而在有n前缀的数据类型里Q同L?br>试串长度的函数将会告诉你?个字W,因ؓ一个汉字就是一个字W?



]]>
jar,war,ear区别http://www.tkk7.com/renyangok/archive/2007/02/08/98784.html保尔?/dc:creator>保尔?/author>Thu, 08 Feb 2007 07:22:00 GMThttp://www.tkk7.com/renyangok/archive/2007/02/08/98784.htmlhttp://www.tkk7.com/renyangok/comments/98784.htmlhttp://www.tkk7.com/renyangok/archive/2007/02/08/98784.html#Feedback0http://www.tkk7.com/renyangok/comments/commentRss/98784.htmlhttp://www.tkk7.com/renyangok/services/trackbacks/98784.html         以最l客L角度来看Q?jar文g是一U封装,他们不需要知?jar文g中有多少?class文gQ每个文件中的功能与作用Q同样可以得C们希望的l果。除jar以外对于J2EE来说q有war和ear。区别见下表Q?/font>

 

 JAR

 WAR

 EAR

 英文  Java Archive file   Web Archive file  Enterprise Archive file
 包含内容  class、properties文gQ是文g装的最单元;  Servlet、JSP面、JSP标记库、JAR库文件、HTML/XML文档和其他公用资源文Ӟ如图片、音频文件等Q?/font>  除了包含JAR、WAR以外Q还包括EJBlg
 部v文g  application-client.xml   web.xml     application.xml
 U别   ?/font>  ?/font>  ?/font>


]]>
Web服务器开发环境下的线E安全问?/title><link>http://www.tkk7.com/renyangok/archive/2006/12/31/91179.html</link><dc:creator>保尔?/dc:creator><author>保尔?/author><pubDate>Sun, 31 Dec 2006 07:31:00 GMT</pubDate><guid>http://www.tkk7.com/renyangok/archive/2006/12/31/91179.html</guid><wfw:comment>http://www.tkk7.com/renyangok/comments/91179.html</wfw:comment><comments>http://www.tkk7.com/renyangok/archive/2006/12/31/91179.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/renyangok/comments/commentRss/91179.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/renyangok/services/trackbacks/91179.html</trackback:ping><description><![CDATA[ <p>Servlet是在多线E环境下的。即可能有多个请求发l一个servelt实例Q每个请求是一个线E?br />struts下的action也类|同样在多U程环境下。可以参考struts user guide: <a >http://struts.apache.org/struts-action/userGuide/building_controller.html</a> 中的Action Class Design Guidelines一?  Write code for a multi-threaded environment - Our controller servlet creates only one instance of your Action class, and uses this one instance to service all requests. Thus, you need to write thread-safe Action classes. Follow the same guidelines you would use to write thread-safe Servlets.<br />?为多U程环境~写代码。我们的controller servlet指挥创徏你的Action cȝ一个实例,用此实例来服务所有的h。因此,你必ȝ写线E安全的ActioncR遵循与写线E安全的servlet同样的方针?br /> <br />1.什么是U程安全的代?br />  在多U程环境下能正确执行的代码就是线E安全的?br />  安全的意思是能正执行,否则后果是程序执行错误,可能出现各种异常情况?/p> <p>2.如何~写U程安全的代?br />  很多书籍里都详细讲解了如何这斚w的问题,他们主要讲解的是如何同步U程对共享资源的使用的问题。主要是对synchronized关键字的各种用法Q以及锁的概c?br />  Java1.5中也提供了如d锁这cȝ工具cR这些都需要较高的技巧,而且相对难于调试?br /> <br />  但是Q线E同步是不得以的Ҏ(gu),是比较复杂的,而且会带来性能的损失。等效的代码中,不需要同?在编写容易度和性能上会更好些?br />  我这里强调的是什么代码是始终为线E安全的、是不需要同步的。如?<br />  1)帔R始终是线E安全的Q因为只存在L作?br />  2)Ҏ(gu)造器的访?new 操作)是线E安全的Q因为每ơ都新徏一个实例,不会讉K׃n的资源?br />  3)最重要的是:局部变量是U程安全的。因为每执行一个方法,都会在独立的I间创徏局部变量,它不是共享的资源。局部变量包括方法的参数变量?br />    struts user guide里有Q?br />    Only Use Local Variables - The most important principle that aids in thread-safe coding is to use only local variables, not instance variables , in your Action class.<br />    ?只用用局部变量?-~写U程安全的代码最重要的原则就是,在ActioncM只用局部变量,不用实例变量?/p> <p> <br />ȝQ?br />    在Java的Web服务器环境下开发,要注意线E安全的问题。最单的实现方式是在Servlet和Struts Action里不要用类变量、实例变量,但可以用类帔R和实例常量?br />如果有这些变量,可以它们{换ؓҎ(gu)的参C入,以消除它们?br />    注意一个容易؜淆的地方Q被Servlet或Action调用的类?如值对象、领域模型类)中是否可以安全的使用实例变量Q如果你在每ơ方法调用时<br />新徏一个对象,再调用它们的Ҏ(gu)Q则不存在同步问?--因ؓ它们不是多个U程׃n的资源,只有׃n的资源才需要同?--而Servlet和Action的实例对于多个线E是׃n的?br />换句话说QServlet和Action的实例会被多个线E同时调用,而过了这一?如果在你自己的代码中没有另外启动U程Q且每次调用后箋业务对象旉是先新徏一个实例再调用Q则都是U程安全的?/p> <img src ="http://www.tkk7.com/renyangok/aggbug/91179.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/renyangok/" target="_blank">保尔?/a> 2006-12-31 15:31 <a href="http://www.tkk7.com/renyangok/archive/2006/12/31/91179.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java中文问题及最优解x案(本地化)http://www.tkk7.com/renyangok/archive/2006/12/31/91106.html保尔?/dc:creator>保尔?/author>Sun, 31 Dec 2006 02:13:00 GMThttp://www.tkk7.com/renyangok/archive/2006/12/31/91106.htmlhttp://www.tkk7.com/renyangok/comments/91106.htmlhttp://www.tkk7.com/renyangok/archive/2006/12/31/91106.html#Feedback0http://www.tkk7.com/renyangok/comments/commentRss/91106.htmlhttp://www.tkk7.com/renyangok/services/trackbacks/91106.html   AbstractQ本文深入分析了JavaE序设计中Java~译器对java源文件和JVM对classcL件的~码/解码q程Q通过此过E的解析透视ZJava~程中中文问题生的Ҏ(gu)原因Q最后给Z的最优化的解决Java中文问题的方法。?

  1、中文问题的来源

    计算机最初的操作pȝ支持的编码是单字节的字符~码Q于是,在计机中一切处理程序最初都是以单字节编码的英文为准q行处理。随着计算机的发展Qؓ了适应世界其它民族的语aQ当然包括我们的汉字Q,Z提出了UNICODE~码Q它采用双字节编码,兼容英文字符和其它民族的双字节字W编码,所以,目前Q大多数国际***的Y件内部均采用UNICODE~码Q在软gq行Ӟ它获得本地支持系l(多数旉是操作系l)默认支持的编码格式,然后再将软g内部?UNICODE转化为本地系l默认支持的格式昄出来。Java的JDK和JVMx如此Q我q里说的JDK是指国际版的JDKQ我们大多数E序员用的是国际化的JDK版本Q以下所有的JDK均指国际化的JDK版本。我们的汉字是双字节~码语言Qؓ了能让计机处理中文Q我们自己制定的gb2312?GBK、GBK2K{标准以适应计算机处理的需求。所以,大部分的操作pȝZ适应我们处理中文的需求,均定制有中文操作pȝQ它们采用的是GBK, GB2312~码格式以正显C我们的汉字。如Q中文Win2K默认采用的是GBK~码昄Q在中文WIN2k中保存文件时默认采用的保存文件的~码格式也是GBK的,卻I所有在中文WIN2K中保存的文g它的内部~码默认均采用GBK~码Q注意:GBK是在GB2312基础上扩充来的?/p>

    ׃Java语言内部采用UNICODE~码Q所以在JAVAE序q行Ӟ存在着一个从UNICODE~码和对应的操作pȝ及浏览器支持的编码格式{换输入、输出的问题Q这个{换过E有着一pd的步骤,如果其中M一步出错,则显C出来的汉字׃出是qQ这是我们常见的JAVA中文问题?/p>

    同时QJava是一个跨q_的编E语aQ也x们编写的E序不仅能在中文windows上运行,也能在中文Linux{系l上q行Q同时也要求能在英文{系l上q行Q我们经常看到有人把在中文win2k上编写的JAVAE序Q移植到英文Linux上运行)。这U移植操作也会带来中文问题?/p>

    q有Q有Z用英文的操作pȝ和英文的IE{浏览器Q来q行带中文字W的E序和浏览中文网,它们本n׃支持中文Q也会带来中文问题?/p>

    几乎所有的览器默认在传递参数时都是以UTF-8~码格式来传递,而不是按中文~码传递,所以,传递中文参数时也会有问题,从而带来ؕ码现象?/p>

    MQ以上几个方面是JAVA中的中文问题的主要来源,我们把以上原因造成的程序不能正运行而生的问题UCQJAVA中文问题?/p>

  2、JAVA~码转换的详l过E?

    我们常见的JAVAE序包括以下cdQ?br />     *直接在console上运行的c?包括可视化界面的c?
     *JSP代码c(注:JSP是Servletscȝ变型Q?br />     *Serveletsc?br />     *EJBc?br />     *其它不可以直接运行的支持c?/p>

    q些cL件中Q都有可能含有中文字W串Qƈ且我们常用前三类JAVAE序和用L接交互,用于输出和输入字W,如:我们在JSP和Servlet中得到客L送来的字W,q些字符也包括中文字W。无些JAVAcȝ作用如何Q这些JAVAE序的生命周期都是这LQ?/p>

    *~程人员在一定的操作pȝ上选择一个合适的~辑软g来实现源E序代码q以.java扩展名保存在操作pȝ中,例如我们在中文win2k中用C本编辑一个java源程序;
     *~程人员用JDK中的javac.exe来编译这些源代码QŞ?classc?JSP文g是由容器调用JDK来编译的)Q?br />     *直接q行q些cL这些类布v到WEB容器中去q行Qƈ输出l果?br />    那么Q在q些q程中,JDK和JVM是如何将q些文g如何~码和解码ƈq行的呢Q?/p>

q里Q我们以中文win2k操作pȝZ说明JAVAcL如何来编码和被解码的?

    W一步,我们在中文win2k中用~辑软g如记事本~写一个Java源程序文?包括以上五类JAVA E序)Q程序文件在保存旉认采用了操作pȝ默认支持GBK~码格式(操作pȝ默认支持的格式ؓfile.encoding格式)形成了一?java文gQ也卻IjavaE序在被~译前,我们的JAVA源程序文件是采用操作pȝ默认支持的file.encoding~码格式保存的,java源程序中含有中文信息字符和英文程序代码;要查看系l的file.encoding参数Q可以用以下代码Q?br />  public class ShowSystemDefaultEncoding {
  public static void main(String[] args) {
  String encoding = System.getProperty("file.encoding");
  System.out.println(encoding);
  }}

    W二步,我们用JDK的javac.exe文g~译我们的Java源程序,׃JDK是国际版的,在编译的时候,如果我们没有?encoding参数指定我们?JAVA源程序的~码格式Q则javac.exe首先获得我们操作pȝ默认采用的编码格式,也即在编译javaE序Ӟ若我们不指定源程序文件的~码格式QJDK首先获得操作pȝ的file.encoding参数(它保存的是操作pȝ默认的编码格式,如WIN2kQ它的gؓGBK)Q然后JDK把我们的java源程序从file.encoding~码格式转化为JAVA内部默认?UNICODE格式攑օ内存中。然后,javac把{换后的unicode格式的文件进行编译成.classcLӞ此时.class文g?UNICODE~码的,它暂攑֜内存中,紧接着QJDK此以UNICODE~码的编译后的class文g保存到我们的操作pȝ中Ş成我们见到的. class文g。对我们来说Q我们最l获得的.class文g是内容以UNICODE~码格式保存的类文gQ它内部包含我们源程序中的中文字W串Q只不过此时它己l由file.encoding格式转化为UNICODE格式了?/p>

    q一步中Q对于JSP源程序文件是不同的,对于JSPQ这个过E是q样的:即WEB容器调用JSP~译器,JSP~译器先查看JSP文g中是否设|有文g~码格式Q如果JSP文g中没有设|JSP文g的编码格式,则JSP~译器调用JDK先把JSP文g用JVM默认的字W编码格?也即WEB容器所在的操作pȝ的默认的file.encoding)转化Z时的Servletc,然后再把它编译成UNICODE格式的classc,q保存在临时文g夹中。如Q在中文win2k上,WEB容器把JSP文g从GBK~码格式转化为UNICODE格式Q然后编译成临时保存的Servletc,以响应用Lh?/p>

    W三步,q行W二步编译出来的c,分ؓ三种情况Q?/strong>

    A?直接在console上运行的c?br />    B?EJBcd不可以直接运行的支持c?如JavaBeanc?
    C?JSP代码和Servletc?br />    D?JAVAE序和数据库之间
    下面我们分这四种情况来看?br />    A、直接在console上运行的c?/strong>

    q种情况Q运行该c首先需要JVM支持Q即操作pȝ中必d装有JRE。运行过E是q样的:首先java启动JVMQ此时JVMd操作pȝ中保存的 class文gq把内容d内存中,此时内存中ؓUNICODE格式的classc,然后JVMq行它,如果此时此类需要接收用戯入,则类会默认用 file.encoding~码格式对用戯入的串进行编码ƈ转化为unicode保存入内存(用户可以讄输入的~码格式Q。程序运行后Q生的字符ԌUNICODE~码的)再回交给JVMQ最后JRE把此字符串再转化为file.encoding格式(用户可以讄输出的~码格式)传递给操作pȝ昄接口q输出到界面上?/p>

    对于q种直接在console上运行的c,它的转化q程可用?更加明确的表C出来:

?

以上每一步的转化都需要正的~码格式转化Q才能最l不出现q现象?br />
    B、EJBcd不可以直接运行的支持c?如JavaBeanc?

    ׃EJBcd不可以直接运行的支持c,它们一般不与用L接交互输入和输出Q它们常怸其它的类q行交互输入和输出,所以它们在W二步被~译后,Ş成了内容是UNICODE~码的类保存在操作系l中了,以后只要它与其它的类之间的交互在参数传递过E中没有丢失Q则它就会正的q行?br />q种EJBcd不可以直接运行的支持c? 它的转化q程可用?更加明确的表C出来:

?


    C、JSP代码和Servletc?/strong>

    l过W二步后QJSP文g也被转化为ServletscLӞ只不q它不像标准的Servlets一校存在于classes目录中,它存在于WEB容器的时目录中Q故q一步中我们也把它做为Servlets来看?/p>

    对于ServletsQ客Lh它时QWEB容器调用它的JVM来运行ServletQ首先,JVM把Servlet的classcMpȝ中读出ƈ装入内存中,内存中是以UNICODE~码的Servletcȝ代码Q然后JVM在内存中q行该Servletc,如果Servlet在运行的q程中,需要接受从客户端传来的字符如:表单输入的值和URL中传入的|此时如果E序中没有设定接受参数时采用的编码格式,则WEB容器会默认采用ISO-8859- 1~码格式来接受传入的值ƈ在JVM中{化ؓUNICODE格式的保存在WEB容器的内存中。Servletq行后生成输出,输出的字W串?UNICODE格式的,紧接着Q容器将Servletq行产生的UNICODE格式的串Q如html语法Q用戯出的串等Q直接发送到客户端浏览器上ƈ输出l用P如果此时指定了发送时输出的编码格式,则按指定的编码格式输出到览器上Q如果没有指定,则默认按ISO-8859-1~码发送到客户的浏览器上。这UJSP代码和Servletc,它的转化q程可用?更加明确地表C出来:

?

D、JavaE序和数据库之间

    对于几乎所有数据库的JDBC驱动E序Q默认的在JAVAE序和数据库之间传递数据都是以ISO-8859-1为默认编码格式的Q所以,我们的程序在向数据库内存储包含中文的数据ӞJDBC首先是把E序内部的UNICODE~码格式的数据{化ؓISO-8859-1的格式,然后传递到数据库中Q在数据库保存数据时Q它默认即以ISO-8859-1保存Q所以,q是Z么我们常常在数据库中d的中文数据是q?br />    对于JAVAE序和数据库之间的数据传递,我们可以用图4清晰地表C出?/p>

?


    3、分析常见的JAVA中文问题几个必须清楚的原?br />
    首先Q经q上面的详细分析Q我们可以清晰地看到QQ何JAVAE序的生命期中,其编码{换的关键q程是在于:最初编译成class文g的{码和最l向用户输出的{码过E?br />    其次Q我们必M解JAVA在编译时支持的、常用的~码格式有以下几U:
    *ISO-8859-1Q?-bit, ?859_1,ISO-8859-1,ISO_8859_1{编?br />    *Cp1252Q美国英语编码,同ANSI标准~码
    *UTF-8Q同unicode~码
    *GB2312Q同gb2312-80,gb2312-1980{编?br />    *GBK , 同MS936Q它是gb2312的扩?br />    及其它的~码Q如韩文、日文、繁体中文等。同Ӟ我们要注意这些编码间的兼容关体系如下Q?br />    unicode和UTF-8~码是一一对应的关pRGB2312可以认ؓ是GBK的子集,即GBK~码是在gb2312上扩展来的。同ӞGBK~码包含?0902个汉字,~码范围为:0x8140-0xfefeQ所有的字符可以一一对应到UNICODE2.0中来?/p>

    再次Q对于放在操作系l中?java源程序文Ӟ在编译时Q我们可以指定它内容的编码格式,具体来说?encoding来指定。注意:如果源程序中含有中文字符Q而你?encoding指定为其它的~码字符Q显然是要出错的。用-encoding指定源文件的~码方式为GBK或gb2312Q无论我们在什么系l上~译含有中文字符的JAVA源程序都不会有问题,它都会正地中文{化ؓUNICODE存储在class文g中?br />    
    然后Q我们必L楚,几乎所有的WEB容器在其内部默认的字W编码格式都是以ISO-8859-1为默认值的Q同Ӟ几乎所有的览器在传递参数时都是默认以UTF-8的方式来传递参数的。所以,虽然我们的Java源文件在出入口的地方指定了正的~码方式Q但其在容器内部q行时还是以ISO-8859- 1来处理的?br />


 4、中文问题的分类及其最优解军_?/strong>

    了解以上JAVA处理文g的原理之后,我们可以提Z一套徏议最优的解决汉字问题的办法?br />    我们的目标是Q我们在中文pȝ中编辑的含有中文字符串或q行中文处理的JAVA源程序经~译后可以移值到M其它?a >操作pȝ中正运行,或拿到其它操作系l中~译后能正确q行Q能正确C递中文和英文参数Q能正确地和数据?/font>交流中英文字W串?br />    我们的具体思\是:在JAVAE序转码的入口和出口及JAVAE序同用h输入输出转换的地斚w制编码方法之正即可?/p>

    具体解决办法如下Q?/strong>

    1?针对直接在console上运行的c?/strong>
    对于q种情况Q我们徏议在E序~写Ӟ如果需要从用户端接收用L可能含有中文的输入或含有中文的输出,E序中应该采用字W流来处理输入和输出Q具体来_应用以下面向字符型节Ҏ(gu)cdQ?br />    Ҏ(gu)ӞFileReaderQFileWrieter
        其字节型节点类型ؓQFileInputStreamQFileOutputStream
    对内存(数组Q:CharArrayReaderQCharArrayWriter
        其字节型节点类型ؓQByteArrayInputStreamQByteArrayOutputStream
    对内存(字符ԌQStringReaderQStringWriter
    对管道:PipedReaderQPipedWriter
        其字节型节点类型ؓQPipedInputStreamQPipedOutputStream
    同时Q应该用以下面向字符型处理流来处理输入和输出Q?br />    BufferedWriterQBufferedReader
        其字节型的处理流为:BufferedInputeStreamQBufferedOutputStream
    InputStreamReaderQOutputStreamWriter
    其字节型的处理流为:DataInputStreamQDataOutputStream
    其中InputStreamReader和InputStreamWriter用于字节流按照指定的字W编码集转换到字W流Q如Q?br />    InputStreamReader in = new InputStreamReader(System.inQ?GB2312")Q?br />    OutputStreamWriter out = new OutputStreamWriter (System.outQ?GB2312")Q?br />    例如Q采用如下的CZJAVA~码pC要求Q?/p>

    //Read.java
    import java.io.*;
    public class Read {
    public static void main(String[] args) throws IOException {
    String str = "\n中文试Q这是内部硬~码的串"+"\ntest english character";
    String strin= "";
    BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in,"gb2312")); //讄输入接口按中文编?br />    BufferedWriter stdout = new BufferedWriter(new OutputStreamWriter(System.out,"gb2312")); //讄输出接口按中文编?br />    stdout.write("误?");
    stdout.flush();
    strin = stdin.readLine();
    stdout.write("q是从用戯入的Ԍ"+strin);
    stdout.write(str);
    stdout.flush();
    }}
    同时Q在~译E序Ӟ我们用以下方式来q行Q?br />    javac -encoding gb2312 Read.java
    其运行结果如?所C:

    ?
2?针对EJBcd不可以直接运行的支持c?如JavaBeanc?

    ׃q种cd们本w被其它的类调用Q不直接与用户交互,故对q种cL_我们的徏议的处理方式是内部程序中应该采用字符来处理E序内部的中文字W串Q具体如上面一节中一PQ同Ӟ在编译类时用-encoding gb2312参数指示源文件是中文格式~码的即可?/p>


    3?针对Servletc?/strong>

    针对ServletQ我们徏议用以下Ҏ(gu)Q(我徏议将.java文g讄为UTF8~码的。当然如果是用Eclipse的话Q只要设|下是了。对于数据库Q我以ؓ~码最好设|ؓUTF8,便于国际化 。尽可能的用UTF8码,  千里草)

    在编译Servletcȝ源程序时Q用-encoding指定~码为GBK或GB2312Q且在向用户输出时的~码部分用response对象?setContentType("text/html;charset=GBK");或gb2312来设|输出编码格式,同样在接收用戯入时Q我们用 request.setCharacterEncoding("GB2312")Q这h论我们的servletcȝ植到什么操作系l中Q只有客L的浏览器支持中文昄Q就可以正确昄。如下是一个正的CZQ?/p>

    //HelloWorld.java
    package hello;
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    public class HelloWorld extends HttpServlet
    {
    public void init() throws ServletException { }
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
    request.setCharacterEncoding("GB2312"); //讄输入~码格式
    response.setContentType("text/html;charset=GB2312"); //讄输出~码格式
    PrintWriter out = response.getWriter(); //使用PrintWriter输出
    out.println("<hr>");
    out.println("Hello World! This is created by Servlet!试中文!");
    out.println("<hr>");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    {
    request.setCharacterEncoding("GB2312"); //讄输入~码格式
    response.setContentType("text/html;charset=GB2312"); //讄输出~码格式
    String name = request.getParameter("name");
    String id = request.getParameter("id");
    if(name==null) name="";
    if(id==null) id="";
    PrintWriter out = response.getWriter(); //使用PrintWriter输出
    out.println("<hr>");
    out.println("你传入的中文字串是:" + name);
    out.println("<hr>你输入的id是:" + id);
    out.println("<hr>");
    }
    public void destroy() { }
    }
        Ljavac -encoding gb2312 HelloWorld.java来编译此E序?br />        试此Servlet的程序如下所C:
    <%@page contentType="text/html; charset=gb2312"%>
    <%request.setCharacterEncoding("GB2312");%>
    <html><head><title></title>
    <Script language="JavaScript">
    function Submit() {
    //通过URL传递中文字W串值给Servlet
    document.base.action = "./HelloWorld?name=中文";
    document.base.method = "POST";
    document.base.submit();
    }
    </Script>
    </head>

<body bgcolor="#FFFFFF" text="#000000" topmargin="5">
    <form name="base" method = "POST" target="_self">
    <input name="id" type="text" value="" size="30">
    <a href = "JavaScript:Submit()">传给Servlet</a>
    </form></body></html>
    其运行结果如?所C:

    ?
    4?JAVAE序和数据库之间

    为避免JAVAE序和数据库之间数据传递出Cؕ码现象,我们采用以下最优方法来处理Q?br />    1?对于JAVAE序的处理方法按我们指定的方法处理?br />    2?把数据库默认支持的编码格式改为GBK或GB2312的?/p>

    如:在mysql中,我们可以在配|文件my.ini中加入以下语句实玎ͼ
    在[mysqld]区增加:
    default-character-set=gbk
    q增加:
    [client]
    default-character-set=gbk
    在SQL Server2K中,我们可以数据库默认的语a讄为Simplified Chinese来达到目的?/p>

    5?针对JSP代码

    ׃JSP是在q行Ӟ由WEB容器q行动态编译的Q如果我们没有指定JSP源文件的~码格式Q则JSP~译器会获得服务器操作系l的 file.encoding值来对JSP文g~译的,它在UL时最Ҏ(gu)出问题,如在中文win2k中可以很好运行的jsp文g拿到英文linux中就不行Q尽客L都是一LQ那是因为容器在~译JSP文g时获取的操作pȝ的编码不同造成的(在中文wink中的file.encoding和在英文 Linux中file.encoding是不同的Q且英文Linux的file.encoding对中文不支持Q所以编译出来的JSPcd会有问题Q?a >|络上讨论的大多数是此类问题Q多是因为JSP文gULq_时不能正显C的问题Q对于这c问题,我们了解了JAVA中程序编码{换的原理Q解册v来就Ҏ(gu)多了。我们徏议的解决办法如下Q?/p>

    1、我们要保证JSP向客L输出时是采用中文~码方式输出的,x论如何我们首先在我们的JSP源代~中加入以下一行:

    <%@page contentType="text/html; charset=gb2312"%>
    2、ؓ了让JSP能正获得传入的参数Q我们在JSP源文件头加入下面一句:
    <%request.setCharacterEncoding("GB2312");%>
    3、ؓ了让JSP~译器能正确地解码我们的含有中文字符的JSP文gQ我们需要在JSP源文件中指定我们的JSP源文件的~码格式Q具体来_我们在JSP源文件头上加入下面的一句即可:
    <%@page pageEncoding="GB2312"%>?lt;%@page pageEncoding="GBK"%>
    q是JSP规范2.0新增加的指o?br />    我们使用此方法来解JSP文g中的中文问题Q下面的代码是一个正做法的JSP文g的测试程序:

//testchinese.jsp
    <%@page pageEncoding="GB2312"%>
    <%@page contentType="text/html; charset=gb2312"%>
    <%request.setCharacterEncoding("GB2312");%>
    <%
    String action = request.getParameter("ACTION");
    String name = "";
    String str = "";
    if(action!=null && action.equals("SENT"))
    {
    name = request.getParameter("name");
    str = request.getParameter("str");
    }
    %>
    <html>
    <head>
    <title></title>
    <Script language="JavaScript">
    function Submit()
    {
    document.base.action = "?ACTION=SENT&str=传入的中?;
    document.base.method = "POST";
    document.base.submit();
    }
    </Script>
    </head>
    <body bgcolor="#FFFFFF" text="#000000" topmargin="5">
    <form name="base" method = "POST" target="_self">
    <input type="text" name="name" value="" size="30">
    <a href = "JavaScript:Submit()">提交</a>
    </form>
    <%
    if(action!=null && action.equals("SENT"))
    {
    out.println("<br>你输入的字符为:"+name);
    out.println("<br>你通过URL传入的字WؓQ?+str);
    }
    %>
    </body>
    </html>
    如图7是此E序q行的结果示意图Q?br />

    ?

    5、ȝ

    在上面的详细分析中,我们清晰地给ZJAVA在处理源E序q程中的详细转换q程Qؓ我们正确解决JAVA~程中的中文问题提供了基。同Ӟ我们l出了认为是最优的解决JAVA中文问题的办法?/p>我的补充Q需要特别注意)Q?在表单(form Q提交时Q如果提交的Ҏ(gu)为getQ那么request.setCharacterEncoding() 是不起作用的。此时在服务器端得到的字W编码仍然是ISO8859-1Q而不是你讄的编码。所以一般我们在提交数据Ӟ量使用postҎ(gu)Q此?request.setCharacterEncoding()Ҏ(gu)h?br />
 如果非要使用getҎ(gu)传form则要转换一下才行: 
  -----  
  <%@   page   contentType="text/html;charset=gb2312"%>  
  <%!  
          public   String   getStr(String   str){  
  try{  
  String   temp_p=str;  
  byte[]   temp_t=temp_p.getBytes("ISO8859-1");  
  String   temp=new   String(temp_t);  
  return   temp;  
  }  
  catch(Exception   e){  
  }  
  return   "null";  
    }  
    %>  
  然后把String   userId=request.getParameter("userId");Ҏ(gu)  
  String   userId=getStr(request.getParameter("userId"));  
Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-Q-
我来说一下tomcat如何实现JSP的你明白了?br />预备知识Q?br /> 1.字节和unicode
  Java内核是unicode的,pclass文g也是Q但是很多媒体,包括文g/的保存方式
  是用字节流的?因此Java要对q些字节经行{化。char是unicode的,而byte是字?
  Java中byte/char互{的函数在sun.io的包中间有。其中ByteToCharConvertercL中调度,
  可以用来告诉你,你用的Convertor。其中两个很常用的静态函数是
   public static ByteToCharConverter getDefault() ;
   public static ByteToCharConverter getConverter(String encoding);
  如果你不指定converterQ则pȝ会自动用当前的Encoding,GBq_上用GBK,ENq_上用
  8859_1
  
  我们来就一个简单的例子Q?br />     "?的gb码是Q?xC4E3 ,unicode?x4F60
     你用:
     --encoding="gb2312";
     --byte b[]={(byte)'\u00c4',(byte)'\u00E3'};
     --convertor=ByteToCharConverter.getConverter(encoding);
     --char [] c=converter.convertAll(b);
     --for(int i=0;i<c.length;c++)
     --{
     -- System.out.println(Integer.toHexString(c[i]));
     --}
     --打印出来?x4F60
     --但是如果使用8859_1的编码,打印出来?br />     --0x00C4,0x00E3
     ----例1
     反过来:
      --encoding="gb2312";
      --char c[]={'\u4F60'};
     --convertor=ByteToCharConverter.getConverter(encoding);
     --byte [] b=converter.convertAll(c);
     --for(int i=0;i<b.length;c++)
     --{
     -- System.out.println(Integer.toHexString(b[i]));
     --}
      --打印出来是:0xC4,0xE3
      ----例2
      --如果?859_1是0x3FQ?P表示无法转化      --
      很多中文问题是从这两个最单的cL生出来的。而却有很多类  
  不直接支持把Encoding输入Q这l我们带来诸多不ѝ很多程序难得用encoding
  了,直接用default的encodingQ这q我们UL带来了很多困?br />  --
  2.UTF-8
  --UTF-8是和Unicode一一对应的,其实现很?br />  --
  -- 7位的Unicode: 0 _ _ _ _ _ _ _
  --11位的Unicode: 1 1 0 _ _ _ _ _ 1 0 _ _ _ _ _ _
  --16位的Unicode: 1 1 1 0 _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
  --21位的Unicode: 1 1 1 1 0 _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _ 1 0 _ _ _ _ _ _
  --大多数情冉|只用到16位以下的Unicode:
  --"?的gb码是Q?xC4E3 ,unicode?x4F60
  --我们q是用上面的例子
  --  --例1Q?xC4E3的二q制Q?br />  --  --    1 1 0 0 0 1 0 0 1 1 1 0 0 0 1 1
  --  --    ׃只有两位我们按照两位的编码来排,但是我们发现q行不通,
  --  --    因ؓW7位不?因此Q返??"
  --  --   
  --  --例2Q?x4F60的二q制Q?br />  --  --    0 1 0 0 1 1 1 1 0 1 1 0 0 0 0 0
  --  --    我们用UTF-8补齐Q变成:
  --  --    11100100 10111101 10100000
  --  --    E4--BD-- A0
  --  --    于是q回0xE4,0xBD,0xA0
  --  --
  3.String和byte[]
  --String其实核心是char[],然而要把byte转化成StringQ必ȝq编码?br />  --String.length()其实是char数组的长度,如果使用不同的编码,很可
  --能会错分Q造成散字和ؕ码?br />  --例:
  ----byte [] b={(byte)'\u00c4',(byte)'\u00e3'};
  ----String str=new String(b,encoding);  ----
  ----如果encoding=8859_1Q会有两个字Q但是encoding=gb2312只有一个字  ----
  --q个问题在处理分|l常发生
  4.Reader,Writer/InputStream,OutputStream
  --Reader和Writer核心是charQInputStream和OutputStream核心是byte?br />  --但是Reader和Writer的主要目的是要把Char?写InputStream/OutputStream
--一个reader的例子:
--文gtest.txt只有一??字,0xC4,0xE3--
--String encoding=;
--InputStreamReader reader=new InputStreamReader(
----new FileInputStream("text.txt"),encoding);
--char []c=new char[10];
--int length=reader.read(c);
--for(int i=0;i<c.length;i++)
----System.out.println(c[i]);
  --如果encoding是gb2312Q则只有一个字W,如果encoding=8859_1Q则有两个字W?br />  --------
--
--
  
   ----
 2.我们要对Java的编译器有所了解Q?br /> --javac -encoding
  我们常常没有用到ENCODINGq个参数。其实Encodingq个参数对于跨^台的操作是很重要的?br />  如果没有指定EncodingQ则按照pȝ的默认Encoding,gbq_上是gb2312Q英文^C是ISO8859_1。 
 --Java的编译器实际上是调用sun.tools.javac.Main的类Q对文gq行~译Q这个类 --
 有compile函数中间有一个encoding的变?-encoding的参数其实直接传lencoding变量?br /> ~译器就是根据这个变量来djava文g的,然后把用UTF-8形式~译成class文g?br /> 一个例子:
 --public void test()
 --{
 ----String str="?;
 ----FileWriter write=new FileWriter("test.txt");
 ----write.write(str);
 ----write.close();
 --}
 ----例3
--如果用gb2312~译Q你会找到E4 BD A0的字D?br />--
--如果?859_1~译Q?br />--00C4 00E3的二q制Q?br />--00000000 11000100 00000000 11100011--
--因ؓ每个字符都大?位,因此?1位编码:
--11000001 10000100 11000011 10100011
--C1-- 84-- C3--  A3
--你会扑ֈC1 84 C3 A3 --
    
  但是我们往往忽略掉这个参敎ͼ因此q样往往会有跨^台的问题Q?br />  --  例3在中文^C~译Q生成ZhClass
  --  例3在英文^C~译Q输出EnClass
  --1.  ZhClass在中文^C执行OK,但是在英文^C不行
  --2.  EnClass在英文^C执行OK,但是在中文^C不行
  原因Q?br /> --1.在中文^C~译后,其实str在运行态的char[]?x4F60, ----
 --在中文^Cq行QFileWriter的缺省编码是gb2312,因此
 --CharToByteConverter会自动用调用gb2312的converter,把str转化
 --成byte输入到FileOutputStream中,于是0xC4,0xE3放进了文件?br /> --但是如果是在英文q_下,CharToByteConverter的缺省值是8859_1,
 --FileWriter会自动调?859_1去{化str,但是他无法解释,因此他会
 --输出"?" ----
 --2. 在英文^C~译后,其实str在运行态的char[]?x00C4 0x00E3, ----
 --在中文^Cq行Q中文无法识别,因此会出??
 --  在英文^CQ?x00C4-->0xC4,0x00E3->0xE3Q因?xC4,0xE3被放q了
 --文g
----
1.对于JSP正文的解释:
--Tomcat首先看一下你的叶面中有没?<%@page include的符受有Q则在相?br />--地方讑֮response.setContentType(..);按照encoding的来读,没有他按?859_1
--d文gQ然后用UTF-8写成.java文gQ然后用sun.tools.Main去读取这个文Ӟ
--Q当然它使用UTF-8去读Q,然后~译成class文g
--setContentType改变的是out的属性,out变量~省的encoding?859_1
2.对Parameter的解?br />--很不qParameter只有ISO8859_1的解释,q个质料可以在servlet的实C码中扑ֈ?br />3.对include的解?br />格式的,但是很不q,׃那个?org.apache.jasper.compiler.Parser"的h
在数lJspUtil.ValidAttribute[]忘记加了一个参敎ͼencoding,因此D不支
持这U方式。你完全可以~译源代码,加上对encoding的支?br />ȝQ?br />如果你在NT底下Q最单的Ҏ(gu)是ƺ骗java,不加MEncoding变量Q?br /><html>
你好<%=request.getParameter("value")%>
</html>
http://localhost/test/test.jsp?value=?br />l果:你好?br />但这U方法局限性较大,比如对上传的文章分段Q这L做法是死定的Q最好的
解决Ҏ(gu)是用q种Ҏ(gu)Q?br /><%@ page contentType="text/html;charset=gb2312" %>
<html>
你好<%=new String(request.getParameter("value").getBytes("8859_1"),"gb2312")%>
</html>


<select name="account.accountId" >
    <OPTION value="<%=account.getAccountId()%>">我的日志</OPTION>
    <OPTION value="">所有日?lt;/OPTION>
    <OPTION <%=s%> value="<%=a.getAccountId()%>"><%=a.getAccountName()%></OPTION>
   </select>


]]>
初学者如何开发出一个高质量的J2EEpȝhttp://www.tkk7.com/renyangok/archive/2006/12/31/91105.html保尔?/dc:creator>保尔?/author>Sun, 31 Dec 2006 02:11:00 GMThttp://www.tkk7.com/renyangok/archive/2006/12/31/91105.htmlhttp://www.tkk7.com/renyangok/comments/91105.htmlhttp://www.tkk7.com/renyangok/archive/2006/12/31/91105.html#Feedback0http://www.tkk7.com/renyangok/comments/commentRss/91105.htmlhttp://www.tkk7.com/renyangok/services/trackbacks/91105.html  J2EE学习者越来越多,J2EE本n技术不断在发展Q涌现出各种概念Q本文章试图从一U容易理解的角度对这些概念向初学者进行解释,以便掌握学习J2EE学习方向?/div>
  首先我们需要知道Java和J2EE是两个不同概念,Java不只是指一U语aQ已l代表与微Y不同的另外一个巨大阵营,所以Java有时是指一UY件系l的派Q当然目前主要是.NET和Java两大L体系?/div>
  J2EE可以说指Java在数据库信息pȝ上实玎ͼ数据库信息系l从早期的dBase、到Delphi/VB{C/Sl构Q发展到B/SQBrowser览?Server服务器)l构Q而J2EE主要是指B/Sl构的实现?/div>
  J2EE又是一U框架和标准Q框架类似API、库的概念,但是要超出它们。如果需要详l了解框Ӟ可先从设计模式开始学习?/div>
  J2EE是一个虚的大的概念,J2EE标准主要有三U子技术标准:WEB技术、EJB技术和JMSQ谈到J2EE应该说最l要落实到这三个子概念上?/div>
  q三U技术的每个技术在应用旉涉及两个部分Q容器部分和应用部分QWeb容器也是指Jsp/Servlet容器Q你如果要开发一个Web应用Q无论是~译或运行,都必要有Jsp/Servlet库或API支持Q除了JDK/J2SE以外Q?/div>
  Web技术中除了Jsp/Servlet技术外Q还需要JavaBeans或Java Class实现一些功能或者包装携带数据,所以Web技术最初裸体简UCؓJsp/Servlet+JavaBeanspȝ?/div>
  谈到JavaBeans技术,涉及到lg构g技术(componentQ,q是Java的核心基部分Q很多Y件设计概念(设计模式Q都是通过JavaBeans实现的?/div>
  JavaBeans不属于J2EE概念范畴中,如果一个JavaBeans对象被Web技术(也就是Jsp/ServletQ调用,那么JavaBeansp行在J2EE的Web容器中;如果它被EJB调用Q它?yu)p行在EJB容器中?/div>
  EJBQ企业JavaBeansQ是普通JavaBeans的一U提升和规范Q因Z业信息系l开发中需要一个可伸羃的性能和事务、安全机Ӟq样能保证企业系l^滑发展,而不是发展到一U规模重新更换一套Y件系l?/div>
  xQJavaBeanslg发展到EJB后,q不是说以前的那UJavaBeans形式消׃Q这p然Ş成了两种JavaBeans技术:EJB 和POJOQPOJO完全不同于EJB概念Q指的是普通JavaBeansQ而且q个JavaBeans不依附某U框Ӟ或者干脆可以说Q这?JavaBeans是你个应用程序单独开发创建的?/div>
  J2EE应用pȝ开发工h很多Q如JBuilder?Eclipse{,q些IDE首先是Java开发工P也就是说Q它们首要基本功能是可以开发出JavaBeans或Java classQ但是如果要开发出J2EEpȝQ就要落实到要么是Web技术或EJB技术,那么有可能要一些专门模块功?如eclipse需?lomboz插g)Q最重要的是Q因为J2EEpȝ区分为容器和应用两个部分Q所以,在Q何开发工具中开发J2EE都需要指定J2EE容器?/div>
  J2EE容器分ؓWEB容器和EJB容器QTomcat/Resin是Web容器QJBoss是EJB容器+Web容器{,其中Web容器直接使用 Tomcat实现的。所以你开发的Web应用E序可以在上面两U容器运行,而你开发的Web+EJB应用则只可以在JBoss服务器上q行Q商业?Websphere/Weblogic{和JBoss属于同一U性质?/div>
  J2EE容器也称为J2EE服务器,大部分时它们概念是一致的?/div>
  如果你的J2EE应用pȝ的数据库q接是通过JNDI获得Q也是说是从容器中获得Q那么你的J2EE应用pȝ基本与数据库无关Q如果你在你的J2EE 应用pȝ耦合了数据库JDBC驱动的配|,那么你的J2EE应用pȝ有数据库概念色彩,作ؓ一个成熟需要推q的J2EE应用pȝQ不推荐和具体数据库耦合Q当然这其中如何保证J2EE应用pȝq行性能又是体现你的设计水^了?/div>
  衡量J2EE应用pȝ设计开发水q高低的标准是Q解耦性;你的应用pȝ各个功能是否能够dqQ是否不怺依赖Q也只有q样Q才能体现可l护性、可拓展性的软g设计目标?/div>
  Z辑ֈq个目的Q诞生各U框架概念,J2EE框架标准一个系l划分ؓWEB和EJB主要部分Q当然我们有时不是以q个具体技术区分,而是从设计上抽象现层、服务层和持久层Q这三个层次从一个高度将J2EE分离开来,实现解耦目的?/div>
  因此Q我们实际编E中Q也要将自己的功能向q三个层ơ上靠,做到大方向清楚,泾渭分明Q但是没有技术上U束限制要做到这Ҏ(gu)很不Ҏ(gu)的,因此我们q是必须借助J2EE具体技术来实现Q这Ӟ你可以用EJB规范实现服务层和持久层,Web技术实现表现层Q?/div>
  EJBZ么能服务层从Jsp/Servlet手中分离出来Q因为它对JavaBeans~码有强制的U束Q现在有一U对JavaBeansq束,使用Ioc模式实现的(当然EJB 3.0也采取这U方式)Q在Ioc模式诞生前,一般都是通过工厂模式来对JavaBeansU束QŞ成一个服务层Q这也是是Jiveq样开源论坛设计原理之一?/div>
  由此Q将服务层从表现层中分离出来目前有两U可选架构选择Q管理普通JavaBeansQPOJOQ框??Spring、JdonFramework)以及理EJB的EJB框架Q因为EJB不只是框Ӟq是标准Q而标准可以扩展发展,所以,q两U区别将来是可能模糊Q被U_同一个标准了。 但是Q个为:标准制定是ؓ某个目的服务的,总要牺牲一些换取另外一些,所以,q两U架构会长时间ƈ存?/div>
  q两U架构分歧也曄诞生一个新名词Q完全POJO的系l也UCؓ轻量U系l?lightweight)Q其实这个名词本w就没有一个严格定义,更多是一个吸引h的招牌,轻量是指Ҏ(gu)学习Ҏ(gu)使用吗?按照q个定义Q其实轻量Spring{系lƈ不容易学习;而且EJB 3.0Q依然叫EJBQ以后的pȝ是否可称量了呢Q?/div>
  前面谈了服务层框Ӟ使用服务层框架可以将 JavaBeans从Jsp/Servlet中分d来,而用表现层框架则可以将Jsp中剩余的JavaBeans完全分离Q这部分JavaBeans 主要负责昄相关Q一般是通过标签库(taglibQ实玎ͼ不同框架有不同自q标签库,Struts是应用比较广泛的一U表现层框架?/div>
  q样Q表现层和服务层的分L通过两种框架辑ֈ目的Q剩余的是持久层框架了Q通过持久层的框架数据库存储从服务层中分d来是其目的,持久层框架有两种方向Q直接自q写JDBC{SQL语句Q如iBatisQ;使用O/R Mapping技术实现的Hibernate和JDO技术;当然q有EJB中的实体Bean技术?/div>
  持久层框架目前呈现百花齐放,各有优缺点的现状Q所以正如表现层框架一P目前没有一个框架被指定为标准框Ӟ当然Q表现层框架现在又出来了一个JSFQ它代表的页面组件概忉|一个新的发展方向,但是复杂的实现让人有些忘而却步?/div>
  在所有这些J2EE技术中Q虽然SUN公司发挥了很大的作用Q不qM来说Q网l上有这样一个评PSUN的理论天下无敌;SUN的品用h撞墙Q对于初学者,特别是那些试N过或已l通过SUN认证的初学者,赶快摆脱SUN的阴影,立即开溜,使用开源领域的产品来实现自q应用pȝ?/div>
  最后,你的J2EE应用pȝ如果采取上面提到的表现层、服务层和持久层的框架实玎ͼ基本你也可以在无需深刻掌握设计模式的情况下开发出一个高质量的应用系l了?/div>
  q要注意的是: 开发出一个高质量的J2EEpȝq需要正的业务需求理解,那么域徏模提供了一U比较切实可行的正确理解业务需求的Ҏ(gu)Q相兌l知识可从UML角度l合理解?/div>
  当然Q如果你惌计自q行业框架Q那么第一步从设计模式开始吧Q因计模式提供你一个实现JavaBeans或类之间解耦参考实现方法,当你学会了系l基本单元JavaBean或类之间解耦时Q那么系l模块之间的解耦你可能掌握,q而你可以实现行业框架的提炼了,q又是另外一个发展方向了?/div>
  以上理念可以ȝZ句话QJava学习开发三件宝: Domain ModelQ域建模Q、PatternsQ模式)和FrameworkQ框Ӟ。集三宝理念于一w,中型J2EE目快速开发工PJdon Framework
----------------------------------------------------------------------------------------------------
JoannaYe ask:
你好 Banq先生 x你的文章很长一D|间了, 对你在Java领域的技术水q?以及在很多问题上的看? 也非怽? 国内目前辑ֈ你的水^的h真是很少(当然高h也许都隐居v来了). 但是, 有几个问题想与你讨论:
首先,软g是一个绝对的应用技?M技术离开了具体的应用, 坦率地说是毫无h(hun)值的.我看,Jdon也有在这斚w的尝?如网?|上商店生成pȝ{?但这与真正的企业应用q有非常大的距离. 我不了解,你在q一领域里ؓ什么没有涉?是因Z认ؓ很困?基本上是以我们国内目前的技术水qx法到辑֑, q是因ؓ你不屑于q方面的深入, 认ؓ你所q求的是Ua然的技术概念呢.
我的其他问题有赖于了解你关于q个问题的回{?让我们l关注和讨论.
banq answer:
 
>但这与真正的企业应用q有非常大的距离. 我不了解,你在q一领域里ؓ什么没有涉?是因Z认ؓ很困?基本上是以我们国内目前的技?/div>
多谢探讨Q这个问题很复杂Q大概有下列几点Q?br />1. 现在软g技术不再象以前的技术,以前的技术可以说只有做个q个行业大型软gpȝ的经验的人才可以说对q些软g技术有掌握Q而现在的技术则不必了,J2EE 讲究架构QJ2EE它是一套应用Y件的规范Q也是_J2EE是很多做q大型Y件的行汇d的经验精华,一个大型系l需要哪些技术部分、什么时候适合什么技术,在J2EE标准中基本都有涉及,例如EJB技术、JMS{?/div>
q样Q如果你能完全掌握和Nq些J2EE架构技术,你有时确实不必一定要做个大型软gl验才型Q这UCؓ站在巨h的肩膀上?/div>
但是反过来,如果你没有丰富的软gpȝ实战l验Q你ȝ解EJB/JMS{就很困难,所以这两个技术对初学者比较难的原因之一?/div>
2. UMLl合J2EEq样OO一套实施过E从Ҏ(gu)Z及模式角度固化了软g数据库系l的分析设计开发,q也是因为有MDAQ将q些q程用Y件自动生成代码)诞生的原因。虽然这些简化了我们开发系l的q程Q但是这只是解决了应用系l的一部分问题Q工作流{尚未成熟,使用q样方式开发系l,依据我的l验Q最后会烦琐和l致的工作压在Jsp面上,目前开发一个系l,l合标签库和用户界面需求这个工作反而花Ҏ(gu)更多旉Q希望JSF在这斚w能有效率提升Q等q些技术细节都能解冻I基本J2EE非常成熟了?/div>
3.目前我通过咨询角色和一些Y件公怸h接一些企业应用项目,例如d承接一个大型外资h事系l,他们要求理GE {几家外资企业的Z利Q这些企业外包h事给他们Q,如果专ؓ一家公司开发h事很单,但是要求q个Z适合多家Q那么重用性要求很高,设计抽象面很高,他们在新加坡有类似系l,但技术很老,我听q新加坡的系l,他们也有一些经验ȝQ大部分和我的J2EE设计相吻合,我和新加坡的Z过xQ他们很惊奇Q不太相信,加上费用问题Q只q行了初步架构设计就搁浅了?/div>
4.不要看|站pȝQ以前网站系l都是用PHP Perl做,功能很弱Q无法和企业pȝ相比Q但是随着Inernet普及Q更多h要求联网Q例如如果一家公司的ERP通过互联|实玎ͼ那么老d差就很方便,但是现在Z家公司开发一个基于internet的ERP很贵Q比传统的贵Q这不合理,q也是SOA提出的目的之一Q以后ERP实现|上U用Q就象你甌一个Blog或论坛或EmailQ你可以Z的企业申请一个ERPpȝQ这样只要企业付U费可以了Q这可理想目前已l接q,前段旉国一家提供这U服务的企业来上做宣传Q他们的业W增长速度极其?500%.
通过|站提供ERP{企业服务对于Y件设计的重用性要求很高,׃套邮ql可以服务很多用户一P你必设计出一套重要性、灵zL很高的ERPpȝ适合不同的用P可见|站软g的水qx极其高的。前面我做的|站自动生成pȝ到现在我都认为完成不够好Q现在很多网站都提供q种服务Q这象BlogQ但是Blog{只限制你网站模板,而不是自由定刉面,所?Blogq些都是孩玩家ӞҎ(gu)无发走向商业Q著名的那个方兴东鼓吹BlogQ其实没有技术革斎ͼ靠你媒体吹呼是革命了?
 
JoannaYe ask:
谢谢 Banq 先生??3日非常认真的回复(抱歉׃?没能马上回复). ȝh, 如果我的理解不错的话, 你的l论?1)你认为网站系lƈ不可觑(同意,一个高讉K?同时能够实现|上交易的网站的如?.2)EJB/JMS技术对于初学者来说是不容?但是对你来说,你是可以Handdle? 3)你也有承接企业系l的实际l验,象你说的那个HRpȝ. 但不知?zhn)以咨询n份参加的q个HRpȝ到底都解决的是实际管理中的什么样的问?在性能斚w都达C什么样的水q? 具体来说,采用了哪些技?诸如(zhn)帖中提到的一些技?应对了实际中具体的什么样的问? 此外以你在这个HRpȝ的经验来? 是一个多h的Team,采取什么样的开发方式和开发进?人员和时间的分配比例)开发的.你认为在q样的一个项目的开发过E中最关键的是什?最影响 Prductivity的又是什?
对这样一些问题看上去g很空?但是实际上能够真正反映出我一开始提出的 issue,"软g是一个绝对的应用技?M技术离开了具体的应用, 坦率地说是毫无h(hun)值的".举个例子来说,书本?名家们会告诉? Value List Handler q个设计模式是解册L问题:"You have a remote client that wants to iterate over a large results list." 一般来?如果是一个大量地查找某一?topic/dimension"下的数据,q样的问?我们也毫无疑问地定要用到这个模?但是,如果对一条具体的数据,如某一个销售员,要和他的客户讨论(在线谈判)他们之间的一个具体合?q时候会不会也需要用到这个模?如果要用q个模式,到底是用 Stateful Session Bean q是?Stateless Session Bean 实现?他们各自在实现方法上Ҏ(gu)能的媄响是什? 当你军_采用了某U实现方?你到底是怎样Tradeoff的呢; 最后对q个设计模式来说,在最l的设计Ҏ(gu)中如何把它抽象到对一个通用?普遍的业务问?而不是仅仅对"某一个销售员,要和他的客户讨论他们之间的一个具体合?q样的一个特例问?作出一个通用的解x?适应L规模,L业务的企?真正辑ֈ软g工程的目?高度的Reusing ?Scalablity. 实际的企业应用系l就是充满着cMq样的问?很有挑战.但有些技术h员就仅仅满于自己可以用某项技术做Z些小的Demo?׃愿意,或根本不屑于深入下去面对一个实际的应用问题.
因此, 我相信?zhn)应该能够非常理?我ؓ什么感兴趣了解(zhn)对我上面提出问题答?
(zhn)的很多看法都很不错, 我非常同? 希望我们能在今后q一步深入地探讨. 谢谢!
banq answer:
>你认为在q样的一个项目的开发过E中最关键的是什?最影响 Prductivity的又是什?
当这L目使用框架lgl合后,׃pȝ重要重用的功能已l封装在框架软g中,所以,只要能够l装出应用系l,一般第一ơ测试就会立即通过Q我已经不止一ơ体会这U快感,我现在基本告别以前那U花费大量时间在Java调试上时代,我相信很多初学者还在这个惔潭里挣扎Q这成为媄响一个品的主要原因Q现在用jdon框架开发,几乎消灭q个因素?/div>
那么,现在最影响 Prductivity的是什么?是技术外的因素:目理?/div>
关于你提的性能斚w设计辑ֈ什么水q等Q这些我已经整合q入Jdon框架Q用Jdon框架开发,几乎无需考虑性能设计Q一开始就h优越的性能Q这些都是有试数据QJava产品的好处就是一切可以自己动手,不必听从W三方评P因ؓ那些都有失公正,服务器配|上Jprofile/OptimizeitQ客L配置JmeterQ启动几个线E一跑,Jdon框架和应用程序的性能真相出来了Q所以,在Java领域Q开源和商业产品是在同一赯U,面对不同的用P前者是更有头脑Q自己动手;后者是对自q乏自信的人;服务是两者的重点?/div>
>在最l的设计Ҏ(gu)中如何把它抽象到对一个通用?普遍的业务问?而不>是仅仅对"某一个销售员,要和他的客户讨论他们之间的一个具体合?q?gt;L一个特例问?/div>
其实你说的行业框架提炼的问题Q这和业务相养IJdon框架{都是基框架Q没有这些组件框架的优雅解决方式Q就没有行业框架的好的开始,我想你不希望在行业框架提g后,发现无法加入一些纵向功能,p数据库设计好之后Q几q以后却成ؓ你发展的障碍?/div>
行业框架需要资q行业背景Q这也不是一般h做的Q但是工作流/Portal{都是行业框架的提炼Q这些也是我们以后发展的方向?/div>
我个h来说Q我愿意解决重要问题Q然后我告诉更多x向,如果他们怿Q大家一起努力来解决所有问题,而不是靠我一个h解决所有问题?/div>
JoannaYe ask:
谢谢Banq先生的回? 你的很多观点都很?我非常同?象你所说最影响Prductivity的是技术外的因素:目理. 但我不知你能不能有一些具体的看法.因ؓM行业,最l的问题, 竞争力的问题都是如何通过理来提高Prductivity. 不知你对软gq一行业有没有特别的见解.
开源项目的有它的优势,特别是作q些开源项目的?往往是一些技术的_英.但是, 我还是以为应该以成熟的Commercial产品作ؓ自己开发的基础,x?巨h的肩膀". q是因ؓ, 成功的Commercial产品往往更注重最l用? q是q些产品能够l它的公司带来巨大的商业利润的源?U技术的专家往往会忽视这一?
要成׃件事(一个大型企业管理应用的目), 是需要很多ht踏实实,坚持不懈(q也非常重要)的努?q和M上课,或者在场外指导一?有很大的区别.
我希望通过你这个论? l识一些志同道合的朋友, 能够作成q样一件事.再次谢谢你的回复, 我因为很多时候很?有一些Deadline非常紧的事情,有时没能马上l?zhn)回? 请你见谅.
banq answer:
非常感谢JoannaYe 讨论Q从aZ感觉你是一个职业的目l理。非怸业?/div>
目l理和设计师良好沟通和理解交流Q是一个项目成功的关键?/div>
关于开源和Commercial区别Q我个h觉得它们之间真的没有严格的区别,只不q是两种思\的表玎ͼ开源通过免费产品卖服务;Commercial是既惛_产品又卖服务Q不能因为它的品卖钱,是技术好Q一般是市场品牌好?/div>
拿EJB实现来说Q在所有J2EE服务器中只有开源JBoss 4.0使用AOP实现Q坚持AOP的一些纯设计z认为EJBq时了,那么Weblogic /Websphere{这些以支持EJB自诩的服务器产品反而不如开源品呢。这些h认ؓQEJB
但是正如你说Qؓ什么客戯是购买Websphere{服务器Q因为它们注重最l用戗?/div>
我认Z直试囑֜q两者之间寻扑^衡是挑战的事情?/div>
-------------------------------------------------------------------------------------------------------------------
 
shuiwx ask:
 
banq老师好,最q大致抽象ȝZ一个比较浅昄规律Q既是?zhn)q_一两个月能够发一比较的适合初学者的帖子Q但每一都可以对偶的有关知识的梳理和导向能够v到很重要的作用,不敢说终生受用但也似乎会持久隑ֿ了,在此q是要道一声感谢?/div>
既然题目是初学?..高质量的J2EEpȝQ那么就题目本nq个用例来说Q参与者该是“novice”了Q领域模型应该是"高质量的"+"J2EEpȝ ",那么能否h再深一步的举个样例来说明何?high quality j2ee system"呢?估计(zhn)不会选petshop,但有可能会将jive和jdon进来,但偶真正想看到的是一个就(zhn)个人来讲曾l有q?consultantl验的项目作Z子来要阐qC高质?j2eepȝ的概貌,或者象(zhn)前面某论oo和数据库的矛盄文章一P能否前瞻性的l出一个在(zhn)心目中最理想的高质量j2eepȝ的轮廓呢Q比如jsf(new version>1.1)+ejb3.0+j2ee设计模式?偶觉得struts+spring+hibernateq不敢称为高质量的或?j2eepȝQ所以总觉得从现在开始既该有意识的用一下jsf+ejb3来设计了Q但׃不知道有没有人在q方面开始吃螃蟹了,所以只好去随大的兛_些什么ajax,xp之类的流行名词了。但从内心来Ԍ无论是javascriptq是lg式编E,无论是spring+hibernateq是ejb3, 无论是xpq是fdd,无非是想量按照客户的要求迅速提交一个界面新颖,l构E_的一个能够跨q_的良好的pȝ吧。假如能预知何ؓ一个好的系l的话,g事情会变的简单些Q也׃必ؓ那些喋喋不休的争论着技术名词的Z所困扰了?/div>
但由于目前偶的能力所限和所处的时期的特D性,g想马上就拿jsf+ejb3来首选做企业U开发还有点不现实,那么作ؓ一个apprentice来说Q能够做的似乎只有学习模式了Q偶不知道关于模式该学到多深才合适,只相信尽量选择从徏模的时候就配合着设计模式来考虑可能会有助于pȝ的稳定和重用Q谈到这里有引申出关于题目的另外一个话题,是 “初学者”,偶觉得如果想作ؓ计算机编Eh员的话,面对着不停的新技术名词和版本更PQ似乎偶总要做一名初学着来的_于是最q有意识的在看一些数据结构方面的评Q希望能够从一些理论基中来L那些所谓的新技术背后所蕴涵的知识,但还是那句话Q由于能力有限,所得甚,所以希望?zhn)如果能站在一个咨询家的角度来看,能否指点一下,?zhn)认ؓ的如果想设计一个好的Y件系l来_或许不仅限于j2ee,该多看看哪些computer science中的理论知识呢?偶不知道q个问题提的对不对,但总觉得设计模式对于系l的意义Q是cM于数据结构和法之相对于E序的意义的Q所以假如?zhn)在类似的斚w能有些心得的话,希望能够得到一Ҏ(gu)炏V?/div>
Q偶的废话似乎不,希望banq老师能忍受)
 
banq answer:
很抱歉现在才回复你的问题Q?br />>如果惌计一个好的Y件系l来_或许不仅限于j2ee,该多看看哪些>computer science中的理论知识
设计一个好的Y件系l我文章里其实写了,掌握分层解耦宗旨,学习使用一些现成的框架可以了Q如果你不原意囫囵吞枣,那么研究一下这些框架设计原理和模式Q这些会p你很长探索,数据l构、编译原理这些已l成为底层机Ӟp汇编是底层一P现在的大学计机教学完全是错误的Q学习的都是正确的废话。所以没有必要在那些大学评上浪Ҏ(gu)间?/div>
增强目l验Q研L码,自己动手~写目是提升水q的唯一道\?br />以上只是我个人意见?/div>

]]>一关于session的好?/title><link>http://www.tkk7.com/renyangok/archive/2006/12/31/91104.html</link><dc:creator>保尔?/dc:creator><author>保尔?/author><pubDate>Sun, 31 Dec 2006 02:10:00 GMT</pubDate><guid>http://www.tkk7.com/renyangok/archive/2006/12/31/91104.html</guid><wfw:comment>http://www.tkk7.com/renyangok/comments/91104.html</wfw:comment><comments>http://www.tkk7.com/renyangok/archive/2006/12/31/91104.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/renyangok/comments/commentRss/91104.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/renyangok/services/trackbacks/91104.html</trackback:ping><description><![CDATA[  <div id="1r5hdrz" class="ContentFont" id="NewaspContentLabel" style="PADDING-RIGHT: 10px; DISPLAY: block; PADDING-LEFT: 10px; PADDING-BOTTOM: 0px; PADDING-TOP: 0px"><font id="font_word" style="FONT-SIZE: 14px; FONT-FAMILY: 宋体,Verdana,Arial,Helvetica,sans-serif"><p><font size="2">作者:郎云鹏(dev2dev ID: hippiewolfQ?/font></p><p><font size="2">摘要Q虽然session机制在web应用E序中被采用已经很长旉了,但是仍然有很多h不清楚session机制的本质,以至不能正确的应用这一技术。本文将详细讨论session的工作机制ƈ且对在Java web application中应用session机制时常见的问题作出解答?/font></p><p><font size="2">目录Q?br /></font><a ><font size="2">一、术语session</font></a><br /><a ><font size="2">二、HTTP协议与状态保?/font></a><br /><a ><font size="2">三、理解cookie机制</font></a><br /><a ><font size="2">四、理解session机制</font></a><br /><a ><font size="2">五、理解javax.servlet.http.HttpSession</font></a><br /><a ><font size="2">六、HttpSession常见问题</font></a><br /><a ><font size="2">七、跨应用E序的session׃n</font></a><br /><a ><font size="2">八、ȝ</font></a><br /><a ><font size="2">参考文?/font></a></p><p id="#1"><font size="2"><b>一、术语session</b><br />在我的经验里Qsessionq个词被滥用的程度大概仅ơ于transactionQ更加有的是transaction与session在某些语境下的含义是相同的?/font></p><p><font size="2">sessionQ中文经常翻译ؓ会话Q其本来的含义是指有始有l的一pd动作/消息Q比如打电话时从拿v电话拨号到挂断电话这中间的一pdq程可以UCZ?session。有时候我们可以看到这L话“在一个浏览器会话期间Q?..”,q里的会话一词用的就是其本义Q是指从一个浏览器H口打开到关闭这个期?①。最混ؕ的是“用P客户端)在一ơ会话期间”这样一句话Q它可能指用L一pd动作Q一般情况下是同某个具体目的相关的一pd动作Q比如从d到选购商品到结账登样一个网上购物的q程Q有时候也被称Z个transactionQ,然而有时候也可能仅仅是指一ơ连接,也有可能是指含义①,其中的差别只能靠上下文来推断②?/font></p><p><font size="2">然而当session一词与<a class="wordstyle" target="_blank">|络</a>协议相关联时Q它又往往隐含了“面向连接”和/或“保持状态”这样两个含义,“面向连接”指的是在通信双方在通信之前要先建立一个通信的渠道,比如打电话,直到Ҏ(gu)接了电话通信才能开始,与此相对的是写信Q在你把信发出去的时候你q不能确认对方的地址是否正确Q通信渠道不一定能建立Q但对发信h来说Q通信已经开始了。“保持状态”则是指通信的一方能够把一pd的消息关联v来,使得消息之间可以互相依赖Q比如一个服务员能够认出再次光的老顾客ƈ且记得上ơ这个顾客还Ơ店里一块钱。这一cȝ例子有“一个TCP session”或者“一个POP3 session”③?/font></p><p><font size="2">而到了web服务器蓬勃发展的时代Qsession在web开发语境下的语义又有了新的扩展Q它的含义是指一cȝ来在客户端与服务器之间保持状态的解决Ҏ(gu) ④。有时候session也用来指q种解决Ҏ(gu)的存储结构,如“把xxx保存在session里”⑤。由于各U用于web开发的语言在一定程度上都提供了对这U解x案的支持Q所以在某种特定语言的语境下Qsession也被用来指代该语a的解x案,比如l常把Java里提供的 javax.servlet.http.HttpSessionUCؓsession⑥?/font></p><p><font size="2">鉴于q种混ؕ已不可改变,本文中session一词的q用也会Ҏ(gu)上下文有不同的含义,请大家注意分辨?br />在本文中Q用中文“浏览器会话期间”来表达含义①,使用“session机制”来表达含义④,使用“session”表辑֐义⑤Q用具体的“HttpSession”来表达含义?/font></p><p id="#2"><font size="2"><b>二、HTTP协议与状态保?/b><br />HTTP协议本n是无状态的Q这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器h<a class="wordstyle" target="_blank">下蝲</a>某些文gQ无论是客户端还是服务器都没有必要纪录彼此过ȝ行ؓQ每一ơ请求之间都是独立的Q好比一个顾客和一个自动售货机或者一个普通的Q非会员Ӟ大卖Z间的关系一栗?/font></p><p><font size="2">然而聪明(或者贪心?Q的Z很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用Q就像给有线电视加上Ҏ(gu)功能一栗这U需求一斚wq HTML逐步d了表单、脚本、DOM{客L行ؓQ另一斚w在服务器端则出现了CGI规范以响应客L的动态请求,作ؓ传输载体的HTTP协议也添加了文g上蝲、cookieq些Ҏ(gu)。其中cookie的作用就是ؓ了解决HTTP协议无状态的~陷所作出的努力。至于后来出现的session机制则是又一U在客户端与服务器之间保持状态的解决Ҏ(gu)?/font></p><p><font size="2">让我们用几个例子来描qC下cookie和session机制之间的区别与联系。笔者曾l常ȝ一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠Q然而一ơ性消?杯咖啡的Z微乎其微Q这时就需要某U方式来U录某位֮的消Ҏ(gu)量。想象一下其实也无外乎下面的几种Ҏ(gu)Q?br />1、该店的店员很厉宻I能记住每位顾客的消费数量Q只要顾客一走进咖啡店,店员q道该怎么对待了。这U做法就是协议本w支持状态?br />2、发l顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每ơ消Ҏ(gu)Q如果顾客出C张卡片,则此ơ消费就会与以前或以后的消费相联pv来。这U做法就是在客户端保持状态?br />3、发l顾客一张会员卡Q除了卡号之外什么信息也不纪录,每次消费Ӟ如果֮出示该卡片,则店员在店里的纪录本上找到这个卡号对应的U录d一些消费信息。这U做法就是在服务器端保持状态?/font></p><p><font size="2">׃HTTP协议是无状态的Q而出于种U考虑也不希望使之成ؓ有状态的Q因此,后面两种Ҏ(gu)成为现实的选择。具体来说cookie机制采用的是在客L保持状态的Ҏ(gu)Q而session机制采用的是在服务器端保持状态的Ҏ(gu)。同时我们也看到Q由于采用服务器端保持状态的Ҏ(gu)在客L也需要保存一个标识,所以session机制可能需要借助于cookie机制来达C存标识的目的Q但实际上它q有其他选择?/font></p><p id="#3"><font size="2"><b>三、理解cookie机制</b><br />cookie机制的基本原理就如上面的例子一L单,但是q有几个问题需要解冻I“会员卡”如何分发;“会员卡”的内容Q以及客户如何用“会员卡”?/font></p><p><font size="2">正统的cookie分发是通过扩展HTTP协议来实现的Q服务器通过在HTTP的响应头中加上一行特D的指示以提C浏览器按照指示生成相应的cookie。然而纯_的客户端脚本如Javascript或者VBscript也可以生成cookie?/font></p><p><font size="2">而cookie 的用是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器查所有存储的cookieQ如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置Q则把该cookie附在h资源的HTTPh头上发送给服务器。意思是麦当劳的会员卡只能在麦当劳的店里出示Q如果某家分店还发行了自q会员卡,那么q这家店的时候除了要出示麦当劳的会员卡,q要出示q家店的会员卡?/font></p><p><font size="2">cookie的内容主要包括:名字Q|q期旉Q\径和域?br />其中域可以指定某一个域比如.google.comQ相当于d招牌Q比如宝z公司,也可以指定一个域下的具体某台机器比如www.google.com或者f(xi)roogle.google.comQ可以用飘柔来做比?br />路径是跟在域名后面的URL路径Q比?或?foo{等Q可以用某飘柔专柜做比?br />路径与域合在一起就构成了cookie的作用范围?br />如果不设|过期时_则表C个cookie的生命期为浏览器会话期间Q只要关闭浏览器H口Qcookie消׃。这U生命期为浏览器会话期的 cookie被称Z话cookie。会话cookie一般不存储在硬盘上而是保存在内存里Q当然这U行为ƈ不是规范规定的。如果设|了q期旉Q浏览器׃把cookie保存到硬盘上Q关闭后再次打开览器,q些cookie仍然有效直到过讑֮的过期时间?/font></p><p><font size="2">存储在硬盘上的cookie可以在不同的览器进E间׃nQ比如两个IEH口。而对于保存在内存里的cookieQ不同的览器有不同的处理方式。对?IEQ在一个打开的窗口上按Ctrl-NQ或者从文g菜单Q打开的窗口可以与原窗口共享,而用其他方式新开的IEq程则不能共享已l打开的窗口的内存 cookieQ对于Mozilla Firefox0.8Q所有的q程和标{N都可以共享同Lcookie。一般来说是用javascript的window.open打开的窗口会与原H口׃n内存cookie。浏览器对于会话cookie的这U只认cookie不认人的处理方式l常l采用session机制的web应用E序开发者造成很大的困扰?/font></p><p><font size="2">下面是一个goolge讄cookie的响应头的例?br />HTTP/1.1 302 Found<br />Location: http://www.google.com/intl/zh-CN/<br />Set-Cookie: PREF=ID=0565f77e132de138:NW=1:TM=1098082649:LM=1098082649:S=KaeaCFPo49RiA_d8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com<br />Content-Type: text/html</font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/200562922161847.jpg" width="408" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><br /><font size="2">q是使用HTTPLookq个HTTP Sniffer<a class="wordstyle" target="_blank">软g</a>来俘LHTTP通讯U录的一部分</font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/200562922167755.jpg" width="432" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><br /><font size="2">览器在再次讉Kgoolge的资源时自动向外发送cookie</font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221613750.jpg" width="421" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><br /><font size="2">使用Firefox可以很容易的观察现有的cookie的?br />使用HTTPLook配合Firefox可以很容易的理解cookie的工作原理?/font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221620917.jpg" width="324" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><br /><font size="2">IE也可以设|在接受cookie前询?/font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221623485.jpg" width="239" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><br /><font size="2">q是一个询问接受cookie的对话框?/font></p><p id="#4"><font size="2"><b>四、理解session机制</b><br />session机制是一U服务器端的机制Q服务器使用一U类g散列表的l构Q也可能是使用散列表)来保存信息?/font></p><p><font size="2">当程序需要ؓ某个客户端的h创徏一个session的时候,服务器首先检查这个客L的请求里是否已包含了一个session标识 - UCؓsession idQ如果已包含一个session id则说明以前已lؓ此客L创徏qsessionQ服务器按照session id把这个session索出来用(如果索不刎ͼ可能会新Z个)Q如果客Lh不包含session idQ则为此客户端创Z个sessionq且生成一个与此session相关联的session idQsession id的值应该是一个既不会重复Q又不容易被扑ֈ规律以仿造的字符Ԍq个session id被在本ơ响应中q回l客L保存?/font></p><p><font size="2">保存q个session id的方式可以采用cookieQ这样在交互q程中浏览器可以自动的按照规则把q个标识发挥l服务器。一般这个cookie的名字都是类g SEEESIONIDQ而。比如weblogic对于web应用E序生成的cookieQJSESSIONID= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764Q它的名字就?JSESSIONID?/font></p><p><font size="2">׃ cookie可以被h为的止Q必L其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一U技术叫做URL重写Q就是把session id直接附加在URL路径的后面,附加方式也有两种Q一U是作ؓURL路径的附加信息,表现形式为http://...../xxx; jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764<br />另一U是作ؓ查询字符串附加在URL后面Q表现Ş式ؓhttp://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764<br />q两U方式对于用h说是没有区别的,只是服务器在解析的时候处理的方式不同Q采用第一U方式也有利于把session id的信息和正常E序参数区分开来?br />Z在整个交互过E中始终保持状态,必d每个客户端可能请求的路径后面都包含这个session id?/font></p><p><font size="2">另一U技术叫做表单隐藏字Dc就是服务器会自动修改表单,d一个隐藏字D,以便在表单提交时能够把session id传递回服务器。比如下面的表单<br /><form name="testform" action="/xxx"><br /><input type="text"><br /></form><br />在被传递给客户端之前将被改写成<br /><form name="testform" action="/xxx"><br /><input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"><br /><input type="text"><br /></form><br />q种技术现在已较少应用Q笔者接触过的很古老的iPlanet6(SunONE应用服务器的前n)׃用了q种技术?br />实际上这U技术可以简单的用对action应用URL重写来代ѝ?/font></p><p><font size="2">在谈论session机制的时候,常常听到q样一U误解“只要关闭浏览器Qsession消׃”。其实可以想象一下会员卡的例子,除非֮d对店家提出销卡,否则店家l对不会L删除֮的资料。对session来说也是一LQ除非程序通知服务器删除一个sessionQ否则服务器会一直保留,E序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会d在关闭之前通知服务器它?yu)要关闭Q因此服务器Ҏ(gu)不会有机会知道浏览器已经关闭Q之所以会有这U错觉,是大部分session机制都用会话cookie来保存session idQ而关闭浏览器后这个session id消׃Q再ơ连接服务器时也无法找到原来的session。如果服务器讄的cookie被保存到盘上,或者用某U手D|写浏览器发出?HTTPh_把原来的session id发送给服务器,则再ơ打开览器仍然能够找到原来的session?/font></p><p><font size="2">恰恰是由于关闭浏览器不会Dsession被删除,q服务器ؓseesion讄了一个失效时_当距dL上一ơ用session的时间超q这个失效时间时Q服务器可以认为客L已经停止了活动,才会把session删除以节省存储空间?/font></p><p id="#5"><font size="2"><b>五、理解javax.servlet.http.HttpSession</b><br />HttpSession是Javaq_对session机制的实现规范,因ؓ它仅仅是个接口,具体到每个web应用服务器的提供商,除了对规范支持之外,仍然会有一些规范里没有规定的细微差异。这里我们以BEA的Weblogic Server8.1作ؓ例子来演C?/font></p><p><font size="2">首先QWeblogic Server提供了一pd的参数来控制它的HttpSession的实玎ͼ包括使用cookie的开关选项Q用URL重写的开关选项Qsession持久化的讄Qsession失效旉的设|,以及针对cookie的各U设|,比如讄cookie的名字、\径、域Qcookie的生存时间等?/font></p><p><font size="2">一般情况下Qsession都是存储在内存里Q当服务器进E被停止或者重启的时候,内存里的session也会被清I,如果讄了session的持久化Ҏ(gu),服务器就会把session保存到硬盘上Q当服务器进E重新启动或q些信息能够被再次使用QWeblogic Server支持的持久性方式包括文件、数据库、客Lcookie保存和复制?/font></p><p><font size="2">复制严格说来不算持久化保存,因ؓsession实际上还是保存在内存里,不过同样的信息被复制到各个cluster内的服务器进E中Q这样即使某个服务器q程停止工作也仍然可以从其他q程中取得session?/font></p><p><font size="2">cookie生存旉的设|则会媄响浏览器生成的cookie是否是一个会话cookie。默认是使用会话cookie。有兴趣的可以用它来试验我们在第四节里提到的那个误解?/font></p><p><font size="2">cookie的\径对于web应用E序来说是一个非帔R要的选项QWeblogic Server对这个选项的默认处理方式得它与其他服务器有明昄区别。后面我们会专题讨论?/font></p><p><font size="2">关于session的设|参考[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869</font></p><p id="#6"><font size="2"><b>六、HttpSession常见问题</b><br />Q在本小节中session的含义ؓ⑤和⑥的混合Q?/font></p><p><br /><font size="2">1、session在何时被创徏<br />一个常见的误解是以为session在有客户端访问时p创徏Q然而事实是直到某server端程序调?HttpServletRequest.getSession(true)q样的语句时才被创徏Q注意如果JSP没有昄的?<%@page session="false"%> 关闭sessionQ则JSP文g在编译成Servlet时将会自动加上这样一条语句HttpSession session = HttpServletRequest.getSession(true);q也是JSP中隐含的session对象的来历?/font></p><p><font size="2">׃session会消耗内存资源,因此Q如果不打算使用sessionQ应该在所有的JSP中关闭它?/font></p><p><font size="2">2、session何时被删?br />l合前面的讨论,session在下列情况下被删除a.E序调用HttpSession.invalidate();或b.距离上一ơ收到客L发送的session id旉间隔过了session的超时设|?或c.服务器进E被停止Q非持久sessionQ?/font></p><p><font size="2">3、如何做到在览器关闭时删除session<br />严格的讲Q做不到q一炏V可以做一点努力的办法是在所有的客户端页面里使用javascript代码window.oncolose来监视浏览器的关闭动作,然后向服务器发送一个请求来删除session。但是对于浏览器崩溃或者强行杀死进E这些非常规手段仍然无能为力?/font></p><p><font size="2">4、有个HttpSessionListener是怎么回事<br />你可以创Llistenerȝ控session的创建和销毁事Ӟ使得在发生这L事g时你可以做一些相应的工作。注意是session的创建和销毁动作触发listenerQ而不是相反。类似的与HttpSession有关的listenerq有 HttpSessionBindingListenerQHttpSessionActivationListener?HttpSessionAttributeListener?/font></p><p><font size="2">5、存攑֜session中的对象必须是可序列化的?br />不是必需的。要求对象可序列化只是ؓ了session能够在集中被复制或者能够持久保存或者在必要时server能够暂时把session交换出内存。在 Weblogic Server的session中放|一个不可序列化的对象在控制C会收C个警告。我所用过的某个iPlanet版本如果session中有不可序列化的对象Q在session销毁时会有一个ExceptionQ很奇怪?/font></p><p><font size="2">6、如何才能正的应付客户端禁止cookie的可能?br />Ҏ(gu)有的URL使用URL重写Q包括超链接Qform的actionQ和重定向的URLQ具体做法参见[6]<br />http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770</font></p><p><font size="2">7、开两个览器窗口访问应用程序会使用同一个sessionq是不同的session<br />参见W三节对cookie的讨论,对session来说是只认id不认人,因此不同的浏览器Q不同的H口打开方式以及不同的cookie存储方式都会对这个问题的{案有媄响?/font></p><p><font size="2">8、如何防止用h开两个览器窗口操作导致的session混ؕ<br />q个问题与防止表单多ơ提交是cM的,可以通过讄客户端的令牌来解冟뀂就是在服务器每ơ生成一个不同的idq回l客LQ同时保存在session里,客户端提交表单时必须把这个id也返回服务器Q程序首先比较返回的id与保存在session里的值是否一_如果不一致则说明本次操作已经被提交过了。可以参看《J2EE核心模式》关于表C层模式的部分。需要注意的是对于用javascript window.open打开的窗口,一般不讄q个idQ或者用单独的idQ以防主H口无法操作Q徏议不要再window.open打开的窗口里做修Ҏ(gu)作,q样可以不用设|?/font></p><p><font size="2">9、ؓ什么在Weblogic Server中改变session的值后要重新调用一ơsession.setValue<br />做这个动作主要是Z在集环境中提示Weblogic Server session中的值发生了改变Q需要向其他服务器进E复制新的session倹{?/font></p><p><font size="2">10、ؓ什么session不见?br />排除session正常失效的因素之外,服务器本w的可能性应该是微乎其微的,虽然W者在iPlanet6SP1加若q补丁的Solaris版本上倒也遇到q;览器插件的可能性次之,W者也遇到q?721插g造成的问题;理论上防火墙或者代理服务器在cookie处理上也有可能会出现问题?br />出现q一问题的大部分原因都是E序的错误,最常见的就是在一个应用程序中去访问另外一个应用程序。我们在下一节讨个问题?/font></p><p id="#7"><font size="2">七、跨应用E序的session׃n<br /><br />常常有这L情况Q一个大目被分割成若干项目开发,Z能够互不q扰Q要求每个小目作ؓ一个单独的web应用E序开发,可是C最后突然发现某几个项目之间需要共享一些信息,或者想使用session来实现SSO(single sign on)Q在session中保存login的用户信息,最自然的要求是应用E序间能够访问彼此的session?/font></p><p><font size="2">然而按照Servlet规范Qsession的作用范围应该仅仅限于当前应用程序下Q不同的应用E序之间是不能够互相讉KҎ(gu)的session的。各个应用服务器从实际效果上都遵守了q一规范Q但是实现的l节却可能各有不同,因此解决跨应用程序session׃n的方法也各不相同?/font></p><p><font size="2">首先来看一下Tomcat是如何实现web应用E序之间session的隔ȝQ从Tomcat讄的cookie路径来看Q它对不同的应用E序讄?cookie路径是不同的Q这样不同的应用E序所用的session id是不同的Q因此即使在同一个浏览器H口里访问不同的应用E序Q发送给服务器的session id也可以是不同的?br /></font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221626822.jpg" width="288" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221626261.jpg" width="257" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><font size="2">Ҏ(gu)q个Ҏ(gu),我们可以推测Tomcat中session的内存结构大致如下?br /></font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221626479.jpg" width="444" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><font size="2">W者以前用q的iPlanet也采用的是同L方式Q估计SunONE与iPlanet之间不会有太大的差别。对于这U方式的服务器,解决的思\很简单,实际实行h也不难。要么让所有的应用E序׃n一个session idQ要么让应用E序能够获得其他应用E序的session id?/font></p><p><font size="2">iPlanet中有一U很单的Ҏ(gu)来实现共享一个session idQ那是把各个应用程序的cookie路径都设?Q实际上应该?NASAppQ对于应用程序来讲它的作用相当于根)?br /><session-info><br /><path>/NASApp</path><br /></session-info></font></p><p><font size="2">需要注意的是,操作׃n的session应该遵@一?a class="wordstyle" target="_blank">~程</a>U定Q比如在session attribute名字的前面加上应用程序的前缀Q得setAttribute("name", "neo")变成setAttribute("app1.name", "neo")Q以防止命名I间冲突Q导致互相覆盖?/font></p><p><br /><font size="2">在Tomcat 中则没有q么方便的选择。在Tomcat版本3上,我们q可以有一些手D|׃nsession。对于版?以上的TomcatQ目前笔者尚未发现简单的办法。只能借助于第三方的力量,比如使用文g、数据库、JMS或者客LcookieQURL参数或者隐藏字D늭手段?/font></p><p><font size="2">我们再看一下Weblogic Server是如何处理session的?br /></font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221627653.jpg" width="288" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221630550.jpg" width="269" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><font size="2">从截屏画面上可以看到Weblogic ServerҎ(gu)有的应用E序讄的cookie的\径都?Q这是不是意味着在Weblogic Server中默认的可以共享session了呢Q然而一个小实验卛_证明即不同的应用程序用的是同一个sessionQ各个应用程序仍然只能访问自己所讄的那些属性。这说明Weblogic Server中的session的内存结构可能如?br /></font></p><p align="center"><font size="2"><img onmousewheel="return bbimg(this)" style="CURSOR: pointer" onclick="javascript:window.open(this.src);" src="http://www.supcode.com/Article/UploadPic/2005-6/2005629221630874.jpg" width="420" onload="javascript:if(this.width>screen.width-600)this.style.width=screen.width-600;" border="0" /></font></p><p><font size="2">对于q样一U结构,在session机制本n上来解决session׃n的问题应该是不可能的了。除了借助于第三方的力量,比如使用文g、数据库、JMS或者客LcookieQURL参数或者隐藏字D늭手段Q还有一U较为方便的做法Q就是把一个应用程序的session攑ֈServletContext 中,q样另外一个应用程序就可以从ServletContext中取得前一个应用程序的引用。示例代码如下,</font></p><p><font size="2">应用E序A<br />context.setAttribute("appA", session); </font></p><p><font size="2">应用E序B<br />contextA = context.getContext("/appA");<br />HttpSession sessionA = (HttpSession)contextA.getAttribute("appA"); </font></p><p><font size="2">值得注意的是q种用法不可ULQ因为根据ServletContext的JavaDocQ应用服务器可以处于安全的原因对于context.getContext("/appA");q回I|以上做法在Weblogic Server 8.1中通过?/font></p><p><font size="2">那么Weblogic ServerZ么要把所有的应用E序的cookie路径都设?呢?原来是ؓ了SSOQ凡是共享这个session的应用程序都可以׃n认证的信息。一个简单的实验可以证明这一点,修改首先d的那个应用程序的描述Wweblogic.xmlQ把cookie路径修改?appA讉K另外一个应用程序会重新要求dQ即使是反过来,先访问cookie路径?的应用程序,再访问修改过路径的这个,虽然不再提示dQ但是登录的用户信息也会丢失。注意做q个实验时认证方式应该用FORMQ因为浏览器和web服务器对basic认证方式有其他的处理方式Q第二次h的认证不是通过session来实现的。具体请参看[7] secion 14.8 AuthorizationQ你可以修改所附的CZE序来做q些试验?/font></p><p id="#8"><font size="2">八、ȝ<br />session机制本nq不复杂Q然而其实现和配|上的灵zL却使得具体情况复杂多变。这也要求我们不能把仅仅某一ơ的l验或者某一个浏览器Q服务器的经验当作普遍适用的经验,而是始终需要具体情况具体分析?/font></p><p><font size="2">关于作者:<br />郎云鹏(dev2dev ID: hippiewolfQ,<a class="wordstyle" target="_blank">软g</a>工程师,从事J2EE开?br />电子邮gQlangyunpeng@yahoo.com.cn<br />地址Q大q?a class="wordstyle" target="_blank">软g</a>园\31L技大厦A座大q博涵咨询服务有限公?/font></p><p id="#9"><font size="2">参考文档:<br />[1] Preliminary Specification http://wp.netscape.com/newsref/std/cookie_spec.html<br />[2] RFC2109 http://www.rfc-editor.org/rfc/rfc2109.txt<br />[3] RFC2965 http://www.rfc-editor.org/rfc/rfc2965.txt<br />[4] The Unofficial Cookie FAQ http://www.cookiecentral.com/faq/<br />[5] http://e-docs.bea.com/wls/docs70/webapp/weblogic_xml.html#1036869<br />[6] http://e-docs.bea.com/wls/docs70/webapp/sessions.html#100770<br />[7] RFC2616 http://www.rfc-editor.org/rfc/rfc2616.txt<br /></font></p><p><font size="2">代码<a class="wordstyle" target="_blank">下蝲</a>Q?/font><a ><font size="2">sampleApp.zip</font></a><br /></p></font></div><img src ="http://www.tkk7.com/renyangok/aggbug/91104.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/renyangok/" target="_blank">保尔?/a> 2006-12-31 10:10 <a href="http://www.tkk7.com/renyangok/archive/2006/12/31/91104.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2ee中文问题的解?/title><link>http://www.tkk7.com/renyangok/archive/2006/12/26/90071.html</link><dc:creator>保尔?/dc:creator><author>保尔?/author><pubDate>Tue, 26 Dec 2006 02:52:00 GMT</pubDate><guid>http://www.tkk7.com/renyangok/archive/2006/12/26/90071.html</guid><wfw:comment>http://www.tkk7.com/renyangok/comments/90071.html</wfw:comment><comments>http://www.tkk7.com/renyangok/archive/2006/12/26/90071.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/renyangok/comments/commentRss/90071.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/renyangok/services/trackbacks/90071.html</trackback:ping><description><![CDATA[  <p><span id="xbxvz3h" class="postbody"><font size="2">W一Q?/font></span><span id="dthz35l" class="postbody"><font size="2">文g的的~码方式其实包括两斚wQ存和取Q?/font></span><span id="55fnrdt" class="postbody"></span><span id="5z1jddd" class="postbody"><font size="2">存文件必M一U编码存Q读文g也必M一U编码读?/font></span><span id="zpdfx35" class="postbody"><font size="2">如果存取按照相同的编码方式,则不会有问题Q关键就是很多时候存取的方式不一_产生q?/font></span><span id="tln5j5p" class="postbody"><font size="2">Q如不特别设|取pȝ默认的编码,中文windows为GBK~码?br /><br />?java->.classq程是,先编?java文gq按莫种~码方式保存Q然后用javacҎ(gu)~译此文Ӟ注意?java没按pȝ默认~码保存则要带encoding参数指明实际~码Q否则出错,生成?class文g存ؓpȝ默认~码?br /><br />?jsp->.java->.classQ先存ؓ某种~码?jsp文gQ然后tomcatҎ(gu)pageEncodingdq{化ؓservlet存ؓpȝ默认~码Q然后同上面.java->.classq程?br /><br />W二QIDE的encoding为对pȝ下文件打开的解码方式或保存的编码方式。特例:如果.jsp文g?lt;%@ page language="java" pageEncoding="UTF-8"%>Q则eclipse会自动存为UTF-8方式Q不eclipse的encoding是什么,q也?eclipse的聪明之处?br /><br />W三Q?br />pageEncoding="UTF-8"表示此文件的~码方式Q必M此文件存储方式一_所以eclipse会首选根据它来存文gQ,tomcatҎ(gu)q个来读?jsp文gq编译ؓservletQ至于编译成?java?class文g应该为tomcat服务器默认编码)?br />contentType="text/html;charset=UTF-8"表示当服务器l浏览器传页面文件时~码方式为UTF-8QŞ式ؓHTML。例如:<br /><%@ page language="java" pageEncoding="UTF-8"%><br /><%@ page contentType="text/html;charset=GBK"%><br /><html><br /> <head><br />  <title>test</title><br /> </head><br /> <body><br />  我是个好?br /> </body><br /></html><br /></font></span></p><p><span id="zjvtv55" class="postbody"></span>表示本jsp文g存ؓUTF-8字符集,当浏览器打开此页面后Q查看原码就会发现源码ؓGBK字符集?br /><br />W四Q?br />request.setCharacterEncoding("UTF-8")是把提交内容的字W集设ؓUTFQ?<br />response.setCharacterEncoding("UTF-8")可以把页面中?font size="2"><%@ page contentType="text/html;charset=iso8859-1"%>换ؓcharset=</font><font size="3">UTF-8Q是l告诉浏览器我这个文件的~码方式?/font><br /><br />W五Q表单提交:无论何种表单提交都可以在后台的java文g中通过String des = new String(s.getBytes("iso8859-1"),"UTF-8");来{换成你想要的UTFQ?~码方式。但如果每处都加词句太麻烦,故分post和get两种方式区分提交Qtomcat5以后分开处理Q之前处理方式一P即都可以?request.setCharacterEncoding("UTF-8")Ҏ(gu)处理Q不qtomcat5以后get提交Ҏ(gu)用此语句无效Q?span class="postbody"><font size="2"><br />1,post提交的数? <br />E序加上org.springframework.web.filter.CharacterEncodingFilterqo? <br /><filter> <br /><filter-name>encodingFilter</filter-name> <br /><filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <br /><init-param> <br /><param-name>encoding</param-name> <br /><param-value>UTF8</param-value> <br /></init-param> <br /><init-param> <br /><param-name>forceEncoding</param-name> <br /><param-value>true</param-value> <br /></init-param> <br /></filter> <br /><br /><filter-mapping> <br /><filter-name>encodingFilter</filter-name> <br /><url-pattern>*.html</url-pattern> <br /></filter-mapping> <br /><filter-mapping> <br /><filter-name>encodingFilter</filter-name> <br /><url-pattern>*.jsp</url-pattern> <br /></filter-mapping> <br /><br />因ؓ规范要求览器提交数据都要用utf8~码,所以这里设|编码方式ؓUTF8. <br /><br />特别注意: <br />a,q个qo器只是简单的调用:request.setCharacterEncoding(this.encoding); <br />在这个语句之前不能调用Q何的request.getParameter()Ҏ(gu),否则会设|tomcat的缺省字W集?ISO-8859-1",q且?setCharacterEncoding的调用失?所以在q个qo器之前的qo器中不能有对getParameterq类Ҏ(gu)的调?比较安全的做法就是把q个qo器尽量靠前放. <br />b,在server.xml中不能加?lt;Valve className="org.apache.catalina.valves.RequestDumperValve"/> <br />q个value也设|tomcat的缺省字W集?ISO-8859-1",使setCharacterEncoding的调用失?可能其他的value也有q个问题,我没有测试过. <br />如果要观察httph参数,可以考虑用过滤器或者其他工?例如ethereal(http://www.ethereal.com/) <br /><br />2,get提交的数? <br />两种情况: <br />a,如果从地址栏直接输入汉?则一般编码ؓ"GBK",需要用 <br />new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK") <br />取出 <br />b,如果是页面超q接q接中带的汉?则编码根据页面编码的不同而不?如果面?<br />content="text/html; charset=utf-8",则在tomcat/conf/server.xml中的配置文g? <br /><!-- Define a non-SSL Coyote HTTP/1.1 Connector on port 8080 --> <br /><Connector port="8080" <br />maxThreads="150" minSpareThreads="25" maxSpareThreads="75" <br />enableLookups="false" redirectPort="8443" acceptCount="100" <br />debug="0" connectionTimeout="20000" useBodyEncodingForURI="true" <br />disableUploadTimeout="true" /> <br /><br />加上:useBodyEncodingForURI="true"卛_正常使用getParameter取出正确内容. <br />如果content="text/html; charset=GBK",需?<br />new String(request.getParameter("something").getBytes("ISO-8859-1"),"GBK") <br />取出,其他情况cM. <br /><br />ȝ: <br />1,所有页面用utf8~码, <br />2,服务器加上过滤器, <br />3,server.xml中不要?<br /><Valve className="org.apache.catalina.valves.RequestDumperValve"/> <br />4,server.xml文g加上useBodyEncodingForURI="true" <br />q样应该可以搞定大多数前台的中文问题.至于地址栏输入中?不支持也|?一般的E序很少要求 <br />从这里输?<br /><br />W六Q连接数据库</font></span> </p><p>1、mysql配置文gQ?br />修改mysql在windows\my.ini里default-character-set=utf-8</p><p>2、mysql里数据库和表也都设ؓutf8_unicode_ci</p><p>3、数据库q结Qjdbc:mysql://localhost/mydb?useUnicode=true&characterEncoding=utf-8<br />注意Q关键就在于此:此句中间?&'不是'&amp;'q是因ؓ数据库连l时Q在.jsp?java文g中应该用&P而XML文g中需要用&amp</p><img src ="http://www.tkk7.com/renyangok/aggbug/90071.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/renyangok/" target="_blank">保尔?/a> 2006-12-26 10:52 <a href="http://www.tkk7.com/renyangok/archive/2006/12/26/90071.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.tkk7.com/" title="亚洲av成人片在线观看">亚洲av成人片在线观看</a> <div class="friend-links"> </div> </div> </footer> վ֩ģ壺 <a href="http://xieehuomh.com" target="_blank">ÿĵӰվһ</a>| <a href="http://6969aaa.com" target="_blank">AV뾫Ʒ</a>| <a href="http://hezuoedu.com" target="_blank">˵һavվ</a>| <a href="http://074g8.com" target="_blank">˿wwwƵ</a>| <a href="http://yw835.com" target="_blank">޾ƷƷ߹ۿ</a>| <a href="http://8fue.com" target="_blank">һAVѲ</a>| <a href="http://91xqq.com" target="_blank">ѹҹӰ</a>| <a href="http://www-741.com" target="_blank">è˳վ</a>| <a href="http://50077995.com" target="_blank">Ʒ˸</a>| <a href="http://wxzg66.com" target="_blank">˳aƬվ</a>| <a href="http://ahbbht.com" target="_blank">޺rӰ</a>| <a href="http://sanyoumiaomu.com" target="_blank">Ʒ888</a>| <a href="http://1515m.com" target="_blank">޾AA߹ۿSEE</a>| <a href="http://773311h.com" target="_blank">þƵվ</a>| <a href="http://rimcn.com" target="_blank">츾avһ</a>| <a href="http://bb927bb.com" target="_blank">aëƬվ</a>| <a href="http://xyxpx.com" target="_blank">avרҳ</a>| <a href="http://tedegold.com" target="_blank">޹Ʒľþþ </a>| <a href="http://sqmdjz.com" target="_blank">߹ۿѰƵ</a>| <a href="http://horticartf.com" target="_blank">ɫWW47</a>| <a href="http://ranjihua.com" target="_blank">ƷѵĻվ</a>| <a href="http://8mav958.com" target="_blank">Ʒþþþþù</a>| <a href="http://7778kk.com" target="_blank">avŮӰ</a>| <a href="http://mironpress.com" target="_blank">Ʒþþþù</a>| <a href="http://51ykz.com" target="_blank">Ƶվ߹ۿ</a>| <a href="http://tzntrip.com" target="_blank">˾Ʒҹ侫պ </a>| <a href="http://shzzhsy.com" target="_blank">91Ƶ</a>| <a href="http://1444000.com" target="_blank">ƵѲ</a>| <a href="http://c4665.com" target="_blank">Ƭ߹ۿ</a>| <a href="http://18736374.com" target="_blank">Ƶ߹ۿ</a>| <a href="http://yuntao360.com" target="_blank">ѿ߾Ʒһ</a>| <a href="http://hh5151.com" target="_blank">Ʒѹۿ</a>| <a href="http://haoda8.com" target="_blank">йڶѲ</a>| <a href="http://sijep.com" target="_blank">޾ƷҳĻ</a>| <a href="http://18888kj.com" target="_blank">һѹۿ </a>| <a href="http://7uj3.com" target="_blank">av˾Ʒ</a>| <a href="http://www44414.com" target="_blank">߹ۿƵ</a>| <a href="http://4eeyy.com" target="_blank">һ</a>| <a href="http://ddm88888.com" target="_blank">ĻӰƵ</a>| <a href="http://tiantangapp.com" target="_blank">þþþþAVվ</a>| <a href="http://www55nana.com" target="_blank">޹Ʒۿþ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>