<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Snowdream-随笔分类-OOP</title><link>http://www.blogjava.net/zellux/category/21869.html</link><description>迷茫的大二：读书 思考 等待</description><language>zh-cn</language><lastBuildDate>Mon, 14 Apr 2008 06:16:58 GMT</lastBuildDate><pubDate>Mon, 14 Apr 2008 06:16:58 GMT</pubDate><ttl>60</ttl><item><title>C# From a Java Programmer's Perspective</title><link>http://www.blogjava.net/zellux/archive/2008/04/14/192725.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Mon, 14 Apr 2008 04:27:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/04/14/192725.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/192725.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/04/14/192725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/192725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/192725.html</trackback:ping><description><![CDATA[
		<a href="http://www.25hoursaday.com/CsharpVsJava.html#wishlist">http://www.25hoursaday.com/CsharpVsJava.html#wishlist</a>
		<br />
		<br />有点长，不过写得很不错<img src ="http://www.blogjava.net/zellux/aggbug/192725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-04-14 12:27 <a href="http://www.blogjava.net/zellux/archive/2008/04/14/192725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Singleton模式与双检测锁定(DCL)</title><link>http://www.blogjava.net/zellux/archive/2008/04/07/191365.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Mon, 07 Apr 2008 13:58:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/04/07/191365.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/191365.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/04/07/191365.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/191365.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/191365.html</trackback:ping><description><![CDATA[
		<p>
				<strong>转载请注明 作者 ZelluX    </strong>
				<a href="/zellux">
						<strong>http://www.blogjava.net/zellux</strong>
				</a>
				<strong>
				</strong>
		</p>
		<p>看OOP教材时，提到了一个双检测锁定(Double-Checked Lock, DCL)的问题，但是书上没有多介绍，只是说这是一个和底层内存机制有关的漏洞。查阅了下相关资料，对这个问题大致有了点了解。</p>
		<p>从头开始说吧。</p>
		<p>在多线程的情况下Singleton模式会遇到不少问题，一个简单的例子</p>
		<p>
				<font face="Courier New">   1:  class Singleton {      <br />   2:      private static Singleton instance = null;      <br />   3:         <br />   4:      public static Singleton instance() {      <br />   5:          if (instance == null) {      <br />   6:              instance = new Singleton();      <br />   7:          }      <br />   8:          return instance;     <br />   9:      }     <br />   10:  }</font>
				<br />   <br />假设这样一个场景，有两个线程调用Singleton.instance()，首先线程一判断instance是否等于null，判断完后一瞬间虚拟机把线程二调度为运行线程，线程二再次判断instance是否为null，然后创建一个Singleton实例，线程二的时间片用完后，线程一被唤醒，接下来它执行的代码依然是instance = new Singleton(); <br />两次调用返回了不同的对象，出现问题了。</p>
		<p>最简单的方法自然是在类被载入时就初始化这个对象：private static Singleton instance = new Singleton();</p>
		<p>JLS(Java Language Specification)中规定了一个类只会被初始化一次，所以这样做肯定是没问题的。</p>
		<p>但是如果要实现延迟初始化(Lazy initialization)，比如这个实例初始化时的参数要在运行期才能确定，应该怎么做呢？</p>
		<p>依然有最简单的方法：使用synchronized关键字修饰初始化方法：</p>
		<p>
				<font face="Courier New" color="#000000">    public synchronized static Singleton instance() {        <br />        if (instance == null) {<br />            instance = new Singleton();<br />        }<br />        return instance;<br />    }</font>
				<br />    <br />这里有一个性能问题：多个线程同时访问这个方法时，会因为同步而导致每次只有一个线程运行，影响程序性能。而事实上初始化完毕后只需要简单的返回instance的引用就行了。</p>
		<p>DCL是一个“看似”有效的解决方法，先把对应代码放上来吧：</p>
		<p>
				<font face="Courier New" color="#000000">    1 :   class Singleton {   <br />    2 :       private static Singleton instance = null ;   <br />    3 :      <br />    4 :       public static Singleton instance() {   <br />    5 :           if (instance == null ) {<br />    6 :               synchronized (this) {   <br />    7 :                   if (instance == null)<br />    8 :                      instance = new Singleton();<br />    9 :              }<br />    10 :          }<br />    11 :          return instance;<br />    12 :      }<br />    13 :  }</font>
		</p>
		<p>用JavaWorld上对应文章的标题来评论这种做法就是smart, but broken。来看原因：</p>
		<p>Java编译器为了提高程序性能会进行指令调度，CPU在执行指令时同样出于性能会乱序执行（至少现在用的大多数通用处理器都是out-of-order的），另外cache的存在也会改变数据回写内存时的顺序[2]。JMM(Java Memory Model, 见[1])指出所有的这些优化都是允许的，只要运行结果和严格按顺序执行所得的结果一样即可。</p>
		<p>Java假设每个线程都跑在自己的处理器上，享有自己的内存，和共享的主存交互。注意即使在单核上这种模型也是有意义的，考虑到cache和寄存器会保存部分临时变量。理论上每个线程修改自己的内存后，必须立即更新对应的主存内容。但是Java设计师们认为这种约束会影响程序性能，他们试着创造了一套让程序跑得更快、但又保证线程之间的交互与预期一致的内存模型。</p>
		<p>synchronized关键字便是其中一把利器。事实上，synchronized块的实现和Linux中的信号量(semaphore)还是有区别的，前者过程中锁的获得和释放都会都会引发一次Memory Barrier来强制线程本地内存和主存之间的同步。通过这个机制，Java中的同步机制保证了synchronized块中指令的原子性(atomic)。</p>
		<p>好了，回过头来看DCL问题。看起来访问一个未同步的instance字段不会产生什么问题，我们再次来假设一个场景：</p>
		<p>线程一进入同步块，执行instance = new Singleton(); 线程二刚开始执行getResource();</p>
		<p>按照顺序的话，接下来应该执行的步骤是 1) 分配新的Singleton对象的内存 2) 调用Singleton的构造器，初始化成员字段 3) instance被赋为指向新的对象的引用。</p>
		<p>前面说过，编译器或处理器都为了提高性能都有可能进行指令的乱序执行，线程一的真正执行步骤可能是1) 分配内存 2) instance指向新对象 3) 初始化新实例。如果线程二在2完成后3执行前被唤醒，它看到了一个不为null的instance，跳出方法体走了，带着一个还没初始化的Singleton对象。</p>
		<p>错误发生的一种情形就是这样，关于更详细的编译器指令调度导致的问题，可以参看这个网页 [4]。</p>
		<p>[3] 中提供了一个编译器指令调度的证据</p>
		<p>instance = new Singleton(); 这条命令在Symantec JIT中被编译成</p>
		<p>
				<font face="Courier New">0206106A   mov         eax,0F97E78h<br />0206106F   call        01F6B210                  ; 分配空间<br />02061074   mov         dword ptr [ebp],eax       ; EBP中保存了instance的地址 </font>
		</p>
		<p>
				<font face="Courier New">02061077   mov         ecx,dword ptr [eax]       ; 解引用，获得新的指针地址</font>
		</p>
		<p>
				<font face="Courier New">02061079   mov         dword ptr [ecx],100h      ; 接下来四行是inline后的构造器<br />0206107F   mov         dword ptr [ecx+4],200h    <br />02061086   mov         dword ptr [ecx+8],400h<br />0206108D   mov         dword ptr [ecx+0Ch],0F84030h</font>
		</p>
		<p>可以看到，赋值完成在初始化之前，而这是JLS允许的。<br /> <br />另一种情形是，假设线程一安稳地完成Singleton对象的初始化，退出了同步块，并同步了和本地内存和主存。线程二来了，看到一个非空的引用，拿走。注意线程二没有执行一个Read Barrier，因为它根本就没进后面的同步块。所以很有可能此时它看到的数据是陈旧的。</p>
		<p>还有很多人根据已知的几种提出了一个又一个fix的方法，但最终还是出现了更多的问题。可以参阅[3]中的介绍。</p>
		<p>[5]中还说明了即使把instance字段声明为volatile还是无法避免错误的原因。</p>
		<p>由此可见，安全的Singleton的构造一般只有两种方法，一是在类载入时就创建该实例，二是使用性能较差的synchronized方法。</p>
		<p>(by ZelluX  <a href="/zellux">http://www.blogjava.net/zellux</a> )</p>
		<p>参考资料： </p>
		<p>[1] Java Language Specification, Second Edition, 第17章介绍了Java中线程和内存交互关系的具体细节。<br />[2] out-of-order与cache的介绍可以参阅Computer System, A Programmer's Perspective的第四、五章。<br />[3] The "Double-Checked Locking is Broken" Declaration, <a href="http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html">http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html</a><br />[4] Synchronization and the Java Memory Model, <a href="http://gee.cs.oswego.edu/dl/cpj/jmm.html">http://gee.cs.oswego.edu/dl/cpj/jmm.html</a><br />[5] Double-checked locking: Clever, but broken, <a href="http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html?page=1">http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html?page=1</a><br />[6] Holub on Patterns, Learning Design Patterns by Looking at Code</p>
		<p> </p>
<img src ="http://www.blogjava.net/zellux/aggbug/191365.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-04-07 21:58 <a href="http://www.blogjava.net/zellux/archive/2008/04/07/191365.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C# 学习笔记 (1)</title><link>http://www.blogjava.net/zellux/archive/2008/04/02/190479.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 02 Apr 2008 15:33:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2008/04/02/190479.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/190479.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2008/04/02/190479.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/190479.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/190479.html</trackback:ping><description><![CDATA[这语言真不错，不像Java那么呆，可惜不开源。<br />入门看的书是CLR via C#中文版，翻译质量不错，起码到现在还没觉得有必要翻一翻原版（不过为什么中文书都喜欢把“栈”叫成“堆栈”呢）。<br />前面几章粗略看了下，从第四章类型基础开始重点阅读。<br />继续漫无目的的学习感兴趣的东西，学习之中经常会惊喜的发现，自己看问题的角度已经不同于之前了。<br /><br />1. 类的new操作会递归调用该类的所有父类构造器，直到System.Object，后者的构造器只是简单返回，用ILDasm查看MSCorLib.dll可以证实这一点。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id="Code_Closed_Image_230126" onclick="this.style.display='none'; Code_Closed_Text_230126.style.display='none'; Code_Open_Image_230126.style.display='inline'; Code_Open_Text_230126.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" width="11" align="top" /><img id="Code_Open_Image_230126" style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_230126.style.display='none'; Code_Closed_Image_230126.style.display='inline'; Code_Closed_Text_230126.style.display='inline';" height="16" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" width="11" align="top" /><span id="Code_Closed_Text_230126" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id="Code_Open_Text_230126" style="DISPLAY: none"><br /><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">.method </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> hidebysig specialname rtspecialname <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />        instance </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">  .ctor() cil managed<br /><img id="Codehighlighter1_95_502_Open_Image" onclick="this.style.display='none'; Codehighlighter1_95_502_Open_Text.style.display='none'; Codehighlighter1_95_502_Closed_Image.style.display='inline'; Codehighlighter1_95_502_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_95_502_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_95_502_Closed_Text.style.display='none'; Codehighlighter1_95_502_Open_Image.style.display='inline'; Codehighlighter1_95_502_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_95_502_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_95_502_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  .custom instance </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> System.Runtime.ConstrainedExecution.ReliabilityContractAttribute::.ctor(valuetype System.Runtime.ConstrainedExecution.Consistency,<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />                                                                                                valuetype System.Runtime.ConstrainedExecution.Cer) </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> ( </span><span style="COLOR: #000000">01</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">03</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">01</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">00</span><span style="COLOR: #000000"> ) <br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Code size       1 (0x1)</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /></span><span style="COLOR: #000000">  .maxstack  </span><span style="COLOR: #000000">8</span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />  IL_0000:  ret<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"> </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> end of method Object::.ctor</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></span></div><br />2. is和as操作符，is类似于Java中的instanceof，as会先检查类型，如果兼容返回该对象的引用，反之返回null。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">Emplooee e </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> o </span><span style="COLOR: #0000ff">as</span><span style="COLOR: #000000"> Employee;<br /><img id="Codehighlighter1_43_57_Open_Image" onclick="this.style.display='none'; Codehighlighter1_43_57_Open_Text.style.display='none'; Codehighlighter1_43_57_Closed_Image.style.display='inline'; Codehighlighter1_43_57_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_43_57_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_43_57_Closed_Text.style.display='none'; Codehighlighter1_43_57_Open_Image.style.display='inline'; Codehighlighter1_43_57_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (e </span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">) </span><span id="Codehighlighter1_43_57_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/images/dot.gif" /></span><span id="Codehighlighter1_43_57_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> blah</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" /></span><span style="COLOR: #000000">}</span></span></div>利用as可以做到只检验一次对象类型，提高程序性能。这本书的很多地方都提到了性能因素。<br /><br />3. 方法调用和x86上汇编语言调用机制很类似。先是参数入栈，接着返回地址入栈，返回的时候也差不多。<font color="#ff0000">不知道x64等寄存器较多的架构上会不会使用寄存器传参呢，呵呵。<br /></font><br />4. 作为方法的prologue的一部分，CLR会自动将所有局部变量初始化为null或0。<font color="#ff0000">感觉这个自动初始化没什么必要</font>，在第五章可以看到。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">SomeVal v1;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />SomeVal v1 </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> SomeVal();</span></div>这里的SomeVal都是值类型，CLR都会将它们初始化为0。区别在于C#认为前者没有初始化，直接使用这个值会报错；而后者在不赋值的情况下使用这个值。<br />可能这是CLR和C#之间不统一导致的冗余步骤吧。<br /><br />5. CLR开始在一个进程中运行时，会给System.Type类型创建一个实例，每个类都会包含指向System.Type类型的指针。<br /><br />6. CLR提供了执行溢出检查的计算指令，例如add.ovf对应add，mul.ovf对应mul。C#中默认关闭溢出检查。<br />可以使用checked关键字使用溢出检查。一般情况下，对预计可能发生溢出的代码放到checked块中，对允许溢出的代码(比如计算hash值)放到一个unchecked块中，其他情况，Debug时打开编译器的/checked+开关，Release版本关闭。<br /><br />7. 所有的值类型都是从System.ValueType继承的。后者重写了Equals方法，比较两个值对象是否完全相等。<br /><br />8. boxing和unboxing。<br />boxing：托管堆中分配内存，复制值类型，然后返回对象地址。<br />unboxing：相当于一个通过指针取值的过程，不过这个指针是已装箱部分中的实际值部分。<br /><br />9. FCL(Framework Class Library)中包含了支持值类型的泛型容器类，不需要对容器中的元素进行boxing/unboxing处理。<br /><font color="#ff0000">不过这里就有个问题了，值类型的话是放在栈上的，生命周期小于容器的，这个怎么处理呢？</font><br />第16章才详细解释泛型，先把这个问题留着吧 =,=<br /><br />10. 依然是性能问题。有时候编译器会反复对一个值类型boxing，此时手动boxing会提高一些性能。<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">Int32 v </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 需三次boxing</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">Console.WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">{0}, {1}, {2}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, v, v, v);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> 只需一次boxing</span><span style="COLOR: #008000"><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #000000">Object o </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> v;<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />Console.WriteLine(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">{0}, {1}, {2}</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, o, o, o);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div><br />接下来书上举了个很搞的例子说明boxing和unboxing的各种情况，其实也很容易理解。<img src ="http://www.blogjava.net/zellux/aggbug/190479.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2008-04-02 23:33 <a href="http://www.blogjava.net/zellux/archive/2008/04/02/190479.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java Puzzler - 数值处理中容易犯的错误</title><link>http://www.blogjava.net/zellux/archive/2007/11/10/159622.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sat, 10 Nov 2007 13:32:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/11/10/159622.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/159622.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/11/10/159622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/159622.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/159622.html</trackback:ping><description><![CDATA[Pitfall 1：判断x的奇偶性
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img id="Codehighlighter1_35_60_Open_Image" onclick="this.style.display='none'; Codehighlighter1_35_60_Open_Text.style.display='none'; Codehighlighter1_35_60_Closed_Image.style.display='inline'; Codehighlighter1_35_60_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_35_60_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_35_60_Closed_Text.style.display='none'; Codehighlighter1_35_60_Open_Image.style.display='inline'; Codehighlighter1_35_60_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">boolean</span><span style="color: #000000">&nbsp;isOdd(</span><span style="color: #0000ff">int</span><span style="color: #000000">&nbsp;x)&nbsp;</span><span id="Codehighlighter1_35_60_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_35_60_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;x&nbsp;</span><span style="color: #000000">%</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">2</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">==</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">1</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
当x为负奇数时，x % 2的值为负数。<br />
Note：把 x % 2 ==&nbsp;1 改为 x % 2 != 0<br />
<br />
Pitfall 2：长整数计算<br />
long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;<br />
这个表达式先计算左边几个int的乘积，然后再把值转换为long，因此仍会溢出<br />
Note：把24改成24L<br />
<br />
Pitfall 3：看看这句话的结果<br />
System.out.println(12345+5432l);<br />
Note：5432后面的l很容易被看成1，因此建议使用L表示长整形时都使用大写。<br />
<br />
Pitfall 4：下面这句话又会是什么结果<br />
System.out.println(Long.toHexString(0x100000000L + 0xcafebabe));<br />
Java计算时先用sign-extension把后面一个数转成long，然后再计算<br />
Note：尽量避免混合类型计算<br />
<br />
Pitfall 5：这句话呢？<br />
System.out.println((int) (char) (byte) -1);<br />
结果是65535<br />
Note：char是无符号类型，将char转为int时使用zero-extension<br />
<br />
Pitfall 6：交换变量值<br />
int x = 1984;<br />
int y = 2001; <br />
x ^= y ^= x ^= y; <br />
最终结果是x == 0, y == 1984 <br />
Note：Java中操作符是从左往右计算的 (JLS 15.7) <br />
改成 y = (x ^ (y ^= x) ^ y; 就可以，但是永远不要这么做&nbsp; <br />
&nbsp; <br />
Pitfall 7：问号操作符 <br />
char x = 'X'; <br />
int i = 0; <br />
System.out.print(true ? x : 0); <br />
System.out.print(false ? i : x); <br />
输出结果为X88 <br />
Note：同样是混合类型计算导致的问题，建议在条件表达式中使用类型相同的第二和第三操作符。 <br />
&nbsp; <br />
Pitfall 8：看似相同的表达式的不同结果 <br />
short x = 0; <br />
int i = 123456; <br />
1) x += i; // 隐含了类型转换，结果为-7616 <br />
2) x = x + i; // 编译无法通过，因为损失了精度&nbsp;<br />
&nbsp;
<img src ="http://www.blogjava.net/zellux/aggbug/159622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-11-10 21:32 <a href="http://www.blogjava.net/zellux/archive/2007/11/10/159622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java3D 入门笔记 (1)  </title><link>http://www.blogjava.net/zellux/archive/2007/11/05/158362.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Mon, 05 Nov 2007 13:43:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/11/05/158362.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/158362.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/11/05/158362.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/158362.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/158362.html</trackback:ping><description><![CDATA[要做个和Java3D有关的项目，需要稍微了解下相关的知识。 <br />
看的资料是The Java3d Tutorial，版本有点早，凑合着看了。&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp; <br />
Java 3D 的虚拟环境是从场景图(scene graph)中建立的，场景图聚合(assemble)了各种定义几何、声音、光、位置、方位等元素的类。&nbsp;<br />
<br />
一种常用的定义图的数据结构由结点(node)和弧(arc)组成。结点都是Java 3D类的实例，而弧则代表了实例间两种不同的关系。 <br />
最常见的关系是父子(parent-child)关系。一个组结点(group node)可以包含任意多的子结点，但只能有一个父结点。 <br />
另一种关系是引用(reference)，引用通过一个场景图的结点关联了一个NodeComponent类，NodeComponent类定义了各种视图对象的几何和外观属性。 <br />
这种结构可以用树来描述，从根结点到任一叶子结点的路成为场景图路径(scene graph path). 每条路径都完整地描述了它的叶子结点的状态。&nbsp;<br />
&nbsp; <br />
<img height="381" alt="" src="http://www.blogjava.net/images/blogjava_net/zellux/27129/r_java3dtree.gif " width="640" border="0" /><br />
这就是一个简单的场景图的结构，其中包括VisualUniverse&nbsp; Locale&nbsp; GroupNode&nbsp; Leaf 等元素&nbsp;<br />
<br />
每个场景图都有单一的VirtualUniverse，后者包含一串Locale对象。一个程序可以包含多个VirtualUniverse对象，但是没有一种简单的方法实现它们相互之间的通信。&nbsp;<br />
&nbsp;<br />
写Java3D程序的通常步骤： <br />
&nbsp;1. 创建一个Canvas3D对象 <br />
&nbsp;2. 创建一个VirtualUniverse对象 <br />
&nbsp;3. 创建一个Locale对象，将其与VirtualUniverse相关联 <br />
&nbsp;4. 构造视图分支(view branch graph)：分别创建一个View ViewPlatform PhysicalBody PhysicalEnvironment对象，将后面三个及Canvas3D与View对象关联 <br />
&nbsp;5. 构造内容分支(content branch graph) <br />
&nbsp;6. 编译(compile)各个分支 <br />
&nbsp;7. 将子图(subgraph)插入Locale中&nbsp;<br />
&nbsp; <br />
使用SimpleUniverse可以简化这些步骤&nbsp;<br />
&nbsp; <br />
<img height="389" alt="" src="http://www.blogjava.net/images/blogjava_net/zellux/27129/r_simpleuniverse.gif " width="640" border="0" /><br />
虚线框起来的部分就是SimpleUniverse中提供的内容&nbsp;<br />
&nbsp; <br />
通过它可以将步骤简化为 <br />
&nbsp;1. 创建一个Canvas3D对象 <br />
&nbsp;2. 创建一个引用了之前的Canvas3D对象的SimpleUniverse类，并定制该类 <br />
&nbsp;3. 构造一个内容分支，编译后插入SimpleUniverse的Locale<br />
&nbsp;<br />
什么是编译(compile)：通过编译BranchGroup，可以将它及其祖先转换为一种更高效的实现方式。建议在最后一步中做编译。
<img src ="http://www.blogjava.net/zellux/aggbug/158362.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-11-05 21:43 <a href="http://www.blogjava.net/zellux/archive/2007/11/05/158362.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java 的类库真是方便啊</title><link>http://www.blogjava.net/zellux/archive/2007/10/17/153415.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 16 Oct 2007 16:44:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/10/17/153415.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/153415.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/10/17/153415.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/153415.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/153415.html</trackback:ping><description><![CDATA[刚做完了Java课布置的homework，其中有一题是打印日历<br />
<span style="font-family: 宋体">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; February 2007<br style="font-family: " />
&nbsp;---------------------------<br style="font-family: " />
&nbsp;Sun Mon Tue Wed Thu Fri Sat<br style="font-family: " />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; 2&nbsp;&nbsp; 3<br style="font-family: " />
&nbsp;&nbsp; 4&nbsp;&nbsp; 5&nbsp;&nbsp; 6&nbsp;&nbsp; 7&nbsp;&nbsp; 8&nbsp;&nbsp; 9&nbsp; 10<br style="font-family: " />
&nbsp; 11&nbsp; 12&nbsp; 13&nbsp; 14&nbsp; 15&nbsp; 16&nbsp; 17<br style="font-family: " />
&nbsp; 18&nbsp; 19&nbsp; 20&nbsp; 21&nbsp; 22&nbsp; 23&nbsp; 24<br style="font-family: " />
&nbsp; 25&nbsp; 26&nbsp; 27&nbsp; 28<br />
<br />
用<font face="宋体">GregorianCalendar类几分钟就做好了<br />
Java的确很方便，主要是很多库都集成在jdk中，查一份手册就可以使用<br />
如果这个用C++写，除非去找个开源的库，否则估计就得自己计算了，印象中日期方面的竞赛题都属于难度不大，但是很容易出错的题目。<br />
话虽如此，还是想学好C++&nbsp; -,-|||</font></span>
<img src ="http://www.blogjava.net/zellux/aggbug/153415.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-10-17 00:44 <a href="http://www.blogjava.net/zellux/archive/2007/10/17/153415.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java泛型中的? super T语法</title><link>http://www.blogjava.net/zellux/archive/2007/08/15/136940.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 15 Aug 2007 07:51:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/08/15/136940.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/136940.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/08/15/136940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/136940.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/136940.html</trackback:ping><description><![CDATA[<p>? super T 语法将泛型类限制为所有T的超类（包括T自身），但只能用于参数中，不可以在返回值用加以限定。<br>如果不加以限定，假设某个函数头为<br>? super Manager get()<br>由于编译器不知道该方法究竟会返回什么类，这样就只能用Object类来接收了。<br></p>
<p>该语法常用的一个情况是泛型类的比较<br>java.util.TreeSet&lt;E&gt; 代表一个有序的元素为E的树，它其中的一个构造器需要一个Comparator类来比较两个元素，以E为String类时为例，此时的Comparator可以是Comparator&lt;String&gt;，也可以是Comparator&lt;Object&gt;，但Comparator&lt;Integer&gt;就不行，如何表示这样的限制呢？<br>jdk源代码中是这样的：<br>public TreeSet(Comparator&lt;? super E&gt; c)<br>这样就保证了传给构造器的Comparator是可以进行E元素的比较的。<br></p>
<p>另一个例子，java.util.Collections的max方法用于获得一个容器中的最大值，这个函数头可以这样写：<br>public static &lt;T extends Comparable&lt;T&gt;&gt;&nbsp; T max(Collection&lt;T&gt; coll)</p>
这样就限定T为能和自己比较的类，过于严格，jdk源码是这样的：
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_93_303_Open_Image onclick="this.style.display='none'; Codehighlighter1_93_303_Open_Text.style.display='none'; Codehighlighter1_93_303_Closed_Image.style.display='inline'; Codehighlighter1_93_303_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_93_303_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_93_303_Closed_Text.style.display='none'; Codehighlighter1_93_303_Open_Image.style.display='inline'; Codehighlighter1_93_303_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">T&nbsp;</span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000">&nbsp;Object&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">&nbsp;Comparable</span><span style="COLOR: #000000">&lt;?</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">super</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;T&nbsp;max(Collection</span><span style="COLOR: #000000">&lt;?</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;coll)&nbsp;</span><span id=Codehighlighter1_93_303_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_93_303_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Iterator</span><span style="COLOR: #000000">&lt;?</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">extends</span><span style="COLOR: #000000">&nbsp;T</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;coll.iterator();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;candidate&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i.next();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top><br><img id=Codehighlighter1_194_279_Open_Image onclick="this.style.display='none'; Codehighlighter1_194_279_Open_Text.style.display='none'; Codehighlighter1_194_279_Closed_Image.style.display='inline'; Codehighlighter1_194_279_Closed_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_194_279_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_194_279_Closed_Text.style.display='none'; Codehighlighter1_194_279_Open_Image.style.display='inline'; Codehighlighter1_194_279_Open_Text.style.display='inline';" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">(i.hasNext())&nbsp;</span><span id=Codehighlighter1_194_279_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id=Codehighlighter1_194_279_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;T&nbsp;next&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;i.next();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(next.compareTo(candidate)&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">)<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;candidate&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;next;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;candidate;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<p>很严谨的函数头，但是限定方面比较宽</p>
<img src ="http://www.blogjava.net/zellux/aggbug/136940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-08-15 15:51 <a href="http://www.blogjava.net/zellux/archive/2007/08/15/136940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Project3 成功转移到Ubuntu</title><link>http://www.blogjava.net/zellux/archive/2007/06/12/123550.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 12 Jun 2007 03:17:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/06/12/123550.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/123550.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/06/12/123550.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/123550.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/123550.html</trackback:ping><description><![CDATA[Java跨平台的优势啊。。。<br><br>1. 把WinXP下的所有项目文件复制到Ubuntu下<br>2. 通过EMS导出数据库的sql文件，在Ubuntu下导入<br>3. 在Ubuntu下用MyEclipse加入该项目，重新设置引用的包的路径（包括数据库的配置）<br>4. 把所有包含中文的java源程序设置编码方式为GBK<br>5. 注意linux下的mysql是对大小写敏感的，因此原来windows下配置正确的Hibernate文件可能在linux下需要修改<br>6. 部署，enjoy
<br> <img src ="http://www.blogjava.net/zellux/aggbug/123550.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-06-12 11:17 <a href="http://www.blogjava.net/zellux/archive/2007/06/12/123550.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Project - 假期学生订票系统</title><link>http://www.blogjava.net/zellux/archive/2007/06/11/123459.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Mon, 11 Jun 2007 12:45:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/06/11/123459.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/123459.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/06/11/123459.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/123459.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/123459.html</trackback:ping><description><![CDATA[第一个接到的Project啊 ^_^ 挺简单的<br><br>1. 映射了一对多关系后需要做查询时碰到问题，翻书发现了个好东西Criterion Query。<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><span style="color: #000000;">Criteria&nbsp;criteria&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;session.createCriteria(Booking.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">criteria.add(Expression.ne(</span><span style="color: #000000;">"</span><span style="color: #000000;">foregift</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;Foregift.getInstance(</span><span style="color: #000000;">1</span><span style="color: #000000;">)));<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;criteria.list();</span></div>
这样就得到了已付押金的订单列表<img src ="http://www.blogjava.net/zellux/aggbug/123459.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-06-11 20:45 <a href="http://www.blogjava.net/zellux/archive/2007/06/11/123459.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[zz]Log4j日志管理系统简单说明</title><link>http://www.blogjava.net/zellux/archive/2007/05/20/118732.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 20 May 2007 11:24:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/20/118732.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/118732.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/20/118732.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/118732.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/118732.html</trackback:ping><description><![CDATA[&nbsp; Log4j有三个主要的组件：Loggers，Appenders和Layouts，这里可简单理解为日志类别，日志要输出的地方和日志以何种形式输出。综合使用这三个组件可以轻松的记录信息的类型和级别，并可以在运行时控制日志输出的样式和位置。下面对三个组件分别进行说明：
<p style="MARGIN-RIGHT: 0px" align=left><strong>1、 Loggers</strong></p>
<p style="MARGIN-RIGHT: 0px" align=left><strong>&nbsp;&nbsp;&nbsp; </strong>Loggers组件在此系统中被分为五个级别：DEBUG、INFO、WARN、ERROR和FATAL。这五个级别是有顺序的，DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; FATAL，明白这一点很重要，这里Log4j有一个规则：假设Loggers级别为P，如果在Loggers中发生了一个级别Q比P高，则可以启动，否则屏蔽掉。</p>
<blockquote dir=ltr style="MARGIN-RIGHT: 0px">
<p style="MARGIN-RIGHT: 0px" align=left><strong>Java程序举例来说：</strong></p>
<p style="MARGIN-RIGHT: 0px" align=left>//建立Logger的一个实例，命名为&#8220;com.foo&#8221;</p>
<p style="MARGIN-RIGHT: 0px" align=left>Logger&nbsp; logger = Logger.getLogger("com.foo");</p>
<p style="MARGIN-RIGHT: 0px" align=left>//设置logger的级别。通常不在程序中设置logger的级别。一般在配置文件中设置。</p>
<p style="MARGIN-RIGHT: 0px" align=left>logger.setLevel(Level.INFO);</p>
<p style="MARGIN-RIGHT: 0px" align=left>Logger barlogger = Logger.getLogger("com.foo.Bar");</p>
<p style="MARGIN-RIGHT: 0px" align=left>//下面这个请求可用，因为WARN &gt;= INFO</p>
<p style="MARGIN-RIGHT: 0px" align=left>logger.warn("Low fuel level.");</p>
<p style="MARGIN-RIGHT: 0px" align=left>//下面这个请求不可用，因为DEBUG &lt; INFO</p>
<p style="MARGIN-RIGHT: 0px" align=left>logger.debug("Starting search for nearest gas station.");</p>
<p style="MARGIN-RIGHT: 0px" align=left>//命名为&#8220;com.foo.bar&#8221;的实例barlogger会继承实例&#8220;com.foo&#8221;的级别。因此，下面这个请求可用，因为INFO &gt;= INFO</p>
<p style="MARGIN-RIGHT: 0px" align=left>barlogger.info("Located nearest gas station.");</p>
<p style="MARGIN-RIGHT: 0px" align=left>//下面这个请求不可用，因为DEBUG &lt; INFO</p>
<p style="MARGIN-RIGHT: 0px" align=left>barlogger.debug("Exiting gas station search");&nbsp;</p>
<p style="MARGIN-RIGHT: 0px" align=left><strong>这里&#8220;是否可用&#8221;的意思是能否输出Logger信息。</strong>&nbsp;</p>
</blockquote>
<p style="MARGIN-RIGHT: 0px" align=left>&nbsp;&nbsp;&nbsp; 在对Logger实例进行命名时，没有限制，可以取任意自己感兴趣的名字。一般情况下建议以类的所在位置来命名Logger实例，这是目前来讲比较有效的Logger命名方式。这样可以使得每个类建立自己的日志信息，便于管理。比如：</p>
<blockquote dir=ltr style="MARGIN-RIGHT: 0px">
<p style="MARGIN-RIGHT: 0px" align=left>static Logger logger = Logger.getLogger(ClientWithLog4j.class.getName());</p>
</blockquote>
<p style="MARGIN-RIGHT: 0px" align=left><strong>2、 Appenders</strong></p>
<p dir=ltr style="MARGIN-RIGHT: 0px" align=left>&nbsp;&nbsp;&nbsp; 禁用与使用日志请求只是Log4j其中的一个小小的地方，Log4j日志系统允许把日志输出到不同的地方，如控制台（Console）、文件（Files）、根据天数或者文件大小产生新的文件、以流的形式发送到其它地方等等。</p>
<blockquote dir=ltr style="MARGIN-RIGHT: 0px">
<p style="MARGIN-RIGHT: 0px" align=left>其语法表示为：</p>
<p style="MARGIN-RIGHT: 0px" align=left>org.apache.log4j.ConsoleAppender（控制台），</p>
<p style="MARGIN-RIGHT: 0px" align=left><br>org.apache.log4j.FileAppender（文件），<br>org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件），org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件），<br>org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方）</p>
<p style="MARGIN-RIGHT: 0px" align=left>配置时使用方式为：</p>
<p style="MARGIN-RIGHT: 0px" align=left>log4j.appender.appenderName = fully.qualified.name.of.appender.class</p>
<p style="MARGIN-RIGHT: 0px" align=left>log4j.appender.appenderName.option1 = value1</p>
<p style="MARGIN-RIGHT: 0px" align=left>&#8230;</p>
<p style="MARGIN-RIGHT: 0px" align=left>log4j.appender.appenderName.option = valueN</p>
<p style="MARGIN-RIGHT: 0px" align=left>这样就为日志的输出提供了相当大的便利。</p>
</blockquote>
<p style="MARGIN-RIGHT: 0px" align=left><strong>3、 Layouts</strong></p>
<p style="MARGIN-RIGHT: 0px" align=left>&nbsp;&nbsp;&nbsp; 有时用户希望根据自己的喜好格式化自己的日志输出。Log4j可以在Appenders的后面附加Layouts来完成这个功能。Layouts提供了四种日志输出样式，如根据HTML样式、自由指定样式、包含日志级别与信息的样式和包含日志时间、线程、类别等信息的样式等等。</p>
<blockquote dir=ltr style="MARGIN-RIGHT: 0px">
<p dir=ltr style="MARGIN-RIGHT: 0px" align=left>其语法表示为：</p>
<p dir=ltr style="MARGIN-RIGHT: 0px" align=left>org.apache.log4j.HTMLLayout（以HTML表格形式布局），<br>org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br>org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br>org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息）</p>
<p dir=ltr style="MARGIN-RIGHT: 0px" align=left>配置时使用方式为：</p>
</blockquote>
<p dir=ltr style="MARGIN-RIGHT: 0px" align=left>&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.appenderName.layout =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fully.qualified.name.of.layout.class<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log4j.appender.appenderName.layout.option1 = value1<br>&nbsp;&nbsp;&nbsp;&nbsp; &#8230;<br>&nbsp;&nbsp;&nbsp;&nbsp; log4j.appender.appenderName.layout.option = valueN<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; 以上是从原理方面说明Log4j的使用方法，在具体Java编程使用Log4j可以参照以下示例：<br><strong>1、 建立Logger实例：<br></strong>&nbsp;&nbsp;&nbsp; 语法表示：public static Logger getLogger( String name)<br>&nbsp;&nbsp;&nbsp; 实际使用：static Logger logger = Logger.getLogger&nbsp;&nbsp; (ServerWithLog4j.class.getName ()) ;<br><strong>2、 读取配置文件：</strong><br>&nbsp;&nbsp;&nbsp; 获得了Logger的实例之后，接下来将配置Log4j使用环境：<br>&nbsp;&nbsp;&nbsp; 语法表示：<br>&nbsp;&nbsp;&nbsp; BasicConfigurator.configure()：自动快速地使用缺省Log4j环境。<br>&nbsp;&nbsp;&nbsp; PropertyConfigurator.configure(String configFilename)：读取使用Java的特性文件编写的配置文件。<br>&nbsp;&nbsp;&nbsp; DOMConfigurator.configure(String filename)：读取XML形式的配置文件。<br>&nbsp;&nbsp;&nbsp; 实际使用：PropertyConfigurator.configure("ServerWithLog4j.properties");<br><strong>3、 插入日志信息</strong><br>&nbsp;&nbsp;&nbsp; 完成了以上连个步骤以后，下面就可以按日志的不同级别插入到你要记录日志的任何地方了。<br>&nbsp;&nbsp;&nbsp; 语法表示：<br>&nbsp;&nbsp;&nbsp; Logger.debug(Object message);<br>&nbsp;&nbsp;&nbsp; Logger.info(Object message);<br>&nbsp;&nbsp;&nbsp; Logger.warn(Object message);<br>&nbsp;&nbsp;&nbsp; Logger.error(Object message);<br>&nbsp;&nbsp;&nbsp; 实际使用：logger.info("ServerSocket before accept: " + server);<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; 在实际编程时，要使Log4j真正在系统中运行事先还要对配置文件进行定义。定义步骤就是对Logger、Appender及Layout的分别使用，具体如下：<br><strong>1、 配置根Logger</strong>，其语法为：<br>&nbsp;&nbsp;&nbsp; log4j.rootLogger = [ level ] , appenderName, appenderName, &#8230;<br>这里level指Logger的优先级，appenderName是日志信息的输出地，可以同时指定多个输出地。如：log4j.rootLogger= INFO,A1,A2<br><strong>2、 配置日志信息输出目的地</strong>，其语法为：<br>&nbsp;&nbsp;&nbsp; log4j.appender.appenderName = fully.qualified.name.of.appender.class<br>&nbsp;&nbsp;&nbsp; 可以指定上面所述五个目的地中的一个。<br><strong>3、 配置日志信息的格式</strong>，其语法为：<br>&nbsp;&nbsp;&nbsp; log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class<br>&nbsp;&nbsp;&nbsp; 这里上面三个步骤是对前面Log4j组件说明的一个简化；下面给出一个具体配置例子，在程序中可以参照执行：<br>&nbsp;&nbsp;&nbsp; log4j.rootLogger=INFO,A1<br>&nbsp;&nbsp;&nbsp; log4j.appender.A1=org.apache.log4j.ConsoleAppender<br>&nbsp;&nbsp;&nbsp;&nbsp;log4j.appender.A1.layout=org.apache.log4j.PatternLayout<br>&nbsp;&nbsp;&nbsp; log4j.appender.A1.layout.ConversionPattern=<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %-4r %-5p %d{yyyy-MM-dd HH:mm:ssS} %c %m%n<br>&nbsp;&nbsp;&nbsp; 这里需要说明的就是日志信息格式中几个符号所代表的含义：<br>&nbsp;&nbsp;&nbsp; －X号: X信息输出时左对齐；<br>&nbsp;&nbsp;&nbsp; %p: 日志信息级别<br>&nbsp;&nbsp;&nbsp; %d{}: 日志信息产生时间<br>&nbsp;&nbsp;&nbsp; %c: 日志信息所在地（类名）<br>&nbsp;&nbsp;&nbsp; %m: 产生的日志具体信息<br>&nbsp;&nbsp;&nbsp; %n: 输出日志信息换行<br>&nbsp;<br><strong>根据上面的日志格式，某一个程序的输出结果如下：</strong><br>0&nbsp;&nbsp;&nbsp; INFO&nbsp; 2003-06-13 13:23:46968 ClientWithLog4j Client socket: Socket[addr=localhost/127.0.0.1,port=8002,localport=2014]<br>16&nbsp;&nbsp; DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server says: 'Java server with log4j, Fri Jun 13 13:23:46 CST 2003'<br>16&nbsp;&nbsp; DEBUG 2003-06-13 13:23:46984 ClientWithLog4j GOOD<br>16&nbsp;&nbsp; DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server responds: 'Command 'HELLO' not understood.'<br>16&nbsp;&nbsp; DEBUG 2003-06-13 13:23:46984 ClientWithLog4j HELP<br>16&nbsp;&nbsp; DEBUG 2003-06-13 13:23:46984 ClientWithLog4j Server responds: 'Vocabulary: HELP QUIT'<br>16&nbsp;&nbsp; DEBUG 2003-06-13 13:23:46984 ClientWithLog4j QUIT</p>
<img src ="http://www.blogjava.net/zellux/aggbug/118732.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-20 19:24 <a href="http://www.blogjava.net/zellux/archive/2007/05/20/118732.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web Project 3 乱码解决方案小结</title><link>http://www.blogjava.net/zellux/archive/2007/05/15/117689.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 15 May 2007 11:38:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/15/117689.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/117689.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/15/117689.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/117689.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/117689.html</trackback:ping><description><![CDATA[1. 数据库乱码<br>使用EMS SQL Manager for MySQL可以容易地解决这个问题，在table的属性对话框中将Character Set设为GBK即可。<br><br>2. Ajax应用中Servlet返回内容乱码<br>设置响应报头的编码即可<br>response.setHeader("Content-Type", "text/html;charset=GB2312");<br><br>3. JSP页面显示乱码<br>在页面开头加上<br>&lt;%@ page&nbsp;pageEncoding="GBK"%&gt;<br><br>4. request.getParameter产生乱码<br>用post方法只要在获取参数前设置编码即可<br>request.setCharacterEncoding("GBK");<br>get方法还需要在获取参数后转换编码<br>name = new String(name.getBytes("ISO8859-1"), "GBK");<br><br>5. google到的另一个解决方法，不过貌似不成功 -,-<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;filter;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.servlet.Filter;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.servlet.FilterConfig;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.servlet.ServletException;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.servlet.ServletRequest;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.servlet.ServletResponse;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;javax.servlet.FilterChain;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;java.io.IOException;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><br><img id="Codehighlighter1_304_1242_Open_Image" onclick="this.style.display='none'; codehighlighter1_304_1242_open_text.style.display="'none';" codehighlighter1_304_1242_closed_image.style.display="'inline';" codehighlighter1_304_1242_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_304_1242_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_304_1242_closed_text.style.display="'none';" codehighlighter1_304_1242_open_image.style.display="'inline';" codehighlighter1_304_1242_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;EncodingFilter&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;Filter&nbsp;</span><span id="Codehighlighter1_304_1242_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_304_1242_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;FilterConfig&nbsp;filterConfig;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;String&nbsp;encodingName;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;enable;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img id="Codehighlighter1_435_497_Open_Image" onclick="this.style.display='none'; codehighlighter1_435_497_open_text.style.display="'none';" codehighlighter1_435_497_closed_image.style.display="'inline';" codehighlighter1_435_497_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_435_497_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_435_497_closed_text.style.display="'none';" codehighlighter1_435_497_open_image.style.display="'inline';" codehighlighter1_435_497_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;EncodingFilter()&nbsp;</span><span id="Codehighlighter1_435_497_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_435_497_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.encodingName&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">UTF-8</span><span style="color: #000000;">"</span><span style="color: #000000;">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.enable&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img id="Codehighlighter1_570_636_Open_Image" onclick="this.style.display='none'; codehighlighter1_570_636_open_text.style.display="'none';" codehighlighter1_570_636_closed_image.style.display="'inline';" codehighlighter1_570_636_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_570_636_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_570_636_closed_text.style.display="'none';" codehighlighter1_570_636_open_image.style.display="'inline';" codehighlighter1_570_636_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;init(FilterConfig&nbsp;filterConfig)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;ServletException&nbsp;</span><span id="Codehighlighter1_570_636_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_570_636_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.filterConfig&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;filterConfig;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;loadConfigParams();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img id="Codehighlighter1_673_944_Open_Image" onclick="this.style.display='none'; codehighlighter1_673_944_open_text.style.display="'none';" codehighlighter1_673_944_closed_image.style.display="'inline';" codehighlighter1_673_944_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_673_944_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_673_944_closed_text.style.display="'none';" codehighlighter1_673_944_open_image.style.display="'inline';" codehighlighter1_673_944_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">private</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;loadConfigParams()&nbsp;</span><span id="Codehighlighter1_673_944_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_673_944_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.encodingName&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.filterConfig.getInitParameter(</span><span style="color: #000000;">"</span><span style="color: #000000;">encoding</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;strIgnoreFlag&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.filterConfig.getInitParameter(</span><span style="color: #000000;">"</span><span style="color: #000000;">enable</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br><img id="Codehighlighter1_868_900_Open_Image" onclick="this.style.display='none'; codehighlighter1_868_900_open_text.style.display="'none';" codehighlighter1_868_900_closed_image.style.display="'inline';" codehighlighter1_868_900_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_868_900_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_868_900_closed_text.style.display="'none';" codehighlighter1_868_900_open_image.style.display="'inline';" codehighlighter1_868_900_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(strIgnoreFlag.equalsIgnoreCase(</span><span style="color: #000000;">"</span><span style="color: #000000;">true</span><span style="color: #000000;">"</span><span style="color: #000000;">))&nbsp;</span><span id="Codehighlighter1_868_900_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_868_900_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.enable&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br><img id="Codehighlighter1_907_940_Open_Image" onclick="this.style.display='none'; codehighlighter1_907_940_open_text.style.display="'none';" codehighlighter1_907_940_closed_image.style.display="'inline';" codehighlighter1_907_940_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_907_940_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_907_940_closed_text.style.display="'none';" codehighlighter1_907_940_open_image.style.display="'inline';" codehighlighter1_907_940_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span id="Codehighlighter1_907_940_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_907_940_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.enable&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;doFilter(ServletRequest&nbsp;request,&nbsp;ServletResponse&nbsp;response,<br><img id="Codehighlighter1_1082_1209_Open_Image" onclick="this.style.display='none'; codehighlighter1_1082_1209_open_text.style.display="'none';" codehighlighter1_1082_1209_closed_image.style.display="'inline';" codehighlighter1_1082_1209_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_1082_1209_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_1082_1209_closed_text.style.display="'none';" codehighlighter1_1082_1209_open_image.style.display="'inline';" codehighlighter1_1082_1209_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FilterChain&nbsp;chain)&nbsp;</span><span style="color: #0000ff;">throws</span><span style="color: #000000;">&nbsp;IOException,&nbsp;ServletException&nbsp;</span><span id="Codehighlighter1_1082_1209_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_1082_1209_Open_Text"><span style="color: #000000;">{<br><img id="Codehighlighter1_1105_1166_Open_Image" onclick="this.style.display='none'; codehighlighter1_1105_1166_open_text.style.display="'none';" codehighlighter1_1105_1166_closed_image.style.display="'inline';" codehighlighter1_1105_1166_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_1105_1166_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_1105_1166_closed_text.style.display="'none';" codehighlighter1_1105_1166_open_image.style.display="'inline';" codehighlighter1_1105_1166_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.enable)&nbsp;</span><span id="Codehighlighter1_1105_1166_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_1105_1166_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;request.setCharacterEncoding(</span><span style="color: #0000ff;">this</span><span style="color: #000000;">.encodingName);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;chain.doFilter(request,&nbsp;response);<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img id="Codehighlighter1_1236_1240_Open_Image" onclick="this.style.display='none'; codehighlighter1_1236_1240_open_text.style.display="'none';" codehighlighter1_1236_1240_closed_image.style.display="'inline';" codehighlighter1_1236_1240_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_1236_1240_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_1236_1240_closed_text.style.display="'none';" codehighlighter1_1236_1240_open_image.style.display="'inline';" codehighlighter1_1236_1240_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;destroy()&nbsp;</span><span id="Codehighlighter1_1236_1240_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_1236_1240_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span></div>
web.xml<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">EncodingFilter</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter-class</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">filter.EncodingFilter</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter-class</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">init-param</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">encoding</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">UTF-8</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">init-param</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">init-param</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">enable</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">true</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">param-value</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">init-param</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter-mapping</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">EncodingFilter</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">url-pattern</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">/user/*</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">url-pattern</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter-mapping</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter-mapping</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">filter-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">EncodingFilter</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter-name</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">url-pattern</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">/manager/*</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">url-pattern</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">filter-mapping</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;">&nbsp;&nbsp;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span></div><img src ="http://www.blogjava.net/zellux/aggbug/117689.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-15 19:38 <a href="http://www.blogjava.net/zellux/archive/2007/05/15/117689.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web Project 3 笔记 (4)</title><link>http://www.blogjava.net/zellux/archive/2007/05/15/117683.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 15 May 2007 11:11:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/15/117683.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/117683.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/15/117683.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/117683.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/117683.html</trackback:ping><description><![CDATA[<p>1. Filter 挺好用的。访问session时要把参数向下转型为HttpServletRequest</p>
beans.User user = (beans.User) ((HttpServletRequest)arg0).getSession().getAttribute("user");<br><br>2. 基本完成了，有空的话，准备增加一点功能<br>a) 乱码问题解决<br>b) 新增书目时上传图片功能<br>c) 删除图书、分类功能<br>d) 购物车计算、提交更改后使用Ajax，做到不刷新界面。<br><img src ="http://www.blogjava.net/zellux/aggbug/117683.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-15 19:11 <a href="http://www.blogjava.net/zellux/archive/2007/05/15/117683.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于Filter的基本知识</title><link>http://www.blogjava.net/zellux/archive/2007/05/13/117125.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Sun, 13 May 2007 09:12:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/13/117125.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/117125.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/13/117125.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/117125.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/117125.html</trackback:ping><description><![CDATA[<p>1. Filter 简介<br>这方面的内容以前看的几本书里都找不到，想到了Sun J2EE的Tutorial，果然里面有比较详细的解释。<br>Filter是一个传输请求或者响应的报头和内容的对象，通常的作用是：<br>a) 根据不同情况处理请求。<br>b) 阻止请求-响应的过远传送。(Block the request-and-response pair from passing any further.)<br>c) 通过自定义新的请求版本，修改请求报头和数据。<br>d) 通过自定义新的响应版本，修改响应报头和数据。<br>e) 和外部资源交互。</p>
<p>2. Filter 编程<br>filtering API由javax.servlet包中的Filter, FilterChain和FilterConfig接口定义。<br>其中最重要的方法是doFilter。它可以用来：<br>a) 检查请求报头。<br>b) 自定义请求对象。<br>c) 自定义响应对象。<br>d) 调用过滤链(filter chain)中的下一个实体(entity)。如果当前过滤器已经是链中最后一个过滤器了，下一个实体就是链尾的资源；否则它就是在WAR中设置的下一个过滤器。当然也可以在此时通过不调用下一个实体来中断请求、<br>e) 在响应报头调用下一个过滤器后检查。<br>f) 抛出反应处理错误的异常。</p>
<p>3. 一个 Duke's Bookstore 的例子<br>HitCounterFilter在servlet被访问时计数。<br>public final class HitCounterFilter implements Filter {<br>&nbsp; private FilterConfig filterConfig = null;</p>
<p>&nbsp; public void init(FilterConfig filterConfig) <br>&nbsp;&nbsp;&nbsp; throws ServletException {<br>&nbsp;&nbsp;&nbsp; this.filterConfig = filterConfig;<br>&nbsp; }<br>&nbsp; public void destroy() {<br>&nbsp;&nbsp;&nbsp; this.filterConfig = null;<br>&nbsp; }<br>&nbsp; public void doFilter(ServletRequest request,<br>&nbsp;&nbsp;&nbsp; ServletResponse response, FilterChain chain) <br>&nbsp;&nbsp;&nbsp; throws IOException, ServletException {<br>&nbsp;&nbsp;&nbsp; if (filterConfig == null)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return;<br>&nbsp;&nbsp;&nbsp; StringWriter sw = new StringWriter();<br>&nbsp;&nbsp;&nbsp; PrintWriter writer = new PrintWriter(sw);<br>&nbsp;&nbsp;&nbsp; Counter counter = (Counter)filterConfig.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getServletContext().<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getAttribute("hitCounter");<br>&nbsp;&nbsp;&nbsp; writer.println();<br>&nbsp;&nbsp;&nbsp; writer.println("===============");<br>&nbsp;&nbsp;&nbsp; writer.println("The number of hits is: " +<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; counter.incCounter());<br>&nbsp;&nbsp;&nbsp; writer.println("===============");<br>&nbsp;&nbsp;&nbsp; // Log the resulting string<br>&nbsp;&nbsp;&nbsp; writer.flush();<br>&nbsp;&nbsp;&nbsp; System.out.println(sw.getBuffer().toString());<br>&nbsp;&nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp; chain.doFilter(request, wrapper);<br>&nbsp;&nbsp;&nbsp; ...<br>&nbsp; }<br>} </p>
<p>4. 设置过滤器映射<br>部署描述符文件的2.3版本引入了两个用于过滤器的元素，分别是：filter和filter-mapping。filter元素向系统注册一个过滤对象，filter-mapping元素指定该过滤对象所应用的URL。<br>1.filter元素<br>filter元素位于部署描述符文件（web.xml）的前部，所有filter-mapping、servlet或servlet-mapping元素之前。filter元素具有如下六个可能的子元素：<br>icon 这是一个可选的元素，它声明IDE能够使用的一个图象文件。<br>filter-name 这是一个必需的元素，它给过滤器分配一个选定的名字。<br>display-name 这是一个可选的元素，它给出IDE使用的短名称。<br>description 这也是一个可选的元素，它给出IDE的信息，提供文本文档。<br>filter-class 这是一个必需的元素，它指定过滤器实现类的完全限定名。<br>init-param 这是一个可选的元素，它定义可利用FilterConfig的getInitParameter方法读取的初始化参数。单个过滤器元素可包含多个init-param元素。</p>
<p>filter-mapping元素<br>filter-mapping元素位于web.xml文件中filter元素之后serlvet元素之前。它包含如下三个可能的子元素：：<br>l filter-name 这个必需的元素必须与用filter元素声明时给予过滤器的名称相匹配。<br>l url-pattern 此元素声明一个以斜杠（/）开始的模式，它指定过滤器应用的URL。所有filter-mapping元素中必须提供url-pattern或servlet-name。但不能对单个filter-mapping元素提供多个url-pattern元素项。如果希望过滤器适用于多个模式，可重复整个filter-mapping元素。<br>l servlet-name 此元素给出一个名称，此名称必须与利用servlet元素给予servlet或JSP页面的名称相匹配。不能给单个filter-mapping元素提供多个servlet-name元素项。如果希望过滤器适合于多个servlet名，可重复这个filter-mapping元素。</p>
<p>&nbsp;</p><img src ="http://www.blogjava.net/zellux/aggbug/117125.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-13 17:12 <a href="http://www.blogjava.net/zellux/archive/2007/05/13/117125.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web Project 3 笔记 (1)</title><link>http://www.blogjava.net/zellux/archive/2007/05/11/116866.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 11 May 2007 14:32:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/11/116866.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/116866.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/11/116866.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/116866.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/116866.html</trackback:ping><description><![CDATA[<p>感觉比去年那个简单点。不少地方都简化了，比如图书分类，使用了enum类型，而不像去年的需要多表查询才能获得分类。<br>使用了Struts + Hibernate，准备先把基本功能做出来，然后再加上Ajax。<br>1. html:select 的列表框选择<br>在csdn上看到的两种方法：<br>1)<br>&lt;html:select&nbsp;&nbsp; property="personnelId"&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;html:option&nbsp;&nbsp; value=""&gt;请选择&lt;/html:option&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;html:options&nbsp;&nbsp;collection="personList"&nbsp;&nbsp; property="personId"&nbsp;&nbsp; labelProperty="personName"/&gt;&nbsp;&nbsp; <br>&nbsp; &lt;/html:select&gt;&nbsp;&nbsp; <br>&nbsp; html:options自动帮你迭代personList中的内容，前提是personList是Collection类型的，而且封装的是一个包含personId，personName属性的对象&nbsp;&nbsp; <br>&nbsp; property显示的是value，labelProperty显示的是页面看到的内容</p>
<br>2)<br>&lt;html:select&gt;&nbsp;&nbsp; <br>&nbsp; &lt;html:option&nbsp;&nbsp; value=""&gt;请选择***&lt;/html:option&gt;&nbsp;&nbsp; <br>&nbsp; &lt;logic:notEmpty&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &lt;logic:iterate&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;option&nbsp;&nbsp; value='11'&gt;11&lt;/option&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; &lt;/logic:iterate&gt;&nbsp;&nbsp; <br>&nbsp; &lt;/logic:notEmpty&gt;&nbsp;&nbsp; <br>&lt;/html:select&gt; <br><br>2. jsp页面中用户权限判断的问题<br>BBS上问了下，一般是采用Filter类的。具体方法明天再看吧。<img src ="http://www.blogjava.net/zellux/aggbug/116866.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-11 22:32 <a href="http://www.blogjava.net/zellux/archive/2007/05/11/116866.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK1.5 源码阅读笔记 (2)</title><link>http://www.blogjava.net/zellux/archive/2007/05/04/115294.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Fri, 04 May 2007 05:11:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/04/115294.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/115294.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/04/115294.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/115294.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/115294.html</trackback:ping><description><![CDATA[<strong>java.util.AbstractCollection</strong><br>感谢BBS上的outerheaven解答了add(E o)方法的问题。在把add方法写成抛出异常不是为了防止子类向上转型时错误地调用AbstractCollection的这个方法，而是为了让不支持add方法的子类继承，比如EnumSet类，它的元素是在创建时就决定的，不支持add方法。<br><br><strong>java.util.AbstractList<br></strong><font color="#000000">1) 包含了<br>private class Itr implements Iterator&lt;E&gt; <br></font>private class ListItr extends Itr implements ListIterator&lt;E&gt;<br>而ListIterator又是继承Iterator接口的。<br><u>分成两个类写是不是为了使代码清晰呢？</u><br><br>2) 使用了modCount变量检查并发操作时容易发生的问题。<br>Iterator中有一个expectedModCount变量，每次通过Iterator操作时，都会调用checkForComodification()方法，检查expectedModCount是否和AbstractList的modCount相等，如果不同则抛出ConcurrentModificationException。 <br><br>3) subList方法和SubList类和视图view有关（是不是Observer模式的应用呢？），先不看了<br><br>4) equals方法中最后那个判断语句有点新颖（或者我土了）<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img id="Codehighlighter1_32_410_Open_Image" onclick="this.style.display='none'; codehighlighter1_32_410_open_text.style.display="'none';" codehighlighter1_32_410_closed_image.style.display="'inline';" codehighlighter1_32_410_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_32_410_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_32_410_closed_text.style.display="'none';" codehighlighter1_32_410_open_image.style.display="'inline';" codehighlighter1_32_410_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top"><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">boolean</span><span style="color: #000000;">&nbsp;equals(Object&nbsp;o)&nbsp;</span><span id="Codehighlighter1_32_410_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_32_410_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(o&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">)<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">true</span><span style="color: #000000;">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">(o&nbsp;</span><span style="color: #0000ff;">instanceof</span><span style="color: #000000;">&nbsp;List))<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;ListIterator</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">E</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;e1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;listIterator();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;ListIterator&nbsp;e2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;((List)&nbsp;o).listIterator();<br><img id="Codehighlighter1_239_362_Open_Image" onclick="this.style.display='none'; codehighlighter1_239_362_open_text.style.display="'none';" codehighlighter1_239_362_closed_image.style.display="'inline';" codehighlighter1_239_362_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_239_362_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_239_362_closed_text.style.display="'none';" codehighlighter1_239_362_open_image.style.display="'inline';" codehighlighter1_239_362_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">while</span><span style="color: #000000;">(e1.hasNext()&nbsp;</span><span style="color: #000000;">&amp;&amp;</span><span style="color: #000000;">&nbsp;e2.hasNext())&nbsp;</span><span id="Codehighlighter1_239_362_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_239_362_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;E&nbsp;o1&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e1.next();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;Object&nbsp;o2&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;e2.next();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(</span><span style="color: #000000;">!</span><span style="color: #000000;">(o1</span><span style="color: #000000;">==</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;o2</span><span style="color: #000000;">==</span><span style="color: #0000ff;">null</span><span style="color: #000000;">&nbsp;:&nbsp;o1.equals(o2)))<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">false</span><span style="color: #000000;">;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">(e1.hasNext()&nbsp;</span><span style="color: #000000;">||</span><span style="color: #000000;">&nbsp;e2.hasNext());<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">}</span></div>
<br>5) hashCode的生成：<br>hashCode(e1, e2, ..., en) = Sigma(hashCode(ei) * 32^i)<br>没有考虑溢出之类的情况，因为只是个hashCode嘛<br><br><img src ="http://www.blogjava.net/zellux/aggbug/115294.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-04 13:11 <a href="http://www.blogjava.net/zellux/archive/2007/05/04/115294.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JDK1.5 源码阅读笔记 (1)</title><link>http://www.blogjava.net/zellux/archive/2007/05/03/115082.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 02 May 2007 17:33:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/03/115082.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/115082.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/03/115082.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/115082.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/115082.html</trackback:ping><description><![CDATA[1. java.util.AbstractionCollection<br>&nbsp; a) add(E o)方法只有一行<br>throw new UnsupportedOperationException();<br>由于不同的容器有不同的加入元素的方法，这么做应该是为了方式它的子类调用父类的这个方法。<br><u>既然如此，为什么不把方法声明为abstract呢？<br></u><br>&nbsp; b)&nbsp;容器类的toString()方法就是从AbstractionCollection里继承的。 <br>
<img src ="http://www.blogjava.net/zellux/aggbug/115082.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-03 01:33 <a href="http://www.blogjava.net/zellux/archive/2007/05/03/115082.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>05 Web Project3 (2)</title><link>http://www.blogjava.net/zellux/archive/2007/05/02/115015.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Wed, 02 May 2007 05:35:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/02/115015.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/115015.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/02/115015.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/115015.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/115015.html</trackback:ping><description><![CDATA[1. CSS控制input标签的风格有点麻烦，google到了一种在css中使用三元判断语句的方法：<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #008080;">1</span><img id="Codehighlighter1_6_81_Open_Image" onclick="this.style.display='none'; codehighlighter1_6_81_open_text.style.display="'none';" codehighlighter1_6_81_closed_image.style.display="'inline';" codehighlighter1_6_81_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_6_81_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_6_81_closed_text.style.display="'none';" codehighlighter1_6_81_open_image.style.display="'inline';" codehighlighter1_6_81_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top"><span style="color: #800000;">input&nbsp;</span><span id="Codehighlighter1_6_81_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;">{<img src="http://www.blogjava.net/Images/dot.gif">}</span><span id="Codehighlighter1_6_81_Open_Text"><span style="color: #000000;">{</span><span style="color: #ff0000;"><br></span><span style="color: #008080;">2</span><span style="color: #ff0000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;width</span><span style="color: #000000;">:</span><span style="color: #0000ff;">&nbsp;expression(this.type!="submit"?'150px':'')</span><span style="color: #000000;">;</span><span style="color: #ff0000;"><br></span><span style="color: #008080;">3</span><span style="color: #ff0000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;height</span><span style="color: #000000;">:</span><span style="color: #0000ff;">&nbsp;23px</span><span style="color: #000000;">;</span><span style="color: #ff0000;"><br></span><span style="color: #008080;">4</span><span style="color: #ff0000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top"></span><span style="color: #000000;">}</span></span></div>
<br>2. 循环&lt;c:forEach var="i" begin="1" end="${pages}"&gt;<br>&nbsp;<br>3. 分支<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><span style="color: #008080;">1</span><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">c:choose</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">2</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">c:when&nbsp;</span><span style="color: #ff0000;">test</span><span style="color: #0000ff;">="${boolean1}"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">c:when</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">3</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">c:when&nbsp;</span><span style="color: #ff0000;">test</span><span style="color: #0000ff;">="${boolean2}"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">c:when</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">4</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">c:otherwise</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">c:otherwise</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br></span><span style="color: #008080;">5</span><span style="color: #000000;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">c:choose</span><span style="color: #0000ff;">&gt;</span></div>
<p><br>4. DisplayTag 标签库<br>这东东真不错，支持奇偶数行css分离、自动换页等功能。<br>a) &lt;display:table name="test" /&gt;<br>这样一行代码就能自动列出test内的所有属性了。<br>b) 如果要只列出指定的列，可以使用</p>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">display:table&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="test"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">　　&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">display:column&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="id"</span><span style="color: #ff0000;">&nbsp;title</span><span style="color: #0000ff;">="ID"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">　　&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">display:column&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="name"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">　　&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">display:column&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="email"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">　　&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">display:column&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="status"</span><span style="color: #ff0000;">&nbsp;</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top">　　&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">display:column&nbsp;</span><span style="color: #ff0000;">property</span><span style="color: #0000ff;">="description"</span><span style="color: #ff0000;">&nbsp;title</span><span style="color: #0000ff;">="Comments"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">display:table</span><span style="color: #0000ff;">&gt;</span></div>
<p>c) 指定某一列的样式：&lt;display:column property="id" title="ID" class="idcol"/&gt;<br>d)&nbsp;创建简单的动态链接<br>&lt;display:column property="email" href="details.jsp" paramId="action" paramName="testparam" paramScope="request" /&gt;<br>这样只能产生details?action=xx的链接</p>
d) 自定义动态链接<br>写一个类，继承org.displaytag.decorator.TableDecorator<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; font-size: 13px; width: 98%; background-color: #eeeeee;"><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><span style="color: #0000ff;">package</span><span style="color: #000000;">&nbsp;util;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"></span><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;org.displaytag.decorator.TableDecorator;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/None.gif" align="top"><br><img id="Codehighlighter1_110_299_Open_Image" onclick="this.style.display='none'; codehighlighter1_110_299_open_text.style.display="'none';" codehighlighter1_110_299_closed_image.style.display="'inline';" codehighlighter1_110_299_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockStart.gif" align="top"><img id="Codehighlighter1_110_299_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_110_299_closed_text.style.display="'none';" codehighlighter1_110_299_open_image.style.display="'inline';" codehighlighter1_110_299_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedBlock.gif" align="top"></span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Decorator&nbsp;</span><span style="color: #0000ff;">extends</span><span style="color: #000000;">&nbsp;TableDecorator&nbsp;</span><span id="Codehighlighter1_110_299_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_110_299_Open_Text"><span style="color: #000000;">{<br><img id="Codehighlighter1_142_297_Open_Image" onclick="this.style.display='none'; codehighlighter1_142_297_open_text.style.display="'none';" codehighlighter1_142_297_closed_image.style.display="'inline';" codehighlighter1_142_297_closed_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top"><img id="Codehighlighter1_142_297_Closed_Image" style="display: none;" onclick="this.style.display='none'; codehighlighter1_142_297_closed_text.style.display="'none';" codehighlighter1_142_297_open_image.style.display="'inline';" codehighlighter1_142_297_open_text.style.display="'inline';"" src="http://www.blogjava.net/Images/OutliningIndicators/ContractedSubBlock.gif" align="top">&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;getEditLink()&nbsp;</span><span id="Codehighlighter1_142_297_Closed_Text" style="border: 1px solid #808080; display: none; background-color: #ffffff;"><img src="http://www.blogjava.net/Images/dot.gif"></span><span id="Codehighlighter1_142_297_Open_Text"><span style="color: #000000;">{<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;beans.Policy&nbsp;p&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(beans.Policy)getCurrentRowObject();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">int</span><span style="color: #000000;">&nbsp;pId&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;p.getId();<br><img src="http://www.blogjava.net/Images/OutliningIndicators/InBlock.gif" align="top">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">&lt;a&nbsp;href=\</span><span style="color: #000000;">"</span><span style="color: #000000;">servlet</span><span style="color: #000000;">/</span><span style="color: #000000;">editItem</span><span style="color: #000000;">?</span><span style="color: #000000;">id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">&nbsp;+&nbsp;pId&nbsp;+&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">\</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;@&lt;/a&gt;</span><span style="color: #000000;">"</span><span style="color: #000000;">;&nbsp;&nbsp;<br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top">&nbsp;&nbsp;}</span></span><span style="color: #000000;"><br><img src="http://www.blogjava.net/Images/OutliningIndicators/ExpandedBlockEnd.gif" align="top">}</span></span></div>
然后在jsp中声明这个Decorator<br>&lt;display:table name="policies" id="PolicyList" decorator="util.Decorator"&gt;<br>增加相应的列<br>&lt;display:column title="Edit" property="editLink"/&gt;<br>e) 生成的html代码中奇偶数行的类分别为.odd和.even，在CSS中就能区分它们了。<br>f) 分页<br>display:table 中加个属性pagesize="10"即可，不过觉得这部分还是在数据库中解决比较高效。<br>g) 排序<br>列中的对象要实现Comparable接口，没有的话可以使用Decorator<br>display:table 中的属性<br>defaultsort="1"&nbsp;&nbsp; 默认以第一列为主键排序<br>defaultorder="descending"&nbsp; 递减<br>也可以在display:column中增加属性sortable="true" headerClass="sortable"<br>官方给出的sample中的那个sortable列表头很漂亮，有两个小按钮选择排序方式。<img src ="http://www.blogjava.net/zellux/aggbug/115015.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-02 13:35 <a href="http://www.blogjava.net/zellux/archive/2007/05/02/115015.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>05 Web Project3 (1)</title><link>http://www.blogjava.net/zellux/archive/2007/05/02/114989.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 01 May 2007 17:05:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/02/114989.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/114989.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/02/114989.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/114989.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/114989.html</trackback:ping><description><![CDATA[<p>开始做05Web应用课的Project3。<br>主要为了实践下EL/JSTL，以及用servlet + jsp + javabean的mvc架构；SQL嘛上学期学过，Core Java II里介绍得也比较详细，所以直接用Hibernate持久层解决问题了。<br><br>1. jsp里form action指向的路径居然打成了"servet/loginServet"，然后tomcat报错。查了好一会儿web.xml也没发现什么问题，然后很郁闷的发现居然是jsp里路径写错了&nbsp; <img src="http://www.blogjava.net/Emoticons/QQ/icon10.gif" border="0" height="20" width="20"><br><br>2. 登录jsp递交到servlet时如何隐藏用户名密码呢？</p>
<br>3. admin登录后要显示Policy列表。我建了个beans.Policies类，然后在控制器servlet中<br>List policies = beans.Policies.getPolicies();&nbsp;&nbsp; //还没实现分页功能<br>然后再setAttribute递交给显示页面。<br>觉得不应该这么做，尽管的确是mvc分离了，但很占资源，而且貌似Policies类每处理一次请求都要访问一次数据库，不知道有没有更好的方法。JavaBean？<br><br>4. Policy列表行颜色深浅相间的效果。在饮水思源上看到过类似的问题，貌似正规的做法是自定义标签。。。<img src ="http://www.blogjava.net/zellux/aggbug/114989.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zellux/" target="_blank">ZelluX</a> 2007-05-02 01:05 <a href="http://www.blogjava.net/zellux/archive/2007/05/02/114989.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts 学习笔记(3) - 文件上传的实现</title><link>http://www.blogjava.net/zellux/archive/2007/05/01/114960.html</link><dc:creator>ZelluX</dc:creator><author>ZelluX</author><pubDate>Tue, 01 May 2007 13:04:00 GMT</pubDate><guid>http://www.blogjava.net/zellux/archive/2007/05/01/114960.html</guid><wfw:comment>http://www.blogjava.net/zellux/comments/114960.html</wfw:comment><comments>http://www.blogjava.net/zellux/archive/2007/05/01/114960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zellux/comments/commentRss/114960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zellux/services/trackbacks/114960.html</trackback:ping><description><![CDATA[struts标签库中有相应html:file标签，enctype这个属性貌似去掉也可以，不知道有什么