﻿<?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-ZT文萃-随笔分类-中间件</title><link>http://www.blogjava.net/longturi/category/53894.html</link><description>本博不原创，转帖自己感兴趣那些事人物，什么入眼贴什么,随心所欲。</description><language>zh-cn</language><lastBuildDate>Tue, 06 May 2014 01:44:52 GMT</lastBuildDate><pubDate>Tue, 06 May 2014 01:44:52 GMT</pubDate><ttl>60</ttl><item><title>谈谈hashCode</title><link>http://www.blogjava.net/longturi/archive/2014/05/04/413189.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Sat, 03 May 2014 22:23:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/05/04/413189.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/413189.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/05/04/413189.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/413189.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/413189.html</trackback:ping><description><![CDATA[下文转帖自：<div>http://www.cnblogs.com/chenssy/p/3651218.html</div>版权归作者所有。<br /><br /><div><h2>hashCode的作用</h2>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要想了解一个方法的内在原理，我们首先需要明白它是干什么的，也就是这个方法的作用。在讲解数组时（<a href="http://www.cnblogs.com/chenssy/p/3463719.html" target="_blank">java提高篇（十八）------数组</a>），我们提到数组是java中效率最高的数据结构，但是&#8220;最高&#8221;是有前提的。第一我们需要知道所查询数据的所在位置。第二：如果我们进行迭代查找时，数据量一定要小，对于大数据量而言一般推荐集合。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;   在Java集合中有两类，一类是List，一类是Set他们之间的区别就在于List集合中的元素师有序的，且可以重复，而Set集合中元素是无序不可重 复的。对于List好处理，但是对于Set而言我们要如何来保证元素不重复呢？通过迭代来equals()是否相等。数据量小还可以接受，当我们的数据量 大的时候效率可想而知（当然我们可以利用算法进行优化）。比如我们向HashSet插入1000数据，难道我们真的要迭代1000次，调用1000次 equals()方法吗？hashCode提供了解决方案。怎么实现？我们先看hashCode的源码(Object)。</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px">   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">native</span> <span style="color: #0000ff">int</span> hashCode();</pre> </div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  它是一个本地方法，它的实现与本地机器有关，这里我们暂且认为他返回的是对象存储的物理位置（实际上不是，这里写是便于理解）。当我们向一个集合中添加某 个元素，集合会首先调用hashCode方法，这样就可以直接定位它所存储的位置，若该处没有其他元素，则直接保存。若该处已经有元素存在，就调用 equals方法来匹配这两个元素是否相同，相同则不存，不同则散列到其他位置（具体情况请参考（Java提高篇（）-----HashMap））。这样 处理，当我们存入大量元素时就可以大大减少调用equals()方法的次数，极大地提高了效率。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所以<strong>hashCode在上面扮演的角色为寻域</strong>（寻 找某个对象在集合中区域位置）。hashCode可以将集合分成若干个区域，每个对象都可以计算出他们的hash码，可以将hash码分组，每个分组对应 着某个存储区域，根据一个对象的hash码就可以确定该对象所存储区域，这样就大大减少查询匹配元素的数量，提高了查询效率。</p>  <h2>hashCode对于一个对象的重要性</h2>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  hashCode重要么？不重要，对于List集合、数组而言，他就是一个累赘，但是对于HashMap、HashSet、HashTable而言，它变 得异常重要。所以在使用HashMap、HashSet、HashTable时一定要注意hashCode。对于一个对象而言，其hashCode过程就 是一个简单的Hash算法的实现，其实现过程对你实现对象的存取过程起到非常重要的作用。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在前面LZ提到了HashMap和HashTable两种数据结构，虽然他们存在若干个区别，但是他们的实现原理是相同的，这里我以HashTable为例阐述hashCode对于一个对象的重要性。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  一个对象势必会存在若干个属性，如何选择属性来进行散列考验着一个人的设计能力。如果我们将所有属性进行散列，这必定会是一个糟糕的设计，因为对象的 hashCode方法无时无刻不是在被调用，如果太多的属性参与散列，那么需要的操作数时间将会大大增加，这将严重影响程序的性能。但是如果较少属相参与 散列，散列的多样性会削弱，会产生大量的散列&#8220;冲突&#8221;，除了不能够很好的利用空间外，在某种程度也会影响对象的查询效率。其实这两者是一个矛盾体，散列的 多样性会带来性能的降低。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 那么如何对对象的hashCode进行设计，LZ也没有经验。从网上查到了这样一种解决方案：设置一个缓存标识来缓存当前的散列码，只有当参与散列的对象改变时才会重新计算，否则调用缓存的hashCode，这样就可以从很大程度上提高性能。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在HashTable计算某个对象在table[]数组中的索引位置，其代码如下：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px">   <pre><span style="color: #0000ff">int</span> index = (hash &amp; 0x7FFFFFFF) % tab.length;</pre> </div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  为什么要&amp;0x7FFFFFFF？因为某些对象的hashCode可能会为负值，与0x7FFFFFFF进行与运算可以确保index为一个正 数。通过这步我可以直接定位某个对象的位置，所以从理论上来说我们是完全可以利用hashCode直接定位对象的散列表中的位置，但是为什么会存在一个 key-value的键值对，利用key的hashCode来存入数据而不是直接存放value呢？这就关系HashTable性能问题的最重要的问 题:Hash冲突！</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  我们知道冲突的产生是由于不同的对象产生了相同的散列码，假如我们设计对象的散列码可以确保99.999999999%的不重复，但是有一种绝对且几乎不 可能遇到的冲突你是绝对避免不了的。我们知道hashcode返回的是int，它的值只可能在int范围内。如果我们存放的数据超过了int的范围呢？这 样就必定会产生两个相同的index，这时在index位置处会存储两个对象，我们就可以利用key本身来进行判断。所以具有相索引的对象，在该 index位置处存在多个对象，我们必须依靠key的hashCode和key本身来进行区分。</p>  <h2>hashCode与equals</h2>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  在Java中hashCode的实现总是伴随着equals，他们是紧密配合的，你要是自己设计了其中一个，就要设计另外一个。当然在多数情况下，这两个 方法是不用我们考虑的，直接使用默认方法就可以帮助我们解决很多问题。但是在有些情况，我们必须要自己动手来实现它，才能确保程序更好的运作。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于equals，我们必须遵循如下规则：</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对称性：如果x.equals(y)返回是&#8220;true&#8221;，那么y.equals(x)也应该返回是&#8220;true&#8221;。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 反射性：x.equals(x)必须返回是&#8220;true&#8221;。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 类推性：如果x.equals(y)返回是&#8220;true&#8221;，而且y.equals(z)返回是&#8220;true&#8221;，那么z.equals(x)也应该返回是&#8220;true&#8221;。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一致性：如果x.equals(y)返回是&#8220;true&#8221;，只要x和y内容一直不变，不管你重复x.equals(y)多少次，返回都是&#8220;true&#8221;。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 任何情况下，x.equals(null)，永远返回是&#8220;false&#8221;；x.equals(和x不同类型的对象)永远返回是&#8220;false&#8221;。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于hashCode，我们应该遵循如下规则：</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1. 在一个应用程序执行期间，如果一个对象的equals方法做比较所用到的信息没有被修改的话，则对该对象调用hashCode方法多次，它必须始终如一地返回同一个整数。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2. 如果两个对象根据equals(Object o)方法是相等的，则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3. 如果两个对象根据equals(Object o)方法是不相等的，则调用这两个对象中任一个对象的hashCode方法，不要求产生不同的整数结果。但如果能不同，则可能提高散列表的性能。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 至于两者之间的关联关系，我们只需要记住如下即可：</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果x.equals(y)返回&#8220;true&#8221;，那么x和y的hashCode()必须相等。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果x.equals(y)返回&#8220;false&#8221;，那么x和y的hashCode()有可能相等，也有可能不等。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 理清了上面的关系我们就知道他们两者是如何配合起来工作的。先看下图：</p>  <p><a href="http://images.cnitblog.com/blog/381060/201404/080846536063051.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="2014040701_thumb2" alt="2014040701_thumb2" src="http://images.cnitblog.com/blog/381060/201404/080846541064964.png" height="404" border="0" width="314" /></a></p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 整个处理流程是：</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1、判断两个对象的hashcode是否相等，若不等，则认为两个对象不等，完毕，若相等，则比较equals。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2、若两个对象的equals不等，则可以认为两个对象不等，否则认为他们相等。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实例：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Person {     </span><span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span><span style="color: #000000"> age;     </span><span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span> sex;    <span style="color: #008000">//</span><span style="color: #008000">0：男，1：女</span>     <span style="color: #0000ff">private</span><span style="color: #000000"> String name;      </span><span style="color: #0000ff">private</span> <span style="color: #0000ff">final</span> <span style="color: #0000ff">int</span> PRIME = 37<span style="color: #000000">;      Person(</span><span style="color: #0000ff">int</span> age ,<span style="color: #0000ff">int</span><span style="color: #000000"> sex ,String name){         </span><span style="color: #0000ff">this</span>.age =<span style="color: #000000"> age;         </span><span style="color: #0000ff">this</span>.sex =<span style="color: #000000"> sex;         </span><span style="color: #0000ff">this</span>.name =<span style="color: #000000"> name;     }      </span><span style="color: #008000">/**</span><span style="color: #008000"> 省略getter、setter方法 *</span><span style="color: #008000">*/</span><span style="color: #000000">      @Override     </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">int</span><span style="color: #000000"> hashCode() {         System.out.println(</span>"调用hashCode方法..........."<span style="color: #000000">);          </span><span style="color: #0000ff">int</span> hashResult = 1<span style="color: #000000">;         hashResult </span>= (hashResult + Integer.valueOf(age).hashCode() + Integer.valueOf(sex).hashCode()) *<span style="color: #000000"> PRIME;         hashResult </span>= PRIME * hashResult + ((name == <span style="color: #0000ff">null</span>) ? 0<span style="color: #000000"> : name.hashCode());          System.out.println(</span>"name:"+name +" hashCode:" +<span style="color: #000000"> hashResult);          </span><span style="color: #0000ff">return</span><span style="color: #000000"> hashResult;     }      </span><span style="color: #008000">/**</span><span style="color: #008000">      * 重写hashCode()      </span><span style="color: #008000">*/</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">boolean</span><span style="color: #000000"> equals(Object obj) {         System.out.println(</span>"调用equals方法..........."<span style="color: #000000">);          </span><span style="color: #0000ff">if</span>(obj == <span style="color: #0000ff">null</span><span style="color: #000000">){             </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;         }         </span><span style="color: #0000ff">if</span>(obj.getClass() != <span style="color: #0000ff">this</span><span style="color: #000000">.getClass()){             </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;         }         </span><span style="color: #0000ff">if</span>(<span style="color: #0000ff">this</span> ==<span style="color: #000000"> obj){             </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;         }          Person person </span>=<span style="color: #000000"> (Person) obj;          </span><span style="color: #0000ff">if</span>(getAge() != person.getAge() || getSex()!=<span style="color: #000000"> person.getSex()){             </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;         }          </span><span style="color: #0000ff">if</span>(getName() != <span style="color: #0000ff">null</span><span style="color: #000000">){             </span><span style="color: #0000ff">if</span>(!<span style="color: #000000">getName().equals(person.getName())){                 </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;             }         }         </span><span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span>(person != <span style="color: #0000ff">null</span><span style="color: #000000">){             </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">false</span><span style="color: #000000">;         }         </span><span style="color: #0000ff">return</span> <span style="color: #0000ff">true</span><span style="color: #000000">;     } }</span></pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 该Bean为一个标准的Java Bean，重新实现了hashCode方法和equals方法。</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> Main <span style="color: #0000ff">extends</span><span style="color: #000000"> JPanel {      </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {         Set</span>&lt;Person&gt; set = <span style="color: #0000ff">new</span> HashSet&lt;Person&gt;<span style="color: #000000">();          Person p1 </span>= <span style="color: #0000ff">new</span> Person(11, 1, "张三"<span style="color: #000000">);         Person p2 </span>= <span style="color: #0000ff">new</span> Person(12, 1, "李四"<span style="color: #000000">);         Person p3 </span>= <span style="color: #0000ff">new</span> Person(11, 1, "张三"<span style="color: #000000">);         Person p4 </span>= <span style="color: #0000ff">new</span> Person(11, 1, "李四"<span style="color: #000000">);          </span><span style="color: #008000">//</span><span style="color: #008000">只验证p1、p3</span>         System.out.println("p1 == p3? :" + (p1 ==<span style="color: #000000"> p3));         System.out.println(</span>"p1.equals(p3)?:"+<span style="color: #000000">p1.equals(p3));         System.out.println(</span>"-----------------------分割线--------------------------"<span style="color: #000000">);         set.add(p1);         set.add(p2);         set.add(p3);         set.add(p4);         System.out.println(</span>"set.size()="+<span style="color: #000000">set.size());     } }</span></pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 运行结果如下：</p>  <p><a href="http://images.cnitblog.com/blog/381060/201404/080846546221108.png"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px; padding-top: 0px" title="2014040702_thumb" alt="2014040702_thumb" src="http://images.cnitblog.com/blog/381060/201404/080846551068792.png" height="309" border="0" width="891" /></a></p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从上图可以看出，程序调用四次hashCode方法，一次equals方法，其set的长度只有3。add方法运行流程完全符合他们两者之间的处理流程。</p></div><img src ="http://www.blogjava.net/longturi/aggbug/413189.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-05-04 06:23 <a href="http://www.blogjava.net/longturi/archive/2014/05/04/413189.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转帖：Java邮件开发-----电子邮件的基本概念介绍</title><link>http://www.blogjava.net/longturi/archive/2014/05/04/413188.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Sat, 03 May 2014 22:19:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/05/04/413188.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/413188.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/05/04/413188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/413188.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/413188.html</trackback:ping><description><![CDATA[下文来自：<div>http://www.cnblogs.com/chenssy/archive/2012/12/09/2809874.html</div>版权归作者所有。<br /><br /><div><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 电子邮件用于网上的信心传递和交流，它是最重要的<span style="font-family: Calibri;">Internet</span>服务之一。据统计<span style="font-family: Calibri;">Internet</span>有<span style="font-family: Calibri;">30%</span>的业务是电子邮件有关的。同时我们也不可否认它在我们的日常生活、工作办公方面扮演着很重要的角色。譬如：许多办公自动化项目<span style="font-family: Calibri;">(OA)</span>中都要附带发送邮件的功能，如果还要使用<span style="font-family: Calibri;">OutLook</span>等手工方式就不适合，在这个高速的时代，我们需要提供工作效率，让工作能够自动化。同时在许多网站中也都需要附带发送邮件的功能：给新注册的用户发送一封包含其注册信息的欢迎<span style="font-family: Calibri;">E-Mail</span>、将网站的最新活动信息通过<span style="font-family: Calibri;">E-Mail</span>发送给所有的注册会员等等。</span> <p>&nbsp;</p> <p><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在开始电子邮件开发前：我们需要明白一下几个概念：电子邮件系统、邮件服务器、电子邮件、邮件客户端软件、邮件传输协议、电子邮件的传输过程。</span></p> <p>&nbsp;</p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">电子邮件系统</span></span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>与 传统的邮政服务相类似，电子邮件系统由电子邮局、电子邮件发送、接收系统组成。发送者和接收者通过电子邮件发送、接收系统来发送和接收电子邮件，他们实际 上是运行在计算机上的邮件客户端程序。电子邮局起着一个桥梁的作用，它实际上是运行在服务器上的邮件服务器程序。电子邮件的处理流程也和邮政服务相类似。</span></p> <p>&nbsp;</p> <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img src="http://img.my.csdn.net/uploads/201212/09/1355026996_7193.jpg" alt="" /></p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">邮件服务器</span></span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>邮件服务器是一种用来负责电子邮件收发管理的设备。在<span style="font-family: Calibri;">Internet</span>上提供了大量的电子邮件服务器，如：<span style="font-family: Calibri;">126</span>、<span style="font-family: Calibri;">163</span>、<span style="font-family: Calibri;">hotmail&#8230;</span>。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>电子邮件服务器主要提供的功能：</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp; 1、</span>&nbsp; 接收用户投递的邮件。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp; 2、</span>&nbsp; 将用户投递进来的邮件转发给目标邮件服务器。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp; 3、</span>&nbsp; 接收其他电子邮件服务器转发来的邮件并该邮件存储到其管理的用户邮中。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp; 4、</span>&nbsp; 为前来读取邮件的用户提供读取邮件的服务。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>邮 件服务器构成了电子邮件系统的核心。每个收信人都有一个位于某个邮件服务器上的邮箱(mailbox)。Bob的邮箱用于管理和维护已经发送给他的邮件消 息。一个邮件消息的典型旅程是从发信人的用户代理开始，邮件发信人的邮件服务器，中转到收信人的邮件服务器，然后投递到收信人的邮箱中。当Bob想查看自 己的邮箱中的邮件消息时，存放该邮箱的邮件服务器将以他提供的用户名和口令认证他。Alice的邮件服务器还得处理Bob的邮件服务器出故障的情况。如果 Alice的邮件服务器无法把邮件消息立即递送到Bob的邮件服务器，Alice的服务器就把它们存放在消息队列(message  queue)中，以后再尝试递送。这种尝试通常每30分钟左右执行一次：要是过了若干天仍未尝试成功，该服务器就把这个消息从消息队列中去除掉，同时以另 一个邮件消息通知发信人(即Alice)。</span></p> <p>&nbsp;</p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">电子邮件</span></span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>电子邮件是一种通过网络实现相互传送和接收信息的现代化通信方式。它是<span style="font-family: Calibri;">&#8212;</span>种用电子手段提供信息交换的通信方式，是<span style="font-family: Calibri;">Internet</span>应用最广的服务，通过网络的电子邮件系统，用户可以用非常低廉的价格，以非常快速的方式，与世界上任何一个角落的网络用户联系，这些电子邮件可以是文字、图像、声音等各种方式。同时，用户可以得到大量免费的新闻、专题邮件，并实现轻松的信息搜索。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>电子邮件由信封和内容两个部分组成。信封又称邮件头，电子邮件服务器根据信封上的信心来传递邮件的。内容称为邮件体，它用于提供邮件的具体内容。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>Internet</span>上的电子邮件地址全球唯一，其格式为&#8220;邮箱名<span style="font-family: Calibri;">@</span>邮件服务器域名&#8221;。域（邮件域）是电子邮件服务器的基本管理单位，邮件服务以域为基础，每个邮箱对应一个用户。其中邮件服务器域名必须是已注册的<span style="font-family: Calibri;">DNS</span>域名，并且必须要与<span style="font-family: Calibri;">MX(</span>邮件交换机<span style="font-family: Calibri;">)</span>记录匹配。<span style="font-family: Calibri;">DNS</span>用于将域名、主机名解析为<span style="font-family: Calibri;">IP</span>地址。<span style="font-family: Calibri;">MX</span>记录指向该域名的邮件服务器主机记录，为邮件服务专用。</span></p> <p>&nbsp;</p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">邮件客户端软件</span></span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>邮件客户端软件负责与邮件服务器通讯，主要用于帮助用户将邮件发送给<span style="font-family: Calibri;">SMTP</span>服务器和<span style="font-family: Calibri;">POP3/IMAP</span>邮件服务器读取用户的电子邮件。邮件客户端软件通常集撰写、发送、接收邮件于一体。</span></p> <p>&nbsp;</p> <p>&nbsp;</p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">电子邮箱</span></span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>每一个电子邮件服务器之上都可以开始多个电子邮箱，电子邮箱也称之为<span style="font-family: Calibri;">E-Mail</span>地址。它类似于现实生活中的通讯地址，用户通过它接受别人发来的电子邮件和向别人发送电子邮件。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>电子邮箱的获得需要在电子邮件服务器上进行申请，确切的说，电子邮箱其实就是用户在邮件服务器上申请的一个账户。邮件服务器把接收到的邮件保持到为某个账户所分配的邮箱空间中，用户通过其申请的用户名和密码登陆到邮件服务器上查看该地址已经收到的电子邮件。</span></p> <p>&nbsp;</p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">电子邮件的传输过程</span></span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span>电子邮件系统采用客户<span style="font-family: Calibri;">/</span>服务器模式。电子邮件传送需要用到以下<span style="font-family: Calibri;">3</span>个重要模块：</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>MUA</span>（<span style="font-family: Calibri;">Mail User Agent</span>，邮件用户代理）：用户通过它与电子邮件服务器打交道。<span style="font-family: Calibri;">MUA</span>实际上就是邮件客户端软件。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>MTA</span>（<span style="font-family: Calibri;">Mail Transfer Agent</span>，邮件传输代理）：它主要负责处理所有接收和发送的邮件，为<span style="font-family: Calibri;">MUA</span>或者<span style="font-family: Calibri;">MTA</span>提供邮件发送服务，接收其他<span style="font-family: Calibri;">MTA</span>发送过来的邮件。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>MDA</span>（<span style="font-family: Calibri;">Mail Delivery Agent</span>，邮件投递代理）：它负责邮件本地投递。当<span style="font-family: Calibri;">MTA</span>决定某邮件发送本地用户时，<span style="font-family: Calibri;">MTA</span>将邮件交给<span style="font-family: Calibri;">MDA</span>程序进行分发，也就是说投递到用户的。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>具体的传递过程如下：</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; 1、</span>&nbsp; 发件人利用<span style="font-family: Calibri;">MUA</span>将邮件发送给<span style="font-family: Calibri;">MTA</span>。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; 2、</span>&nbsp;<span style="font-family: Calibri;">MTA</span>收到邮件后判断收件人是不是本地账户，如果是本地账户，交由<span style="font-family: Calibri;">MDA</span>投送到该账户的邮箱中，完成发送过程，跳到第<span style="font-family: Calibri;">5</span>步。如果不是则执行下一步骤。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; 3、</span>&nbsp;<span style="font-family: Calibri;">MTA</span>根据其邮件中继转发设置来决定如何转发邮件。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; 4、</span>&nbsp; 最终目的的<span style="font-family: Calibri;">MTA</span>将受到的交给他的<span style="font-family: Calibri;">MDA</span>处理，有<span style="font-family: Calibri;">MDA</span>将邮件投递到收件人的邮箱中。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>&nbsp;&nbsp;&nbsp;&nbsp; 5、</span>&nbsp; 收件人利用<span style="font-family: Calibri;">MUA</span>通过<span style="font-family: Calibri;">POP/IMAP</span>协议连接到邮箱所在的服务器，请求查看自己的收件箱是否有邮件，如果有邮件，将会通过它传送个收件人的<span style="font-family: Calibri;">MUA</span>。</span></p> <p><span style="font-size: large;"><span style="color: #0070c0;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>注意：提示邮件访问服务的是</span><span style="color: #0070c0;"><span style="font-family: Calibri;">POP</span></span><span style="color: #0070c0;">或者</span><span style="color: #0070c0;"><span style="font-family: Calibri;">IMAP</span></span><span style="color: #0070c0;">服务器软件，而并非当初收下邮件的</span><span style="color: #0070c0;"><span style="font-family: Calibri;">MTA</span></span><span style="color: #0070c0;">，两者的角色是分离的。</span></span></p> <p><span style="color: #0070c0;">&nbsp;</span></p> <p><span style="color: #ff0000; font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: x-large;">邮件传输协议</span></span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>电子邮件服务传输主要是用到以下<span style="font-family: Calibri;">3</span>中网络协议</span></p> <p><span style="font-size: large;"><span style="color: #ff0000;"><span style="font-family: Calibri;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SMTP(</span></span><span style="color: #ff0000;">简单邮件传输协议</span><span style="color: #ff0000;"><span style="font-family: Calibri;">)</span></span></span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>SMTP</span>是<span style="font-family: Calibri;">Simple Mail Transfer Protocol</span>。标准<span style="font-family: Calibri;">TCP</span>端口是<span style="font-family: Calibri;">25</span>。<span style="font-family: Calibri;">MUA</span>将邮件发送到<span style="font-family: Calibri;">MTA</span>，<span style="font-family: Calibri;">MTA</span>将邮件发送给下一个<span style="font-family: Calibri;">MTA</span>，都是要使用<span style="font-family: Calibri;">SMTP</span>。<span style="font-family: Calibri;">SMTP</span>的目标是可靠高效地传送邮件，它独立于传送子系统而且仅要求一条可以保证传送数据单元顺序的通道。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>SMTP</span>是一个&#8220;单向&#8221;的协议，它不能用户从其他邮件服务器收取邮件。它本身是采用客户<span style="font-family: Calibri;">/</span>服务器模式，负责发送邮件的<span style="font-family: Calibri;">SMTP</span>进程就是<span style="font-family: Calibri;">SMTP</span>客户端，负责接收邮件的<span style="font-family: Calibri;">SMTP</span>进程就是<span style="font-family: Calibri;">SMTP</span>服务器。一个完整的<span style="font-family: Calibri;">SMTP</span>通信过程主要包括建立连接、传送邮件、释放连接三个过程。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>建立连接：首先由发件人将要发送的邮件发送到邮件缓存，<span style="font-family: Calibri;">SMTP</span>客户端定期扫描邮件缓存，一旦发现有邮件，就与<span style="font-family: Calibri;">SMTP</span>服务器建立<span style="font-family: Calibri;">TCP</span>连接，然后发送<span style="font-family: Calibri;">HRLLO</span>命令以附上发送方的主机名。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>传送邮件：<span style="font-family: Calibri;">SMTP</span>客户端使用<span style="font-family: Calibri;">MAIL</span>命令开始传送邮件，该命令提供发件人的地址；然后执行<span style="font-family: Calibri;">RCPT</span>命令，并提供收件人地址；最后执行<span style="font-family: Calibri;">DATA</span>命令传送邮件内容。</span></p> <p><span style="font-size: large;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>释放连接：邮件传送完毕后，<span style="font-family: Calibri;">SMTP</span>客户端发送<span style="font-family: Calibri;">OUT</span>命令请求关闭<span style="font-family: Calibri;">TCP</span>连接。</span></p> <p><span style="font-size: 18px;"><span style="color: #ff0000;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>POP</span></span><span style="color: #ff0000;">（邮局协议）</span></span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>POP</span>是<span style="font-family: Calibri;">Post Office Protocol</span>。标准<span style="font-family: Calibri;">TCP</span>端口为<span style="font-family: Calibri;">110</span>。主要用于电子邮件的接收。<span style="font-family: Calibri;">MUA</span>经由<span style="font-family: Calibri;">POP</span>协议连接到<span style="font-family: Calibri;">MTA</span>的用户收件箱，以读取或下载用户在收件箱中邮件。</span></p> <p><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;目前用的较多的<span style="font-family: Calibri;">POP</span>协议是<span style="font-family: Calibri;">POP3</span>。<span style="font-family: Calibri;">POP3</span>使用<span style="font-family: Calibri;"> TCP </span>作为传输协议。</span></p> <p><span style="font-size: 18px;"><span style="color: #ff0000;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>IMAP</span></span><span style="color: #ff0000;">（</span><span style="color: #ff0000;"><span style="font-family: Calibri;">Internet</span></span><span style="color: #ff0000;">信息访问协议）</span></span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>IMAP</span>是<span style="font-family: Calibri;">Internet Message Access Protocol</span>。标准<span style="font-family: Calibri;">TCP</span>端口为<span style="font-family: Calibri;">143</span>，它也是让<span style="font-family: Calibri;">MUA</span>从<span style="font-family: Calibri;">MTA</span>收取邮件。目标球<span style="font-family: Calibri;">IMAP</span>协议的版本为<span style="font-family: Calibri;">IMAP4</span>。</span></p> <p><span style="font-size: large;"><span style="font-family: Calibri;"><span style="font-size: large;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>POP</span>和<span style="font-family: Calibri;">IMAP</span>两者都可以用于收取邮件，都是采用客户<span style="font-family: Calibri;">/</span>服务器模式，两者最主要的区别就在于他们检索邮件的方式不同。使用<span style="font-family: Calibri;">POP</span>时，邮件驻留在服务器中个，一旦接收邮件，邮件都从服务器上下载到用户计算机上。而<span style="font-family: Calibri;">IMAP</span>则能够然该用户了解到服务器上存储邮件的情况，已下载的邮件仍然滞留在服务器中，以便于实现邮件归档和共享。</span></p></div><img src ="http://www.blogjava.net/longturi/aggbug/413188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-05-04 06:19 <a href="http://www.blogjava.net/longturi/archive/2014/05/04/413188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转帖：渐析java的浅拷贝和深拷贝</title><link>http://www.blogjava.net/longturi/archive/2014/05/04/413187.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Sat, 03 May 2014 22:15:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/05/04/413187.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/413187.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/05/04/413187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/413187.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/413187.html</trackback:ping><description><![CDATA[转载自：<div>http://www.cnblogs.com/chenssy/p/3308489.html</div>版权归作者所有。<br /><br /><div><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先来看看浅拷贝和深拷贝的定义：</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 浅拷贝：使用一个已知实例对新创建实例的成员变量逐个赋值，这个方式被称为浅拷贝。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 深拷贝：当一个类的拷贝构造方法，不仅要复制对象的所有非引用成员变量值，还要为引用类型的成员变量创建新的实例，并且初始化为形式参数实例值。这个方式称为深拷贝</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 也就是说浅拷贝只复制一个对象，传递引用，不能复制实例。而深拷贝对对象内部的引用均复制，它是创建一个新的实例，并且复制实例。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于浅拷贝当对象的成员变量是基本数据类型时，两个对象的成员变量已有存储空间，赋值运算传递值，所以浅拷贝能够复制实例。但是当对象的成员变量是引用数据类型时，就不能实现对象的复制了。 </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 存在一个对象Person，代码如下：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Person {     </span><span style="color: #0000ff">private</span><span style="color: #000000"> String name;     </span><span style="color: #0000ff">private</span><span style="color: #000000"> String sex;     </span><span style="color: #0000ff">private</span> <span style="color: #0000ff">int</span><span style="color: #000000"> age;          </span><span style="color: #0000ff">public</span> Person(String name,String sex,<span style="color: #0000ff">int</span><span style="color: #000000"> age){         </span><span style="color: #0000ff">this</span>.name =<span style="color: #000000"> name;         </span><span style="color: #0000ff">this</span>.sex =<span style="color: #000000"> sex;         </span><span style="color: #0000ff">this</span>.age =<span style="color: #000000"> age;     }          </span><span style="color: #0000ff">public</span> Person(Person p){                   <span style="color: #008000">//</span><span style="color: #008000">拷贝构造方法，复制对象</span>         <span style="color: #0000ff">this</span>.name =<span style="color: #000000"> p.name;         </span><span style="color: #0000ff">this</span>.sex =<span style="color: #000000"> p.sex;         </span><span style="color: #0000ff">this</span>.age =<span style="color: #000000"> p.age;     } }</span></pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的对象Person有三个成员变量。name、sex、age。两个构造方法。第二个的参数为该对象，它称为拷贝构造方法，它将创建的新对象初始化为形式参数的实例值，通过它可以实现对象复制功能。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 又有一个对象Asian,如下：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> Asian {     </span><span style="color: #0000ff">private</span><span style="color: #000000"> String skin;     Person person;          </span><span style="color: #0000ff">public</span><span style="color: #000000"> Asian(String skin,Person person){         </span><span style="color: #0000ff">this</span>.skin =<span style="color: #000000"> skin;         </span><span style="color: #0000ff">this</span>.person = person;                    <span style="color: #008000">//</span><span style="color: #008000">引用赋值</span> <span style="color: #000000">    }      </span><span style="color: #0000ff">public</span> Asian(Asian asian){                 <span style="color: #008000">//</span><span style="color: #008000">拷贝构造方法，复制对象</span>         <span style="color: #0000ff">this</span><span style="color: #000000">(asian.skin,asian.person);                } }</span></pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面对象也存在着两个成员变量，skin 和Person对象</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于person对象有如下：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px">   <pre>Person p1 = <span style="color: #0000ff">new</span> Person("李四","mam",23<span style="color: #000000">);   Person p2 </span>= <span style="color: #0000ff">new</span> Person(P1);</pre> </div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当调用上面的语句时。P2对象将会对P1进行复制。执行情况如下如下图：</p>  <p><img alt="" src="http://hi.csdn.net/attachment/201202/27/0_13303512963l30.gif" /></p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于Asian对象有：</p>  <p>     </p><div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px">       <pre>Asian a1 = <span style="color: #0000ff">new</span> Asian("yellow",<span style="color: #0000ff">new</span> Person("李四","mam",23<span style="color: #000000">)); Asian a2 </span>= <span style="color: #0000ff">new</span> Asian(a1);</pre>     </div>      <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; New Asian(a1)执行Asian类的拷贝构造方法，由于对象赋值是引用赋值。使得a1和a2引用同一个对象  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如下图：</p>  <p><img alt="" src="http://hi.csdn.net/attachment/201202/27/0_133035141375ZL.gif" /></p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当a1执行某条可以改变该值的语句时，那么a1将会通过这个语句也可以改变a2对象的成员变量</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如果执行以下语句：a2.name = new Person(a1.name) </p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这时将会创建一个新的Person对象</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 如下图：</p>  <p><img alt="" src="http://hi.csdn.net/attachment/201202/27/0_1330351465s7F7.gif" /></p></div><br /><img src ="http://www.blogjava.net/longturi/aggbug/413187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-05-04 06:15 <a href="http://www.blogjava.net/longturi/archive/2014/05/04/413187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转帖：再解Java中的String</title><link>http://www.blogjava.net/longturi/archive/2014/05/04/413186.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Sat, 03 May 2014 22:10:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/05/04/413186.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/413186.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/05/04/413186.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/413186.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/413186.html</trackback:ping><description><![CDATA[<div><p>转帖：<div>http://www.cnblogs.com/chenssy/p/3695271.html</div>版权归作者所有。<br /></p><p><br /></p><p>&nbsp;&nbsp;&nbsp;&nbsp; 今天朋友问我String的内容是真的不可变吗？我肯定告诉他是的？因为在我的主观意识里String就是一个不可变的对象。于是他给我发了这段程序：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> StringTest {     </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {         String a </span>= "chenssy"<span style="color: #000000">;         System.out.println(</span>"a = " +<span style="color: #000000"> a);         Field a_ </span>= String.<span style="color: #0000ff">class</span>.getDeclaredField("value"<span style="color: #000000">);         a<em>.setAccessible(</em></span><em><span style="color: #0000ff">true</span><span style="color: #000000">);         </span><span style="color: #0000ff">char</span>[] value=(<span style="color: #0000ff">char</span><span style="color: #000000">[])a</span></em>.get(a);         value[4]='_';   <span style="color: #008000">//</span><span style="color: #008000">修改a所指向的值</span>         System.out.println("a = " +<span style="color: #000000"> a);     } }</span></pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 看到这个简单的程序，我笑了，你这不是从底层来修改String的值么？从这里来理解String的值肯定是可以改变的啦（我们应该始终相信String的不可变性）！接着他再给我一段程序：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre><span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span><span style="color: #000000"> StringTest {     </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {         String a </span>= "chenssy"<span style="color: #000000">;         String b </span>= "chenssy"<span style="color: #000000">;         String c </span>= <span style="color: #0000ff">new</span> String("chenssy"<span style="color: #000000">);         System.out.println(</span>"--------------修改前值-------------------"<span style="color: #000000">);         System.out.println(</span>"a = " +<span style="color: #000000"> a);         System.out.println(</span>"b = " +<span style="color: #000000"> b);         System.out.println(</span>"c = " +<span style="color: #000000"> c);         </span><span style="color: #008000">//</span><span style="color: #008000">修改String的值</span>         Field a_ = String.<span style="color: #0000ff">class</span>.getDeclaredField("value"<span style="color: #000000">);         a_.setAccessible(</span><span style="color: #0000ff">true</span><span style="color: #000000">);         </span><span style="color: #0000ff">char</span>[] value=(<span style="color: #0000ff">char</span><span style="color: #000000">[])a_.get(a);         value[</span>4]='_';   <span style="color: #008000">//</span><span style="color: #008000">修改a所指向的值</span> <span style="color: #000000">                 System.out.println(</span>"--------------修改后值-------------------"<span style="color: #000000">);         System.out.println(</span>"a = " +<span style="color: #000000"> a);         System.out.println(</span>"b = " +<span style="color: #000000"> b);         System.out.println(</span>"chenssy"<span style="color: #000000">);         System.out.println(</span>"c = " +<span style="color: #000000"> c);     } }</span></pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 乍看这程序是异常的简单，无非就是赋值、改值、输出嘛！可能你现在就会毫不犹豫的说太简单了结果就是&#8230;&#8230;。但是！！你的毫不犹豫会害死你，而且你的结果很可能错误。那么运行结果是什么呢？</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px"><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div>   <pre>--------------修改前值-------------------<span style="color: #000000"> a </span>=<span style="color: #000000"> chenssy b </span>=<span style="color: #000000"> chenssy c </span>=<span style="color: #000000"> chenssy </span>--------------修改后值-------------------<span style="color: #000000"> a </span>=<span style="color: #000000"> chen_sy b </span>=<span style="color: #000000"> chen_sy chen_sy c </span>= chen_ssy</pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 修改前值很容易理解，但是修改后值呢？是不是有点儿不理解呢？你可能会问：为什么System.out.println("chenssy");的结果会是chen_ssy，System.out.println("c = " + c);也是chen_ssy呢？</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要明白这个其实也比较简单，掌握一个知识点：字符串常量池。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  我们知道字符串的分配和其他对象分配一样，是需要消耗高昂的时间和空间的，而且字符串我们使用的非常多。JVM为了提高性能和减少内存的开销，在实例化字 符串的时候进行了一些优化：使用字符串常量池。每当我们创建字符串常量时，JVM会首先检查字符串常量池，如果该字符串已经存在常量池中，那么就直接返回 常量池中的实例引用。如果字符串不存在常量池中，就会实例化该字符串并且将其放到常量池中。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串（这点对理解上面至关重要）。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我们再来理解上面的程序。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String a = "chenssy";</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String b = "chenssy";</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a、b和字面上的chenssy都是指向JVM字符串常量池中的&#8221;chenssy&#8221;对象，他们指向同一个对象。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String c = new String("chenssy");</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  new关键字一定会产生一个对象chenssy（注意这个chenssy和上面的chenssy不同），同时这个对象是存储在堆中。所以上面应该产生了两 个对象：保存在栈中的c和保存堆中chenssy。但是在Java中根本就不存在两个完全一模一样的字符串对象。故堆中的chenssy应该是引用字符串 常量池中chenssy。所以c、chenssy、池chenssy的关系应该是：c---&gt;chenssy---&gt;池chenssy。整个 关系如下：</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://images.cnitblog.com/blog/381060/201404/272149150297421.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px" title="201404271001" alt="201404271001" src="http://images.cnitblog.com/blog/381060/201404/272149156708549.png" height="335" border="0" width="560" /></a></p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过上面的图我们可以非常清晰的认识他们之间的关系。所以我们修改内存中的值，他变化的是所有。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>总结：</strong>虽然a、 b、c、chenssy是不同的对象，但是从String的内部结构我们是可以理解上面的。String c = new  String("chenssy");虽然c的内容是创建在堆中，但是他的内部value还是指向JVM常量池的chenssy的value，它构造 chenssy时所用的参数依然是chenssy字符串常量。</p>  <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为了让各位充分理解常量池，特意准备了如下一个简单的题目：</p>  <div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px">   <pre>String a = "chen"<span style="color: #000000">; String b </span>= a + <span style="color: #0000ff">new</span> String("ssy");</pre> </div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建了几个String对象？？ </div><img src ="http://www.blogjava.net/longturi/aggbug/413186.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-05-04 06:10 <a href="http://www.blogjava.net/longturi/archive/2014/05/04/413186.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Class的getResource方法</title><link>http://www.blogjava.net/longturi/archive/2014/05/02/413147.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 02 May 2014 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/05/02/413147.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/413147.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/05/02/413147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/413147.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/413147.html</trackback:ping><description><![CDATA[<div>Class的getResource方法，实际上是靠调入这个类的ClassLoader的getResource方法来实现的，如果调入这个类的ClassLoader是原生的BootStrap ClassLoader，这个ClassLoader是用C++写成的，在Java中没有相对应的物件。这时候的实现靠的是ClassLoader的静态方法getSystemResource。<br /><br />只有当使用Class类的getResource方法的时候，才会有下面介绍的那种算法。<br /><br />这种算法就是说，如果你指定的路径以/开头，那么就是从ClassPath的起点开始寻找这个路径。如果直接以某个名字开头，那么就是从当前包名的目录为起点开始寻找。<br />所以大家如果用过hibernate就知道，有些表示类到数据库表的映射关系的xml文件就和这个类的class文件放在一起，这样它就直接使用这个类.class.getResource方法来得到这个xml文件。<br /><br />而在使用ClassLoader的getResource方法的时候，永远是以Classpath为直接起点开始寻找资源的。不用担心从什么包开始寻找的问题。<br /><br />用Class.getResource不加/就是从当前包开始找，用ClassLoader.getResource不加/就是直接从Classpath的起点开始寻找。<br /><br />当然，如果觉得麻烦，你定位资源的时候全部都使用/开头的方式就好了</div><img src ="http://www.blogjava.net/longturi/aggbug/413147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-05-02 15:48 <a href="http://www.blogjava.net/longturi/archive/2014/05/02/413147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Class.getResource()</title><link>http://www.blogjava.net/longturi/archive/2014/05/02/413146.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 02 May 2014 07:34:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/05/02/413146.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/413146.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/05/02/413146.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/413146.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/413146.html</trackback:ping><description><![CDATA[<div><div id="blog_content"><dd><br /></dd><dd><br /></dd><dd><br /></dd><dd><br /></dd><dd><br /></dd><dd><br /></dd><dd>查找带有给定名称的资源,查找给定类相关的资源的规则是通过定义类的 <a title="java.lang 中的类" href="http://wangxuliangboy.iteye.com/java/lang/ClassLoader.html"><span style="color: #ffffff; background-color: #0a246a;">class</span> loader</a> 实现的。此方法委托给此对象的类加载器。如果此对象通过引导类加载器加载，则此方法将委托给 <a href="http://wangxuliangboy.iteye.com/java/lang/ClassLoader.html#getSystemResource%28java.lang.String%29"><code>ClassLoader.getSystemResource(java.lang.String)</code></a>。 <p>在委托前，使用下面的算法从给定的资源名构造一个绝对资源名： </p> <ul><li>如果 <tt>name</tt> 以 <tt>'/'</tt>&nbsp; 开始，则绝对资源名是 <tt>'/'</tt> 后面的 <tt>name</tt> 的一部分。 </li><li>否则，绝对名具有以下形式： <blockquote> <pre>   <tt>modified_package_name</tt>/<tt>name</tt> </pre> </blockquote> <p>其中 <tt>modified_package_name</tt> 是此对象的包名，该名用 <tt>'/'</tt> 取代了 <tt>'.'</tt> (<tt>'\u002e'</tt>)。</p> </li></ul> </dd> <p>Class.getResource(""); 获取classpath</p> <p>&nbsp;</p> <p>Class.getResource("JMF.class"); 代表获取相于类路径当前包下的SendService.class的类路径.</p> <p>/D:/bak/upload/upload/WebRoot/WEB-INF/classes/jmf/JMF.class--------&gt;打印出的结果</p> <p>Class.getResource("/jmf/WebCamSwing.class"); /jmf/WebCamSwing.class-&gt;代表相于类路径的绝对路径</p> <p>file:/D:/bak/upload/upload/WebRoot/WEB-INF/classes/jmf/JMF.class&nbsp;&nbsp;--------&gt;打印出的结果</p> <p>&nbsp;</p> <p>我们怎么获得Object的类路径:</p> <p>Class.getResource("/java/lang/Object.class")&nbsp;因为Object是通过引导类加载器 (BootStrapClassLoader)加载的,所以此方法通过系统类加载器来查找资料,&nbsp;所以我们要指定类的绝对路径/java/lang /Object.class</p> <p>public java.net.URL getResource(String name) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = resolveName(name);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassLoader cl = getClassLoader0();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (cl==null) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // A system class.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ClassLoader.getSystemResource(name);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return cl.getResource(name);<br />&nbsp;&nbsp;&nbsp; }</p> <p>&nbsp;</p> <p>我们来看看如何通过系统类加载器来查找Object:</p> <p>Class.getClassLoader().getSystemResource("java/lang/Object.class")</p> <p>&nbsp;</p> <p>打印出来的结果多是:</p> <p>jar:file:/E:/Program/Java/jdk1.5.0_15/jre/lib/rt.jar!/java/lang/Object.class</p> <p>&nbsp;</p> <p>为什么getResource("")前面要加"/",而getSystemResource("")前面不用加呢?</p> <p>private String resolveName(String name) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (name == null) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!name.startsWith("/")) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class c = this;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (c.isArray()) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; c = c.getComponentType();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String baseName = c.getName();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int index = baseName.lastIndexOf('.');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (index != -1) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = baseName.substring(0, index).replace('.', '/')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +"/"+name;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = name.substring(1);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return name;<br />&nbsp;&nbsp;&nbsp; }</p> <p>&nbsp;</p> <p>其实最后还是要把"/"去掉的...</p></div></div><img src ="http://www.blogjava.net/longturi/aggbug/413146.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-05-02 15:34 <a href="http://www.blogjava.net/longturi/archive/2014/05/02/413146.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Apache Common HttpClient使用之七种武器</title><link>http://www.blogjava.net/longturi/archive/2014/02/26/410341.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Wed, 26 Feb 2014 10:10:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/02/26/410341.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/410341.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/02/26/410341.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/410341.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/410341.html</trackback:ping><description><![CDATA[<div>http://laohuang.iteye.com/blog/55613</div><br /><div><strong>1.拳头之Get/Post</strong><br /> 拳头是最基本的一重武器，也是最重要的，好比练武之人必须先扎稳马步。<br /> <br /> <div>java 代码</div> <div> <div>&nbsp;</div> <ol><li><span>HttpClient&nbsp;httpclient=new&nbsp;HttpClient();//创建一个客户端，类似打开一个浏览器&nbsp;&nbsp;</span></li><li>GetMethod&nbsp;getMethod=<span>new&nbsp;GetMethod("http://www.blablabla.com");//创建一个get方法，类似在浏览器地址栏中输入一个地址&nbsp;&nbsp;</span></li><li><span>int&nbsp;statusCode=httpclient.executeMethod(getMethod);//回车&#8212;&#8212;出拳！&nbsp;&nbsp;</span></li><li>System.out.println(<span>"response="&nbsp;+&nbsp;getMethod.getResponseBodyAsString());//察看拳头命中情况，可以获得的东西还有很多，比如head,&nbsp;cookies等等&nbsp;&nbsp;</span></li><li>getMethod.releaseConnection();<span>//释放，记得收拳哦&nbsp;&nbsp;</span></li></ol> </div> <br /> <br /> <strong>2.孔雀翎之支持https</strong><br /> <br /> 如何支持https?<br /> <div>java 代码</div> <div> <div>&nbsp;</div> <ol><li><span>static{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;Protocol&nbsp;easyhttps&nbsp;=&nbsp;<span>new&nbsp;Protocol("https",&nbsp;new&nbsp;EasySSLProtocolSocketFactory(),&nbsp;443);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;Protocol.registerProtocol(<span>"https",&nbsp;easyhttps);&nbsp;&nbsp;</span></li><li>}&nbsp;&nbsp;</li></ol> </div> <br /> 在执行具体的http method之前，暗中将https协议注册一把，如孔雀翎暗藏玄机，毙敌于无形。记住，官方的binary发行版本没有ssl的contribute包，方法一是下载源代码版本来打造你的孔雀翎。<br /> <br /> <strong>3.多情环之cookies</strong><br /> 常道人老多情，其实是记忆太多，所以情之所至，正如cookies甜心，无论你走到那，总把你牵挂：<br /> <div>java 代码</div> <div> <div>&nbsp;</div> <ol><li><span>HttpClient&nbsp;httpclient=new&nbsp;HttpClient();&nbsp;&nbsp;</span></li><li>httpclient.getParams().setCookiePolicy(CookiePolicy.RFC_2109);<span>//RFC_2109是支持较普遍的一个，还有其他cookie协议&nbsp;&nbsp;</span></li><li>HttpState&nbsp;initialState&nbsp;=&nbsp;<span>new&nbsp;HttpState();&nbsp;&nbsp;</span></li><li>Cookie&nbsp;cookie=<span>new&nbsp;Cookie();&nbsp;&nbsp;</span></li><li>cookie.setDomain(<span>"www.balblabla.com");&nbsp;&nbsp;</span></li><li>cookie.setPath(<span>"/");&nbsp;&nbsp;</span></li><li>cookie.setName(<span>"多情环");&nbsp;&nbsp;</span></li><li>cookie.setValue(<span>"多情即无情");&nbsp;&nbsp;</span></li><li>initialState.addCookie(cookie);&nbsp;&nbsp;</li><li>httpclient.setState(initialState);&nbsp;&nbsp;</li><li>...&nbsp;&nbsp;</li></ol> </div> <br /> <strong><br /> 4.离别钩之解构cookies</strong><br /> 多情环的反面即离别钩，钩出，敌之身体某个部件即要与身体别离，端的是无情：<br /> <div>java 代码</div> <div> <div>&nbsp;</div> <ol><li><span>...//执行了某些get/post方法后&nbsp;&nbsp;</span></li><li>Cookie[]&nbsp;cookies&nbsp;=&nbsp;httpclient.getState().getCookies();&nbsp;&nbsp;</li><li>System.out.println(<span>"Present&nbsp;cookies:&nbsp;");&nbsp;&nbsp;</span></li><li><span>for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;cookies.length;&nbsp;i++)&nbsp;{//循环结构零部件&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span>"&nbsp;-&nbsp;"&nbsp;+&nbsp;cookies[i].toExternalForm());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span>"&nbsp;-&nbsp;domain="&nbsp;+&nbsp;cookies[i].getDomain());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<span>"&nbsp;-&nbsp;path="&nbsp;+&nbsp;cookies[i].getPath());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>}&nbsp;&nbsp;</li></ol> </div> <br /> <br /> <strong>5.霸王抢之post参数</strong><br /> 枪，长兵器之王，诸多名将均使一杆或金或银命名的名枪，比如岳飞。post方法在提交参数对时,犹如灵蛇出洞：<br /> <div>java 代码</div> <div> <div>&nbsp;</div> <ol><li><span>PostMethod&nbsp;postMethod&nbsp;=&nbsp;new&nbsp;PostMethod("http://www.saybot.com/postme");&nbsp;&nbsp;</span></li><li>NameValuePair[]&nbsp;postData&nbsp;=&nbsp;<span>new&nbsp;NameValuePair[2];&nbsp;&nbsp;</span></li><li>postData[<span>0]&nbsp;=&nbsp;new&nbsp;NameValuePair("武器",&nbsp;"枪");&nbsp;&nbsp;</span></li><li>postData[<span>1]&nbsp;=&nbsp;new&nbsp;NameValuePair("什么枪",&nbsp;"神枪");&nbsp;&nbsp;</span></li><li>postMethod.addParameters(postData);&nbsp;&nbsp;</li><li>...<span>//出枪吧&nbsp;&nbsp;</span></li></ol> </div> <br /> <strong><br /> 6.七星碧玉刀之支持代理(proxy)</strong><br /> 代理，非常重要，尤其在局域网横行的年头，没有代理，你在公司上不了QQ，没有代理，google不了网页快照，代理之威，可比七星碧玉刀，无刀，在局域网和开发当中，一切白搭：<br /> <div>java 代码</div> <div> <div>&nbsp;</div> <ol><li><span>HttpClient&nbsp;httpclient=new&nbsp;HttpClient();&nbsp;&nbsp;</span></li><li>httpClient.getHostConfiguration().setProxy(<span>"192.168.0.1",&nbsp;9527);&nbsp;&nbsp;</span></li><li>httpClient.getParams().setAuthenticationPreemptive(<span>true);//重要！！！告诉httpclient，使用抢先认证，否则你会收到&#8220;你没有资格&#8221;的恶果&nbsp;&nbsp;</span></li><li><span>/*&nbsp;</span></li><li><span>&nbsp;&nbsp;这一步也至关重要，MyProxyCredentialsProvider实现了org.apache.commons.httpclient.auth.CredentialsProvider接口，&nbsp;</span></li><li><span>&nbsp;&nbsp;返回代理的credential(username/password)*/&nbsp;&nbsp;</span></li><li>httpClient.getParams().setParameter(CredentialsProvider.PROVIDER,&nbsp;<span>new&nbsp;MyProxyCredentialsProvider());&nbsp;&nbsp;</span></li><li>httpClient.getState().setProxyCredentials(&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>new&nbsp;AuthScope("192.168.0.1",&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AuthScope.ANY_PORT,&nbsp;<span>//任意端口哦，可要小心&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AuthScope.ANY_REALM),<span>//任意域哦，可要小心&nbsp;&nbsp;</span></li><li><span>new&nbsp;UsernamePasswordCredentials("username",//proxy的用户名&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>"password"));//proxy的密码&nbsp;&nbsp;</span></li></ol> </div> <br /> ...<br /> <br /> <strong>7.长生剑之天下第一</strong><br /> 看httpclient的官方文档：<a href="http://jakarta.apache.org/commons/httpclient/userguide.html">jakarta.apache.org/commons/httpclient/userguide.html</a><br /> 看Hilton网友写的小葵花宝典笔记：<a href="http://www.cnjm.net/tech/article1155.html">www.cnjm.net/tech/article1155.html</a><br /> 通读后，你会有种拔剑四顾心茫然的高手感觉。<br /> <br /> 七种武器，打完收工！   </div><img src ="http://www.blogjava.net/longturi/aggbug/410341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-02-26 18:10 <a href="http://www.blogjava.net/longturi/archive/2014/02/26/410341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>httpclient的一些学习心得</title><link>http://www.blogjava.net/longturi/archive/2014/02/26/410340.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Wed, 26 Feb 2014 10:08:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/02/26/410340.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/410340.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/02/26/410340.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/410340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/410340.html</trackback:ping><description><![CDATA[转载自：<div>http://wallimn.iteye.com/blog/540566</div><br /><div>最近忙于一个项目，了解下httpclient，在这里总结出来，和大家一起学习分享，希望各位朋友提出宝贵的意见。 <br /> <br />首先介绍一下项目的背景： <br />&nbsp; 目标：把国内一家保险公司的&#8220;ＷＥＢ一账通&#8221;改成&#8220;ＷＡＰ一账通&#8221;。 <br />&nbsp; 资源：客户不提供任何的webservice接口。 <br />&nbsp;  <br />本项目中用到的第三方组件是apache的httpclient，一个非常强大的网页抓取工具（抓这个字用得可能不太好），　这里和大家 <br />一起讨论下httpclient的一些常用用法和要注意的地方。 <br /> <br />本文引用的资源列表： <br /> <br />&nbsp; httpclient入门：&nbsp; http://www.ibm.com/developerworks/cn/opensource/os-httpclient/ <br />&nbsp; httpclient证书导入：http://www.blogjava.net/happytian/archive/2006/12/22/89447.html <br />&nbsp; httpclient高级认识：http://laohuang.iteye.com/blog/55613 <br />&nbsp; httpclient官方文档：http://hc.apache.org/httpcomponents-client/index.html <br />&nbsp; httpclient资源关闭：http://www.iteye.com/topic/234759 <br />&nbsp;  <br />&nbsp;  <br />上面的文章写得很好，看完之后也就知道怎么用httpclient这个很好的工具了，但是在这里还是补充一些比较重要的东西，也是项目中经 <br />常碰到的问题。 <br /> <br />首先要注意的有以下几点： <br />1、httpclient连接后资源释放问题很重要，就跟我们用database connection要释放资源一样。 <br />2、https网站采用ssl加密传输，证书导入要注意。 <br />3、做这样的项目最好先了解下http协义，比如302,301,200,404返回代码的含义（这是最基本的）,cookie,session的机制。 <br />4、httpclient的redirect状态默认是自动的，这在很大程度上给开发者很大的方便（如一些授权获得cookie），但是有时要手动管理下，比如 <br />　　有时会遇到CircularRedirectException异常，出现这样的情况是因为返回的头文件中location值指向之前重复(端口号可以不同)地址，导致可能会出现死 <br />&nbsp; 循环递归重定向，这时可以手动关闭:method.setFollowRedirects(false) <br />5、有的网站会先判别用户的请求是否是来自浏览器，如不是，则返回不正确的文本，所以用httpclient抓取信息时在头部加入如下信息： <br />&nbsp; header.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0;  Windows NT 5.1; SV1; QQDownload 1.7; .NET CLR 1.1.4322; CIBA; .NET CLR  2.0.50727)"); <br />6、当post请求提交数据时要改变默认编码，不然的话提交上去的数据会出现乱码。重写postMethod的setContentCharSet()方法就可以了： <br /> <br />  <br /> <br />  <br /> <br />&nbsp;  <br />下面写一个通用类来处理request请求返回的文本: <br /><div id=""><div><div>Java代码 &nbsp;<a title="收藏这段代码"><img src="http://wallimn.iteye.com/images/icon_star.png" alt="收藏代码" /></a></div></div><ol start="1"><li><span>/*&nbsp;</span></li><li><span>&nbsp;*&nbsp;HttpRequestProxy.java&nbsp;</span></li><li><span>&nbsp;*&nbsp;</span></li><li><span>&nbsp;*&nbsp;Created&nbsp;on&nbsp;November&nbsp;3,&nbsp;2008,&nbsp;9:53&nbsp;AM&nbsp;</span></li><li><span>&nbsp;*/&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li><span>package&nbsp;cn.com.mozat.net;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li><span>import&nbsp;java.io.BufferedReader;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.io.IOException;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.io.InputStream;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.io.InputStreamReader;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.util.HashMap;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.util.Iterator;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.util.Map;&nbsp;&nbsp;</span></li><li><span>import&nbsp;java.util.Set;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li><span>import&nbsp;org.apache.commons.httpclient.Header;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.HttpClient;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.HttpException;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.HttpMethod;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.NameValuePair;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.SimpleHttpConnectionManager;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.methods.GetMethod;&nbsp;&nbsp;</span></li><li><span>import&nbsp;org.apache.commons.httpclient.methods.PostMethod;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li><span>import&nbsp;cn.com.mozat.exception.CustomException;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li><span>/**&nbsp;</span></li><li><span>&nbsp;*&nbsp;&nbsp;</span></li><li><span>&nbsp;*&nbsp;@author&nbsp;bird&nbsp;&nbsp;email:lihongfu-84@163.com&nbsp;</span></li><li><span>&nbsp;*&nbsp;</span></li><li><span>&nbsp;*&nbsp;2008-11-4&nbsp;&nbsp;09:49:48&nbsp;</span></li><li><span>&nbsp;*/&nbsp;&nbsp;</span></li><li><span>public&nbsp;class&nbsp;HttpRequestProxy{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>//超时间隔&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>private&nbsp;static&nbsp;int&nbsp;connectTimeOut&nbsp;=&nbsp;60000;&nbsp;&nbsp;</span></li><li>&nbsp;<span>//让connectionmanager管理httpclientconnection时是否关闭连接&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>private&nbsp;static&nbsp;boolean&nbsp;alwaysClose&nbsp;=&nbsp;false;&nbsp;&nbsp;</span></li><li>&nbsp;<span>//返回数据编码格式&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>private&nbsp;String&nbsp;encoding&nbsp;=&nbsp;"UTF-8";&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>private&nbsp;final&nbsp;HttpClient&nbsp;client&nbsp;=&nbsp;new&nbsp;HttpClient(new&nbsp;SimpleHttpConnectionManager(alwaysClose));&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;HttpClient&nbsp;getHttpClient(){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;client;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>/**&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;用法：&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;HttpRequestProxy&nbsp;hrp&nbsp;=&nbsp;new&nbsp;HttpRequestProxy();&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;hrp.doRequest("http://www.163.com",null,null,"gbk");&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;url&nbsp;&nbsp;请求的资源ＵＲＬ&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;postData&nbsp;&nbsp;POST请求时form表单封装的数据&nbsp;没有时传null&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;header&nbsp;&nbsp;&nbsp;request请求时附带的头信息(header)&nbsp;没有时传null&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@param&nbsp;encoding&nbsp;response返回的信息编码格式&nbsp;没有时传null&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;&nbsp;response返回的文本数据&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@throws&nbsp;CustomException&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>public&nbsp;String&nbsp;doRequest(String&nbsp;url,Map&nbsp;postData,Map&nbsp;header,String&nbsp;encoding)&nbsp;throws&nbsp;CustomException{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;responseString&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>//头部请求信息&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Header[]&nbsp;headers&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if(header&nbsp;!=&nbsp;null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&nbsp;entrySet&nbsp;=&nbsp;header.entrySet();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>int&nbsp;dataLength&nbsp;=&nbsp;entrySet.size();&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;headers=&nbsp;<span>new&nbsp;Header[dataLength];&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>int&nbsp;i&nbsp;=&nbsp;0;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>for(Iterator&nbsp;itor&nbsp;=&nbsp;entrySet.iterator();itor.hasNext();){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map.Entry&nbsp;entry&nbsp;=&nbsp;(Map.Entry)itor.next();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;headers[i++]&nbsp;=&nbsp;<span>new&nbsp;Header(entry.getKey().toString(),entry.getValue().toString());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>//post方式&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if(postData!=null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PostMethod&nbsp;postRequest&nbsp;=&nbsp;<span>new&nbsp;PostMethod(url.trim());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if(headers&nbsp;!=&nbsp;null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>for(int&nbsp;i&nbsp;=&nbsp;0;i&nbsp;&lt;&nbsp;headers.length;i++){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postRequest.setRequestHeader(headers[i]);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Set&nbsp;entrySet&nbsp;=&nbsp;postData.entrySet();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>int&nbsp;dataLength&nbsp;=&nbsp;entrySet.size();&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NameValuePair[]&nbsp;params&nbsp;=&nbsp;<span>new&nbsp;NameValuePair[dataLength];&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>int&nbsp;i&nbsp;=&nbsp;0;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>for(Iterator&nbsp;itor&nbsp;=&nbsp;entrySet.iterator();itor.hasNext();){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map.Entry&nbsp;entry&nbsp;=&nbsp;(Map.Entry)itor.next();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;params[i++]&nbsp;=&nbsp;<span>new&nbsp;NameValuePair(entry.getKey().toString(),entry.getValue().toString());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;postRequest.setRequestBody(params);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;responseString&nbsp;=&nbsp;<span>this.executeMethod(postRequest,encoding);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(CustomException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>throw&nbsp;e;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;}&nbsp;<span>finally{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;postRequest.releaseConnection();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>//get方式&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if(postData&nbsp;==&nbsp;null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMethod&nbsp;getRequest&nbsp;=&nbsp;<span>new&nbsp;GetMethod(url.trim());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>if(headers&nbsp;!=&nbsp;null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>for(int&nbsp;i&nbsp;=&nbsp;0;i&nbsp;&lt;&nbsp;headers.length;i++){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getRequest.setRequestHeader(headers[i]);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;responseString&nbsp;=&nbsp;<span>this.executeMethod(getRequest,encoding);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(CustomException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>throw&nbsp;e;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;}<span>finally{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;getRequest.releaseConnection();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>return&nbsp;responseString;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;</li><li>&nbsp;<span>private&nbsp;String&nbsp;executeMethod(HttpMethod&nbsp;request,&nbsp;String&nbsp;encoding)&nbsp;throws&nbsp;CustomException{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;String&nbsp;responseContent&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;InputStream&nbsp;responseStream&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;BufferedReader&nbsp;rd&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>this.getHttpClient().executeMethod(request);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>if(encoding&nbsp;!=&nbsp;null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;responseStream&nbsp;=&nbsp;request.getResponseBodyAsStream();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rd&nbsp;=&nbsp;<span>new&nbsp;BufferedReader(new&nbsp;InputStreamReader(responseStream,&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encoding));&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;tempLine&nbsp;=&nbsp;rd.readLine();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer&nbsp;tempStr&nbsp;=&nbsp;<span>new&nbsp;StringBuffer();&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;crlf=System.getProperty(<span>"line.separator");&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>while&nbsp;(tempLine&nbsp;!=&nbsp;null)&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempStr.append(tempLine);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempStr.append(crlf);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempLine&nbsp;=&nbsp;rd.readLine();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseContent&nbsp;=&nbsp;tempStr.toString();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;}<span>else&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;responseContent&nbsp;=&nbsp;request.getResponseBodyAsString();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;Header&nbsp;locationHeader&nbsp;=&nbsp;request.getResponseHeader(<span>"location");&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>//返回代码为302,301时，表示页面己经重定向，则重新请求location的url，这在&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>//一些登录授权取cookie时很重要&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>if&nbsp;(locationHeader&nbsp;!=&nbsp;null)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;redirectUrl&nbsp;=&nbsp;locationHeader.getValue();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>this.doRequest(redirectUrl,&nbsp;null,&nbsp;null,null);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(HttpException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;}&nbsp;<span>finally{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>if(rd&nbsp;!=&nbsp;null)&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rd.close();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>if(responseStream&nbsp;!=&nbsp;null)&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseStream.close();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;<span>return&nbsp;responseContent;&nbsp;&nbsp;</span></li><li>&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;<span>/**&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;特殊请求数据,这样的请求往往会出现redirect本身而出现递归死循环重定向&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;所以单独写成一个请求方法&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;比如现在请求的url为：http://localhost:8080/demo/index.jsp&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;返回代码为302&nbsp;头部信息中location值为:http://localhost:8083/demo/index.jsp&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;这时httpclient认为进入递归死循环重定向，抛出CircularRedirectException异常&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;@param&nbsp;url&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;@return&nbsp;</span></li><li><span>&nbsp;&nbsp;*&nbsp;@throws&nbsp;CustomException&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;*/&nbsp;&nbsp;</span></li><li>&nbsp;<span>public&nbsp;String&nbsp;doSpecialRequest(String&nbsp;url,int&nbsp;count,String&nbsp;encoding)&nbsp;throws&nbsp;CustomException{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;String&nbsp;str&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;InputStream&nbsp;responseStream&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;BufferedReader&nbsp;rd&nbsp;=&nbsp;<span>null;&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;GetMethod&nbsp;getRequest&nbsp;=&nbsp;<span>new&nbsp;GetMethod(url);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;<span>//关闭httpclient自动重定向动能&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;getRequest.setFollowRedirects(<span>false);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;<span>this.client.executeMethod(getRequest);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;Header&nbsp;header&nbsp;=&nbsp;getRequest.getResponseHeader(<span>"location");&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>if(header!=&nbsp;null){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>//请求重定向后的ＵＲＬ，count同时加1&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>this.doSpecialRequest(header.getValue(),count+1,&nbsp;encoding);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;<span>//这里用count作为标志位，当count为0时才返回请求的ＵＲＬ文本,&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>//这样就可以忽略所有的递归重定向时返回文本流操作，提高性能&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>if(count&nbsp;==&nbsp;0){&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;getRequest&nbsp;=&nbsp;<span>new&nbsp;GetMethod(url);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;getRequest.setFollowRedirects(<span>false);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>this.client.executeMethod(getRequest);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;responseStream&nbsp;=&nbsp;getRequest.getResponseBodyAsStream();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;rd&nbsp;=&nbsp;<span>new&nbsp;BufferedReader(new&nbsp;InputStreamReader(responseStream,&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encoding));&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;tempLine&nbsp;=&nbsp;rd.readLine();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StringBuffer&nbsp;tempStr&nbsp;=&nbsp;<span>new&nbsp;StringBuffer();&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;crlf=System.getProperty(<span>"line.separator");&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>while&nbsp;(tempLine&nbsp;!=&nbsp;null)&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempStr.append(tempLine);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempStr.append(crlf);&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tempLine&nbsp;=&nbsp;rd.readLine();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str&nbsp;=&nbsp;tempStr.toString();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(HttpException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;}&nbsp;<span>finally{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;getRequest.releaseConnection();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;<span>if(rd&nbsp;!=null)&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rd.close();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>if(responseStream&nbsp;!=null)&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>try&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;responseStream.close();&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;<span>catch&nbsp;(IOException&nbsp;e)&nbsp;{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>throw&nbsp;new&nbsp;CustomException(e.getMessage());&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;<span>return&nbsp;str;&nbsp;&nbsp;</span></li><li>&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;</li><li>&nbsp;<span>public&nbsp;static&nbsp;void&nbsp;main(String[]&nbsp;args)&nbsp;throws&nbsp;Exception{&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;HttpRequestProxy&nbsp;hrp&nbsp;=&nbsp;<span>new&nbsp;HttpRequestProxy();&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;Map&nbsp;header&nbsp;=&nbsp;<span>new&nbsp;HashMap();&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;header.put(<span>"User-Agent",&nbsp;"Mozilla/4.0&nbsp;(compatible;&nbsp;MSIE&nbsp;6.0;&nbsp;Windows&nbsp;NT&nbsp;5.1;&nbsp;SV1;&nbsp;QQDownload&nbsp;1.7;&nbsp;.NET&nbsp;CLR&nbsp;1.1.4322;&nbsp;CIBA;&nbsp;.NET&nbsp;CLR&nbsp;2.0.50727)");&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;String&nbsp;str&nbsp;=&nbsp;hrp.doRequest(&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;<span>"http://www.cma-cgm.com/en/eBusiness/Tracking/Default.aspx?BolNumber=GZ2108827",&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span>null,&nbsp;header,null);&nbsp;&nbsp;</span></li><li>&nbsp;&nbsp;System.out.println(str.contains(<span>"row_CRXU1587647"));&nbsp;&nbsp;</span></li><li><span>//&nbsp;&nbsp;System.out.println(str);&nbsp;&nbsp;</span></li><li>&nbsp;}&nbsp;&nbsp;</li><li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li><li>}&nbsp; <br /></li></ol></div></div><img src ="http://www.blogjava.net/longturi/aggbug/410340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-02-26 18:08 <a href="http://www.blogjava.net/longturi/archive/2014/02/26/410340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java程序运行时间的计算  </title><link>http://www.blogjava.net/longturi/archive/2014/02/14/409842.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 14 Feb 2014 01:51:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/02/14/409842.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/409842.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/02/14/409842.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/409842.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/409842.html</trackback:ping><description><![CDATA[<div>http://blog.163.com/kevinlee_2010/blog/static/16982082020112710557998/</div><br /><div>第一种是以毫秒为单位计算的。   <p>　　Java代码</p>  <p>　　//伪代码</p>  <p>　　long startTime=System.currentTimeMillis();&nbsp;&nbsp; //获取开始时间</p>  <p>　　doSomeThing();&nbsp; //测试的代码段</p>  <p>　　long endTime=System.currentTimeMillis(); //获取结束时间</p>  <p>　　System.out.println("程序运行时间： "+(end-start)+"ms");</p>  <p>　　//伪代码</p>  <p>　　long startTime=System.currentTimeMillis();&nbsp;&nbsp; //获取开始时间</p>  <p>　　doSomeThing();&nbsp; //测试的代码段</p>  <p>　　long endTime=System.currentTimeMillis(); //获取结束时间</p>  <p>　　System.out.println("程序运行时间： "+(end-start)+"ms");</p>  <p>　　第二种是以纳秒为单位计算的。</p>  <p>　　Java代码</p>  <p>　　//伪代码</p>  <p>　　long startTime=System.nanoTime();&nbsp;&nbsp; //获取开始时间</p>  <p>　　doSomeThing();&nbsp; //测试的代码段</p>  <p>　　long endTime=System.nanoTime(); //获取结束时间</p>  <p>　　System.out.println("程序运行时间： "+(end-start)+"ns");</p>  <p>　　//伪代码</p>  <p>　　long startTime=System.nanoTime();&nbsp;&nbsp; //获取开始时间</p>  <p>　　doSomeThing();&nbsp; //测试的代码段</p>  <p>　　long endTime=System.nanoTime(); //获取结束时间</p>  <p>　　System.out.println("程序运行时间： "+(end-start)+"ns");</p></div><img src ="http://www.blogjava.net/longturi/aggbug/409842.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-02-14 09:51 <a href="http://www.blogjava.net/longturi/archive/2014/02/14/409842.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中计算两个时间差</title><link>http://www.blogjava.net/longturi/archive/2014/02/14/409841.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 14 Feb 2014 01:49:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/02/14/409841.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/409841.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/02/14/409841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/409841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/409841.html</trackback:ping><description><![CDATA[<div>http://china.gmail.cn/html/38/63638-41467.html</div><br /><br /><div>javaz中对日期时间的处理比较多，代码中列出了3中日期时间计算差值的方法。<br /><br />比如：现在是2004-03-26 13：31：40<br />过去是：2004-01-02 11：30：24<br />我现在要获得两个日期差，差的形式为：XX天XX小时XX分XX秒<br /><br />&nbsp;<br /><br />java计算时间差及比较时间大小<br />比如：现在是2004-03-26 13：31：40<br />过去是：2004-01-02 11：30：24<br />我现在要获得两个日期差，差的形式为：XX天XX小时XX分XX秒<br /><br />方法一：<br />DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");<br /><br />try<br />{<br />Date d1 = df.parse("2004-03-26 13:31:40");<br />Date d2 = df.parse("2004-01-02 11:30:24");<br />long diff = d1.getTime() - d2.getTime();<br />long days = diff / (1000 * 60 * 60 * 24);<br />}<br />catch (Exception e)<br />{<br />}<br /><br />方法二： SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");<br />java.util.Date now = df.parse("2004-03-26 13:31:40");<br />java.util.Date date=df.parse("2004-01-02 11:30:24");<br />long l=now.getTime()-date.getTime();<br />long day=l/(24*60*60*1000);<br />long hour=(l/(60*60*1000)-day*24);<br />long min=((l/(60*1000))-day*24*60-hour*60);<br />long s=(l/1000-day*24*60*60-hour*60*60-min*60);<br />System.out.println(""+day+"天"+hour+"小时"+min+"分"+s+"秒");<br /><br />方法三：<br />SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");<br />java.util.Date begin=dfs.parse("2004-01-02 11:30:24");<br />java.util.Date end = dfs.parse("2004-03-26 13:31:40");<br />long between=(end.getTime()-begin.getTime())/1000;//除以1000是为了转换成秒<br /><br />long day1=between/(24*3600);<br />long hour1=between%(24*3600)/3600;<br />long minute1=between%3600/60;<br />long second1=between%60/60;<br />System.out.println(""+day1+"天"+hour1+"小时"+minute1+"分"+second1+"秒");<br /><br /><br />====================================================<br /><br />java 比较时间大小 <br /><br />String s1="2008-01-25 09:12:09";<br />String s2="2008-01-29 09:12:11";<br />java.text.DateFormat df=new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");<br />java.util.Calendar c1=java.util.Calendar.getInstance();<br />java.util.Calendar c2=java.util.Calendar.getInstance();<br />try<br />{<br />c1.setTime(df.parse(s1));<br />c2.setTime(df.parse(s2));<br />}catch(java.text.ParseException e){<br />System.err.println("格式不正确");<br />}<br />int result=c1.compareTo(c2);<br />if(result==0)<br />System.out.println("c1相等c2");<br />else if(result&lt;0)<br />System.out.println("c1小于c2");<br />else<br />System.out.println("c1大于c2");</div><img src ="http://www.blogjava.net/longturi/aggbug/409841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-02-14 09:49 <a href="http://www.blogjava.net/longturi/archive/2014/02/14/409841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在 Liberty 集群中共享内存网格数据</title><link>http://www.blogjava.net/longturi/archive/2014/01/20/409131.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Mon, 20 Jan 2014 04:59:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/01/20/409131.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/409131.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/01/20/409131.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/409131.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/409131.html</trackback:ping><description><![CDATA[<div><div> <div>  <h2><div><span style="font-size: 8pt;">http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/1303_qiuxl_liberty.html</span></div><br /></h2><h2>介绍</h2><h3>WebSphere Liberty Profile Server 介绍</h3><p>Liberty 是一款全新的轻量级应用服务器， 具有以下几个方面的特点：</p><ol type="1"><li>高 模块化&#8212;&#8212;该功能允许用户根据自己应用程序的需求启用或者禁用相关的 feature（所谓  feature，在这里指的是运行应用程序所需要的各种资源的支持。比如，应用程序用到了 JSP，我们就需要启动 JSP 这个  feature，如果不在需要此 feature，就可以将其禁用。通过这种模块化的控制，我们可以按需启动不同的 feature，包括 JSP,   Servlet, JPA 等等，这种控制是实现轻量级应用服务器的基础）。</li><li>轻量级&#8212;&#8212; Liberty 采用了多种技术进行瘦身和优化（主要是 OSGi 的应用），与传统的 WAS 相比，极大的减少了运行时的内存消耗。</li><li>高动态性&#8212;&#8212;由于采用了 OSGi 的架构，程序员在开发的时候，可以动态修改配置文件，应用程序以及服务器的运行时信息，这些修改都是实时生效的，不需要重启服务器。</li><li>快速&#8212;&#8212;由于采用了高模块化的设计，Liberty 应用服务器会&#8220;按需启动&#8221;，自身消耗的系统资源很少，对执行任务的反应时间也非常短，例如，一般来说 Liberty 的启动时间小于 5 秒。</li><li>配置简单&#8212;&#8212;在整个开发过程中，用户只需要和一个配置文件（server.xml）打交道，而且配置的使用也非常灵活。</li></ol><h3>WebSphere eXtreme Scale 介绍</h3><p>WebSphere  eXtreme Scale  以内存网格的方式运行，动态处理、分区、复制和管理数以万计服务器上的应用程序数据和业务逻辑。提供事务完整性和透明的故障恢复功能，从而确保高可用性、 高可靠性和一致的响应时间。它可以监控和管理自己，支持扩大和缩小，可以自动从故障恢复。极大的扩大了应用程序可以支持的用户数量。用更少的时间服务更多 的用户，或者在规定的、可接受的响应时间内为更多的用户提供服务。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/1303_qiuxl_liberty.html#ibm-pcon">回页首</a></p><h2>前提</h2><ul><li>安装 Oracle 或者 IBM JDK，并配置好环境变量。</li><li>如果使用 Eclipse，请安装 WebSphere Application Server V8.5 Liberty Profile Developer Tools</li></ul><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/1303_qiuxl_liberty.html#ibm-pcon">回页首</a></p><h2>安装配置</h2><h3>安装 IBM HTTP 服务器及插件</h3><p>本文将使用 IBM 安装管理器来在测试机 A 中安装 IBM HTTP 服务器以及插件。</p><ul><li>下载并安装 IBM Installation Manager 1.5.2 或以上版本</li><li>下载添加安装路径到 IBM 安装管理器</li><li>选中 IBM HTTP 服务器以及插件</li></ul><h5>图 1. 安装成功界面</h5><img alt="图 1. 安装成功界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image01.jpg" width="580" /><h3>安装 Liberty</h3><p>Liberty 支持两种安装方式：运行 JAR 文件、使用安装管理器安装。本文将介绍如何使用运行 JAR 文件安装 Liberty 服务器。在此例中，将会在测试机 A、B 和 C 上安装 Liberty 服务器。</p><ol type="1"><li>下载 wlp-developers-8.5.0.0.jar 文件到本地机器。</li><li>打开命令行，找到下载的 jar 文件，例如 C:\Liberty。</li><li>执行 java -jar wlp-developers-8.5.0.0.jar。</li><li>设定安装路径完成安装。</li></ol><h5>图 2. Liberty 安装界面</h5><img alt="图 2. Liberty 安装界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image02.jpg" width="580" /><h3>安装 WebSphere eXtreme Scale</h3><p>WebSphere  eXtreme Scale 支持两种安装方式：运行 JAR 文件、使用安装管理器安装。本文将介绍如何使用运行 JAR 文件安装  WebSphere eXtreme Scale 插件。在此例中，将会在测试机 A 上安装 WebSphere eXtreme Scale 插件。</p><ol type="1"><li>下载 wxs-wlp_850.jar 文件到本地机器。</li><li>打开命令行，找到下载的 jar 文件，例如 C:\Liberty。</li><li>执行 java -jar wlp-developers-8.5.0.0.jar。</li><li>设定安装路径完成安装。</li></ol><h5>图 3. WebSphere eXtreme Scale 安装界面</h5><img alt="图 3. WebSphere eXtreme Scale 安装界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image03.jpg" width="580" /><h3>创建 Liberty 服务器</h3><ol type="1"><li>进入 Liberty 安装目录下的 bin 文件夹</li><li>执行服务器创建命令 server create 服务器名称（例如：Test001）</li></ol><p>在本文中将会在测试机 A、B 和 C 上创建三个 Liberty 服务器实例，分别命名为 Test001，Test002 和 Test003.</p><h5>图 4. Liberty 服务器创建界面</h5><img alt="图 4. Liberty 服务器创建界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image04.jpg" width="580" /><p>在 wlp_home/usr/servers 目录下看到以服务器命名的文件夹则表示创建成功。</p><h5>图 5. 服务器创建成功界面</h5><img alt="图 5. 服务器创建成功界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image05.jpg" width="580" /><h3>配置 Liberty 服务器</h3><p>为每个 Liberty 服务器添加两个新功能（在 Liberty 中运行嵌入式 XS 服务器，使用 XS 存储 HTTP 会话）到 server.xml。添加代码如下：</p><h5>清单 1. Feature 添加示例</h5><div><pre>    &lt;!-- Enable features --&gt;      &lt;featureManager&gt;          &lt;feature&gt;jsp-2.2&lt;/feature&gt;          &lt;feature&gt;localConnector-1.0&lt;/feature&gt;          &lt;feature&gt;eXtremeScale.web-1.0&lt;/feature&gt;          &lt;feature&gt;eXtremeScale.server-1.0&lt;/feature&gt;      &lt;/featureManager&gt;</pre></div><p>更改 server.xml 中 HTTP 默认端口，可以在 Test002 中使用 9080 端口，在 Test003 中使用 9081 端口。因为不同的服务器在不同的测试机上，此处我们使用默认端口 9080 不会产生冲突。添加代码如下：</p><h5>清单 2. HTTP 端口修改示例</h5><div><pre> &lt;httpEndpoint host="*"                httpPort="9080"                httpsPort="9443"                id="defaultHttpEndpoint"&gt;</pre></div><p>添加 WXS 配置文件到  Liberty 服务器，并将 Test001 作为 Catalog 服务器。Test002 和 Test003 不需要作为 Catalog  服务器，所以 &lt;xsServer&gt; 标签的 isCatalog 属性设定为&#8220;false&#8221;。添加代码如下：</p><h5>清单 3. XS Server 配置示例</h5><div><pre>    &lt;!-- Configuration for XS Server --&gt;      &lt;xsServer isCatalog="true"                listenerPort="2809"                serverName="Server1"/&gt;      &lt;!-- Configuration for XS HTTP Session data storage --&gt;   &lt;xsWebApp catalogHostPort="localhost:2809"            objectGridType="REMOTE"            replicationInterval="0"            reuseSessionId="true"            securityEnabled="true"            sessionTableSize="0"/&gt;</pre></div><p>在 Test001 服务器目录下创建&#8220;grids&#8221;文件夹，导入 XML 配置文件 deployment.xml 和 objectgrid.xml</p><p>deployment.xml 文件代码如下：</p><h5>清单 4. deployment.xml 示例</h5><div><pre> &lt;?xml version="1.0" encoding="UTF-8"?&gt;   &lt;deploymentPolicy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://ibm.com/ws/objectgrid/   deploymentPolicy ../deploymentPolicy.xsd" 	 xmlns="http://ibm.com/ws/objectgrid/deploymentPolicy"&gt;   &lt;objectgridDeployment objectgridName="session"&gt;   &lt;mapSet name="sessionMapSet"              numberOfPartitions="47"              minSyncReplicas="0"              maxSyncReplicas="0"              maxAsyncReplicas="1"              developmentMode="false"              placementStrategy="FIXED_PARTITIONS"&gt;          &lt;map ref="objectgridSessionMetadata"/&gt;          &lt;map ref="objectgridSessionAttribute.*"/&gt;          &lt;map ref="objectgridSessionTTL.*"/&gt;      &lt;/mapSet&gt;   &lt;/objectgridDeployment&gt;   &lt;/deploymentPolicy&gt;</pre></div><h5>清单 5. objectgrid.xml 示例</h5><div><pre> &lt;?xml version="1.0" encoding="UTF-8"?&gt;   &lt;objectGridConfig xmlns:xsi="http://www.w3.org/2001/   XMLSchema-instance" xsi:schemaLocation="http://ibm.com/ws/   objectgrid/config ../objectGrid.xsd" xmlns="http://ibm.com/ws/objectgrid/config"&gt;   &lt;objectGrids&gt;      &lt;objectGrid name="session" txTimeout="30"&gt;          &lt;bean id="ObjectGridEventListener"                className="com.ibm.ws.xs.   sessionmanager.SessionHandleManager"/&gt;          &lt;backingMap name="objectgridSessionMetadata"                      pluginCollectionRef="objectgridSessionMetadata"                      readOnly="false"                      lockStrategy="PESSIMISTIC"                      ttlEvictorType="LAST_ACCESS_TIME"                      timeToLive="3600"                      copyMode="COPY_TO_BYTES"/&gt;          &lt;backingMap name="objectgridSessionAttribute.*"                      template="true"                      readOnly="false"                      lockStrategy="PESSIMISTIC"                      ttlEvictorType="NONE"                      copyMode="COPY_TO_BYTES"/&gt;          &lt;backingMap name="objectgridSessionTTL.*"                      template="true"                      readOnly="false"                      lockStrategy="PESSIMISTIC"                      ttlEvictorType="LAST_ACCESS_TIME"                      timeToLive="3600"                      copyMode="COPY_TO_BYTES"/&gt;      &lt;/objectGrid&gt;   &lt;/objectGrids&gt;   &lt;backingMapPluginCollections&gt;      &lt;backingMapPluginCollection id="objectgridSessionMetadata"&gt;   &lt;bean id="MapEventListener"        className="com.ibm.ws.xs.sessionmanager.MetadataMapListener"/&gt;      &lt;/backingMapPluginCollection&gt;   &lt;/backingMapPluginCollections&gt;   &lt;/objectGridConfig&gt;</pre></div><p>在三个 Liberty 服务器中添加 &lt;httpSession&gt; 标签，使 Liberty 的会话管理器使用相同的会话 ID，添加代码如下：</p><h5>清单 6. httpSession 重用设定示例</h5><div><pre> &lt;! &#8212; Configuration for httpSession resuse --&gt;   &lt;httpSession idReuse="true"/&gt;</pre></div><p>Test002 和 Test003 不需要配置 XS 服务器，将设定 isCatalog 为"false"， 同时 Test002 和 Test003 不需要创建&#8220;grids&#8221;文件夹。</p><p>为方便起见，在此我们将 Test001、Test002 和 Test003 导入到 Eclipse（Indigo Service Release 2）。</p><h5>图 6. Liberty 服务器导入界面</h5><img alt="图 6. Liberty 服务器导入界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image06.jpg" width="580" /><h3>创建部署测试程序</h3><p>新建 Web Project，命名为 testApp</p><p>在 WebContent 文件夹下创建 index.jsp 文件，文件代码如下：</p><h5>清单 7. Index.jsp 页面代码示例</h5><div><pre> &lt;%@page contentType="text/html" pageEncoding="UTF-8"%&gt;   &lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&gt;     &lt;html&gt;   &lt;head&gt;   &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;   &lt;title&gt; 在 Liberty 集群中共享内存网格数据 &lt;/title&gt;   &lt;/head&gt;   &lt;body&gt;   &lt;h1&gt; 在 Liberty 集群中共享内存网格数据测试页面 !&lt;/h1&gt;   &lt;%   Integer count;   Object obj_Count = session.getAttribute("COUNT");   if (obj_Count != null) {   count = (Integer) obj_Count;   count = count + 1;   } else {   count = 1;   }   session.setAttribute("COUNT", count);   %&gt;   &lt;h3&gt; 计数器会在每次页面加载时加 1&lt;/h3&gt;   &lt;h3&gt;&lt;font color="#FF0000"&gt; 计数器  = &lt;%=count%&gt;&lt;/font&gt;&lt;/h3&gt;   &lt;h4&gt;&lt;font color="#FF0000"&gt;&lt;b&gt; 页面服务器 :   &lt;%= System.getProperty("wlp.server.name") %&gt;&lt;/b&gt;&lt;/font&gt;&lt;/h4&gt;   &lt;br/&gt;  页面生成时间 = &lt;%=new java.util.Date().toString()%&gt;&lt;br/&gt;   &lt;br/&gt;   &lt;/body&gt;   &lt;/html&gt;</pre></div><p>将 testApp 分别部署到 Test002 和 Test003，</p><h5>图 7. 测试程序部署界面</h5><img alt="图 7. 测试程序部署界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image07.jpg" width="580" /><p>启动 Test001 ，Test002 和 Test003 服务器</p><p>可 以使用命令行启停 Liberty 服务器。例如在 Liberty 的安装目录的 bin 文件夹下执行 server  start   Test001 来启动 Test001 服务器。将测试程序直接拷贝应用程序（例如 war 文件）到 dropins 目录，当 Liberty  启动的时候，就会自动扫描，然后启动文件夹内的应用程序。前提是在启动前要配置好 server.xml 中关于应用程序的相关信息，代码如下：</p><h5>清单 8. 应用程序部署示例</h5><div><pre> &lt;application id="testApp"               location="testApp.war"               name="testApp"               type="war"/&gt;</pre></div><h3>配置 HTTP 服务器</h3><p>为 Test002 和 Test003 生成 plugin-cfg.xml 配置文件。在此使用 JAVA 的 jconsole 生成配置文件 </p><p>在 JAVA 的安装目录的 bin 文件夹下运行 jconsole。</p><h5>图 8. Jconsole 启动命令界面</h5><img alt="图 8. Jconsole 启动命令界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image08.jpg" width="580" /><h5>图 9. Jconsole 启动界面</h5><img alt="图 9. Jconsole 启动界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image09.jpg" width="404" /><p>选择之前创建的 Liberty 服务器，连接</p><p>在 MBeans 标签下点击 generateDefaultPluginConfig 方法生成配置文件 .</p><h5>图 10. 配置文件生成界面</h5><img alt="图 10. 配置文件生成界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image10.jpg" width="580" /><p>合并 Test002 和 Test003 的 plugin-cfg.xml 配置文件。文件代码如下，其中的 IP 分别为测试机 B 和 C 的 IP。</p><h5>清单 9. plugin-cfg.xml 代码示例</h5><div><pre> &lt;?xml version="1.0" encoding="UTF-8"?&gt;   &lt;!-- This config file was generated by plugin's merge tool v1.0.0.2 on 2012.10.16 at   16:03:42 CST --&gt;   &lt;Config ASDisableNagle="false"          AcceptAllContent="false"         AppServerPortPreference="HostHeader"          ChunkedResponse="false"         FIPSEnable="false"          IISDisableNagle="false"          IISPluginPriority="High"         IgnoreDNSFailures="false"          RefreshInterval="60"         ResponseChunkSize="64"          SSLConsolidate="false"         SSLPKCSDriver="REPLACE"          SSLPKCSPassword="REPLACE"         TrustedProxyEnable="false"          VHostMatchingCompat="false"&gt;      &lt;Log LogLevel="Error" Name=".\logs\defaultServer\http_plugin.log"/&gt;      &lt;Property Name="ESIEnable" Value="true"/&gt;      &lt;Property Name="ESIMaxCacheSize" Value="1024"/&gt;      &lt;Property Name="ESIInvalidationMonitor" Value="false"/&gt;      &lt;Property Name="ESIEnableToPassCookies" Value="false"/&gt;      &lt;Property Name="PluginInstallRoot" Value="."/&gt;      &lt;!-- Server Clusters --&gt;      &lt;ServerCluster CloneSeparatorChange="false"                     GetDWLMTable="false"                    IgnoreAffinityRequests="true"                     LoadBalance="Round Robin"                    Name="Shared_2_Cluster_0"                     PostBufferSize="64"                     PostSizeLimit="-1"                    RemoveSpecialHeaders="true"                     RetryInterval="60"&gt;          &lt;Server CloneID="Server3CloneID"             ConnectTimeout="0" ExtendedHandshake="false"             MaxConnections="-1" Name="Server3"             ServerIOTimeout="900" WaitForContinue="false"&gt;            &lt;Transport Hostname="9.115.75.85"                       Port="9081"                       Protocol="http"/&gt;          &lt;/Server&gt;          &lt;Server CloneID="Server2CloneID"                 ConnectTimeout="0"                  ExtendedHandshake="false"                 MaxConnections="-1"                  Name="Server2"                 ServerIOTimeout="900"                  WaitForContinue="false"&gt;                &lt;Transport Hostname="9.111.97.74"                           Port="9081"                           Protocol="http"/&gt;           &lt;/Server&gt;           &lt;PrimaryServers&gt;               &lt;Server Name="Server3"/&gt;               &lt;Server Name="Server2"/&gt;           &lt;/PrimaryServers&gt;      &lt;/ServerCluster&gt;      &lt;!-- Virtual Host Groups --&gt;      &lt;VirtualHostGroup Name="/cell/sharedCell_2/vHostGroup/shared_host_0"&gt;          &lt;VirtualHost Name="*:443"/&gt;          &lt;VirtualHost Name="*:80"/&gt;          &lt;VirtualHost Name="*:9080"/&gt;          &lt;VirtualHost Name="*:9081"/&gt;      &lt;/VirtualHostGroup&gt;      &lt;!-- URI Groups --&gt;      &lt;UriGroup Name="/cell/sharedCell_2/application/   default_host_defaultServer_default_node_Cluster_URIs"&gt;          &lt;Uri AffinityCookie="JSESSIONID"              AffinityURLIdentifier="jsessionid"               Name="/test/*"/&gt;      &lt;/UriGroup&gt;      &lt;!-- Routes --&gt;      &lt;Route ServerCluster="Shared_2_Cluster_0"            UriGroup="/cell/sharedCell_2/application/   default_host_defaultServer_default_node_Cluster_URIs"              VirtualHostGroup="/cell/sharedCell_2/vHostGroup/shared_host_0"/&gt;   &lt;/Config&gt;</pre></div><p>将合并后的 plugin-cfg.xml 配置文件拷贝到 IBM HTTP 服务器上。</p><p>下边所示代码到 http.conf 文件使 plugin-cfg.xml 配置文件生效</p><h5>清单 10. plugin-cfg.xml 生效示例</h5><div><pre> LoadModule was_ap22_module "path\to\mod_was_ap22_http.dll"  WebSpherePluginConfig "path\to\plugin-cfg.xml"</pre></div><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/1303_qiuxl_liberty.html#ibm-pcon">回页首</a></p><h2>测试</h2><h3>访问测试程序</h3><p>启动 HTTP 服务器以及 Test001、Test002 和 Test003。在测试机 A 上打开浏览器，访问 <em>http://localhost/testApp/</em> 可以看到 Test002 访问界面或者 Test003 访问界面。这依赖于 HTTP 服务器将请求发送到 Test002 还是 Test003。</p><h5>图 11. Test002 访问界面</h5><img alt="图 11. Test002 访问界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image11.jpg" width="580" /><h5>图 12. Test003 访问界面</h5><img alt="图 12. Test003 访问界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image12.jpg" width="580" /><p>以第一次访问 Test002 为例，此时如果 Test002 发生故障停机了（在此手动停掉 Test002），当再次访问 <em>http://localhost/testApp/</em> 时，HTTP 服务器会将请求发送到 Test003，如图 13 所示。但此时计数器并没有还原，由于两个服务器共享内存网格数据，所以计数器在首次访问 Test003 的时候已经在 Test002 的基础上加了一。</p><h5>图 13. Test003 计数器增加界面</h5><img alt="图 13. Test003 计数器增加界面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1303_qiuxl_liberty/images/image13.jpg" width="580" />   </div> </div>         <h2>参考资料 </h2></div><img src ="http://www.blogjava.net/longturi/aggbug/409131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-01-20 12:59 <a href="http://www.blogjava.net/longturi/archive/2014/01/20/409131.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>websphere liberty 装配 部署 </title><link>http://www.blogjava.net/longturi/archive/2014/01/17/409057.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 17 Jan 2014 06:19:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/01/17/409057.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/409057.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/01/17/409057.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/409057.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/409057.html</trackback:ping><description><![CDATA[<div>websphere   liberty 安装 部署<br />      <p>websphere application server liberty &nbsp;部署</p> <p>&nbsp;</p> <p>下载地址</p> <p>http://www.ibm.com/developerworks/cn/downloads/ws/wasdevelopers/</p> <p>&nbsp;</p> <p>1.IBM WebSphere Application Server Liberty for Developers</p> <p>&nbsp; &nbsp;was.repo.8550.liberty.developers.ilan.zip &nbsp;(112M)</p> <p>&nbsp;</p> <p>2.Installation Manager 1.6.2 for Windows 64-bit ---看实际情况下载</p> <p>agent.installer.win32.win32.x86_64_1.6.2000.20130301_2248.zip &nbsp;(135M)</p> <p>&nbsp;</p> <p>完成下载后，先安装 IBM Installation Manager，安装后让重启&nbsp;IBM Installation Manager，点击&#8220;存储库&#8221;选择</p> <p>was.repo.8550.liberty.developers.ilan.zip解压后的文件repository.config</p> <p>然后就开始安装了...</p> <p>&nbsp;</p> <p>安装好后。</p> <p><strong>启动websphere &nbsp; liberty ：</strong></p> <pre name="code">C:\Users\xxx&gt;"C:\Program Files\IBM\WebSphere\Liberty\bin\server.bat" start    正在启动服务器 defaultServer。    服务器 defaultServer 已启动。</pre> <p><strong>&nbsp;App部署和卸载&nbsp;</strong></p> <p><span style="color: #ff0000;">&nbsp;myserver目录即<span style="font-size: 12px; line-height: 1.5;">C:\Program Files\IBM\WebSphere\Liberty\usr\servers\defaultServer\</span></span></p> <p>部署和卸载行为可以在两个地方发生,一个是server.xml配置文件中,另一个是dropins目录.<br />(1)  在myserver目录下找到server.xml文件并打开,加入&#8221;&lt;application id="hello-app"  location="hello-app.war" name="hello-app"  type="war"/&gt;&#8221;即可完成部署,删除这句话即可完成卸载，即便myserver处于运行状态也可以这样操作，因为server.xml是 可以即时更新的，所做的修改能够马上生效。相对于tomcat这是Liberty  profile的一个优势，当tomcat的server.xml内容被修改修改时必须重启才能生效。这种部署方式适用于开发阶段。<br />(2) 直接将war包扔进myserver目录下的dropins文件夹中即可完成部署，删除此war包机完成卸载，这种部署适用于实施阶段。<br />(3)访问App <br />在浏览器中键入http://localhost:9080/hello-app/index.jsp，页面显示hello world，说明App部署成功，运行正常。</p> <p>&nbsp;</p> <p>参考：</p> <p>http://blog.csdn.net/qiaoyupeng/article/details/7226303</p></div><img src ="http://www.blogjava.net/longturi/aggbug/409057.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-01-17 14:19 <a href="http://www.blogjava.net/longturi/archive/2014/01/17/409057.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>新一代轻量级应用服务器 — WebSphere Liberty Profile Server 介绍</title><link>http://www.blogjava.net/longturi/archive/2014/01/13/408839.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Mon, 13 Jan 2014 03:11:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/01/13/408839.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/408839.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/01/13/408839.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/408839.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/408839.html</trackback:ping><description><![CDATA[<div>http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html</div><br /><div><div id="dw-summary-area"> 		<div> 		<p>2012 年  6 月 15 日，IBM 正式发布了 WebSphere Application Server V8.5 版本（简称 WAS  V8.5）。WebSphere Liberty Profile Server（简称 Liberty）是 WAS V8.5  中最主要的新特性，它是一个基于 OSGi 内核，高模块化，高动态性的轻量级 WebSphere  应用服务器，其安装极为简单（解压即可）、启动非常快、占用很少的磁盘和内存空间，支持 Web、mobile 和 OSGi  应用的开发，旨在提高开发人员的生产效率。</p><p>在本文中，我们将详细介绍什么是 Liberty 以及如何使用 Liberty 快速的开发和部署应用，使读者迅速的掌握这一全新的轻量级应用服务器。</p> 		<p ibm-ind-link"="">  			 			<span id="nCmts">0<img alt="" src="http://dw1.s81c.com/developerworks/i/v17/dw-cmts-arrow.png" height="7" width="7" /> <a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#icomments">评论：</a></span> 		</p> 		</div> 		<div dw-toc-margin"=""> 			<p><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#authorN10017">朱 修磊</a>, 软件工程师, IBM</p>  			<p>2012 年 7 月 19 日</p> 			   			<div id="dw-toc"><div><ul><li><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#toggle"  ibm-twisty-trigger-closed"=""><img src="http://www.ibm.com/i/c.gif" alt="+" /></a>内容</li></ul></div></div> 		</div> 	</div> 	             <div> <div>  <h2>什么是 WebSphere Liberty Profile Server ？</h2><p>Liberty 是一款全新的轻量级应用服务器，它将用户的良好开发体验作为最主要的出发点。其主要特点和内容包括：</p><ul><li>高 模块化&#8212;&#8212;该功能允许用户根据自己应用程序的需求启用或者禁用相关的 feature（所谓  feature，在这里指的是运行应用程序所需要的各种资源的支持。比如，应用程序用到了 JSP，我们就需要启动 JSP 这个  feature，如果不在需要此 feature，就可以将其禁用。通过这种模块化的控制，我们可以按需启动不同的 feature，包括 JSP,  Servlet, JPA 等等，这种控制是实现轻量级应用服务器的基础）。</li><li>轻量级&#8212;&#8212; Liberty 采用了多种技术进行瘦身和优化（主要是 OSGi 的应用），与传统的 WAS 相比，极大的减少了运行时的内存消耗。</li><li>高动态性&#8212;&#8212;由于采用了 OSGi 的架构，程序员在开发的时候，可以动态修改配置文件，应用程序以及服务器的运行时信息，这些修改都是实时生效的，不需要重启服务器。</li><li>快速&#8212;&#8212;由于采用了高模块化的设计，Liberty 应用服务器会&#8220;按需启动&#8221;，自身消耗的系统资源很少，对执行任务的反应时间也非常短，例如，一般来说 Liberty 的启动时间小于 5 秒。</li><li>配置简单&#8212;&#8212;在整个开发过程中，用户只需要和一个配置文件（server.xml）打交道，而且配置的使用也非常灵活。</li></ul><p>尽 管 Liberty 与传统 WAS 相比只是一个&#8220;小块头&#8221;，但是在 Web 和 OSGi 应用程序的开发上，Liberty 与传统 WAS  完全保持一致，在 Liberty 上开发的程序，可以直接移植到传统 WAS 上，不需要做任何的改变。相比传统 WAS 的庞大，Liberty  在为用户提供良好的开发体验上遥遥领先。</p><p>作为应用服务器，Liberty 支持与多种开发工具的结合：</p><ul><li>支持在 Rational Application Developer 中使用 Liberty，推荐在企业级应用开发中使用这种方式，因为这种方式支持最大范围的编程模型以及 Cloud。</li><li>支 持在 Eclipse 3.6(Helios) 或者 3.7(Indigo) 中使用 Liberty, 需要从 Eclipse  Marketplace 安装 WebSphere Application Server V8.5 Developer Tools for  Eclipse 或者 WebSphere Application Server V8.5 Liberty Profile Developer  Tools for Eclipse。在 Eclipse 中使用 Liberty 是完全免费的，当然，如果你需要得到 IBM  工程师的支持，则需要支付额外的费用。</li></ul><p>同时，Liberty 服务器也支持多种主流的操作系统平台，包括  Windows、Linux、Unix、z/OS 以及 Mac OS 等。Liberty 既可以用在开发环境中，也可以用于产品环境（Mac OS  除外）。Liberty 同时支持 Oracle 和 IBM JDK，支持的最低版本分别是：Oracle Java&#8482; 6 update 26 和  IBM Java 6.0 (J9 2.6) SR 1。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>初探 WebSphere Liberty Profile Server</h2><h3>快速安装</h3><p>在 本文中我们主要介绍 Eclipse 与 Liberty 的结合使用，在开始搭建 Liberty 的开发环境前，读者需要自行下载和安装  Oracle 或者 IBM JDK，并配置好环境变量，这是 Liberty 能正常运行的必要条件。如果是以开发为目的，那么使用 Liberty  以及 Liberty 工具是完全免费的，并且没有时间限制。</p><p><strong>在线安装 Liberty 开发工具</strong></p><p>打开 Eclipse，依次点击 Help &gt; Eclipse MarketPlace，在出现的页面搜索栏里输入 websphere，并点击搜索。</p><h5>图 1. 安装 Liberty 开发工具</h5><img alt="图 1. 安装 Liberty 开发工具" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image01.jpg" width="582" /><p>在 搜索结果中会看到如上红色方框标注的工具，其中 WebSphere Application Server V8.5 Liberty Profile  Developer Tools 是 WebSphere Application Server V8.5 Developer Tools  的子集，对于搭建 Liberty 开发环境，直接安装前者就可以，如果读者还需要将 Eclipse 与传统的 WAS  结合使用，那么就需要安装后一个工具。在本文中，我们直接安装 WebSphere Application Server V8.5 Liberty  Profile Developer Tools。在安装过程结束后，需要重启 Eclipse。待 Eclipse 重启后，选择 Servers  视图，右击新建一个服务器，出现如下图所示，则表明 Liberty 开发工具已经成功安装</p><h5>图 2. 验证 Liberty 开发工具安装成功</h5><img alt="图 2. 验证 Liberty 开发工具安装成功" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image02.jpg" width="495" /><p><strong>创建 Liberty 服务器</strong></p><p>在安装好 Liberty 开发工具后，我们需要在 Eclipse 中创建 Liberty 服务器，接着图 2 所示，选择 WebSphere Application Server V8.5 Liberty Profile，点击 Next</p><h5>图 3. 选择 Liberty 的安装位置</h5><img alt="图 3. 选择 Liberty 的安装位置" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image03.jpg" width="500" /><p>在 上图中，我们需要指定 Liberty 服务器的安装位置，对于如何下载 Liberty 服务器，有两种选择：1. 访问 wasdev.net  站点，下载 Liberty 的安装文件，Liberty 安装文件只有不到 50M，下载成功后只需要解压该文件到磁盘的任何一个位置即可完成  Liberty 的安装，&#8220;解压即安装&#8221;，安装 Liberty 就是如此简单。然后，点击 Browser 选择 Liberty  的安装位置，即可继续创建 Liberty 服务器；2. 直击点击上图的 Download or  install，安装提示进行操作，只需要几分钟就可以在线下载并安装一个全新的 Liberty  服务器。在这里我们需要指出的是，您也可以选择直接使用 Liberty 服务器，而不是将其与 Eclipse 搭配起来使用，直接解压下载的  Liberty 到任意目录，就可以使用了。点击 Next，因为 Liberty 默认是没有创建服务器的，所以可以得到下图</p><h5>图 4. 空白的 Liberty 服务器</h5><img alt="图 4. 空白的 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image04.jpg" width="500" /><p>点击 New，创建你的第一个 Liberty 服务器</p><h5>图 5. 创建 Liberty 服务器</h5><img alt="图 5. 创建 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image05.jpg" width="435" /><p>为你的 Liberty 任意指定一个名字，点击 Finish 完成创建。在 Servers 视图中，我们将看到创建好的 DemoServer。</p><h5>图 6. Liberty 服务器概览</h5><img alt="图 6. Liberty 服务器概览" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image06.jpg" width="494" /><p>从上图中我们可以看到 DemoServer 是停止状态，右键 DemoServer，选择 Start 启动 Liberty 服务器，在 Console 视图中检查 log，可以看到 Liberty 已经正常启动。</p><h5>清单 1. Liberty 启动日志</h5><div><pre> Launching DemoServer (wlp-1.0.0.20120428-1251/websphere-kernel_1.0.0)   on Java HotSpot(TM) Client VM, version 1.7.0_01-b08 (en_US)   [AUDIT   ] CWWKE0001I: The server DemoServer has been launched.   [AUDIT   ] CWWKZ0058I: Monitoring dropins for applications.   [AUDIT   ] CWWKF0011I: The server DemoServer is ready to run a smarter planet.</pre></div><p>在上图中，双击 Server Configuration，可以看到如下配置文件（server.xml）。</p><h5>清单 2. 初始的 server.xml 文件</h5><div><pre> &lt;server description="new server"&gt;       &lt;!-- Enable features --&gt;      &lt;featureManager&gt;          &lt;feature&gt;jsp-2.2&lt;/feature&gt;      &lt;/featureManager&gt;       &lt;httpEndpoint id="defaultHttpEndpoint"                   host="localhost"                   httpPort="9080"                   httpsPort="9443" /&gt;    &lt;/server&gt;</pre></div><p>这个 server.xml 就是 Liberty  服务器中唯一的配置文件，我们在开发过程中对应用程序或者 Liberty 运行时的配置都是在这个文件中完成。在默认情况下，Liberty  已经启用了 JSP 功能，我们可以动态的根据应用的需求为 Liberty 增加各种功能支持，方法如下：</p><p>在 server.xml 编辑窗口下方，选择 Design 模式，</p><h5>图 7. 图形化编辑配置文件</h5><img alt="图 7. 图形化编辑配置文件" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image07.jpg" width="582" /><p>选择左侧 Feature Manager，然后选择右侧 Add，出现下图列表，根据需要添加相应的功能支持。</p><h5>图 8. Features 列表</h5><img alt="图 8. Features 列表" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image08.jpg" width="439" /><p>当 然，读者也可以直接手工编辑 server.xml，手动添加需要的 Feature，但是要注意遵循 Liberty  配置文件的编写规范。到此，我们已经成功的安装了 Liberty 服务器，并搭建好了 Liberty  服务器的开发环境。开始我们的例子程序之前，下文首先向读者更深层次的介绍 Liberty 的功能特性。</p><h3>简化服务器配置</h3><p>在  Liberty 中，和用户打交道的只有一个配置文件  server.xml。关于应用程序或者服务器运行时的所有配置都是在这一个文件中完成的，简化了服务器的配置，也减轻了程序员的负担。我们可以在  Eclipse 中直接编辑该文件，修改内容会实时生效。这个配置文件是可以被导出，也可以被不同的服务器共享。</p><h3>灵活的服务器配置</h3><h5>图 9. 灵活配置</h5><img alt="图 9. 灵活配置" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image09.jpg" width="511" /><p>对 于配置文件的使用是非常灵活的，例如：如果有很多个 Liberty  都需要用到同一个配置文件，那么可以将该文件单独导出，存放在一个共享的位置，单个的 Liberty 服务器可以利用 &lt;incluse  /&gt;  属性导入共享的配置文件；又比如配置文件的内容非常多而且繁杂，我们就可以将其中的内容分别写在不同的配置文件中（称为不同的配置文件片段），同样利用  &lt;include /&gt; 将这些片段文件导入到主配置文件中，运行时会负责去实时的解析这些片段文件。</p><h3>应用部署</h3><p>在 Liberty 中部署应用也是非常简单的事情，打开你的 Liberty 安装目录 &lt;Liberty_Install_dir&gt;\usr\servers\server_name ，可以看到如下目录结构 :</p><h5>图 10. 应用部署目录</h5><img alt="图 10. 应用部署目录" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image10.jpg" width="582" /><p>在 上图中 apps 和 dropins 是两个存放安装的应用的文件夹，我们可以通过 Eclipse 部署应用到 Liberty，应用文件将被放在  apps 下面（这个是应用部署的默认目录，也可以通过配置，将应用文件部署到其他任何位置）。我们也可以直接拷贝应用程序（例如 war 文件）到  dropins 目录，当 Liberty  启动的时候，就会自动扫描上面的两个文件夹，然后启动文件夹内的应用程序。当然，启动应用前，要确保已经配置好 server.xml 里的相关信息。</p><h3>动态加载模块</h3><h5>图 11. 动态化加载</h5><img alt="图 11. 动态化加载" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image11.jpg" width="582" /><p>与 传统 WAS 不同的是，Liberty  并不是一个静态的服务器，它是动态的，可以根据应用程序的需要动态加载相应的模块。这些模块是以&#8220;feature&#8221;来定义的，比如 JSP,  Servlet 等，都是不同的 feature。可以将 feature 看作是一个独立的模块，它由一到多个 OSGi bundle  组成，共同来完成某一个特定的任务。这些 feature 可是随时被添加和移除，而不需要重启服务器，正是得益于这样的动态化设计，Liberty  无论在启动时间还是反应时间上都更胜一筹，为程序员带来了快速的开发体验。</p><h3>运行时动态更新</h3><h5>图 12. 动态更新</h5><img alt="图 12. 动态更新" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image12.jpg" width="533" /><p>Liberty  为我们提供了一个可以动态实时更新的运行时，无论你是修改了应用程序，还是修改配置文件都会实时的被 Liberty  检测到，并立即更新运行时到最新状态，无需重启 Liberty 服务器。新的 feature 可以被随时的添加到 server.xml  中，运行时为负责实时启动相应的功能模块，这一切都与程序员来说都是透明的。例如：我们首先启动 Liberty 服务器，然后将一个 JSP 应用放到  dropins 目录里，如果你没有在 server.xml 中启动 JSP  功能，那么该应用就不会被启动。你将会得到一个警告信息，提示你应该首先启用 JSP 功能，然后该应用才会被实时的启动。同样，如果你将 JSP  功能从 server.xml 中移除，该应用也会被立刻停止。</p><h3>新型的软件部署方式</h3><h5>图 13. 集中管理 Liberty 服务器</h5><img alt="图 13. 集中管理 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image13.jpg" width="582" /><p>当 我们使用 Liberty 开发完应用程序后，Liberty 为我们提供了一个全新的软件部署方式，我们可以将 Liberty  服务器和应用程序一起打包为 ZIP 文件，然后将这个 ZIP  传输到需要部署软件的服务器上直接解压即可。为了支持适合云端和大规模应用的部署，WebSpere（传统  WAS）还提供了集中管理部署的功能（需要安装 WAS ND 版本），使用该功能可以将我们事先打好的 ZIP  包远程的传输到多个服务器上，在传送完成后，WAS 还会负责解压和安装。另外，WAS 的集中管理功能还提供了远程启动、停止和卸载 Liberty  服务器的功能。</p><h3>Liberty 之于开发人员</h3><p>对于开发人员来说，Liberty  的出现是一个十分振奋人心的消息。首先，Liberty 作为一个轻量级的应用服务器，和 Eclipse  可以完美的结合，其最重要的特性就是关注程序员的开发体验，包括快速的下载、安装和环境搭建，在开发过程中，实时的应用更新而无需重启服务器，这些都会极 大的提高程序员的开发效率；其次，在开发，测试和部署应用的过程中，Liberty 都极其友好和方便，其与传统 WAS  的完全兼容，也为应用程序的迁移提供了有力的保障。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>与主流 WEB 容器的对比</h2><p>从某种程度上来讲，目前，Liberty 与 Tomcat 处在同一个产品层次上，我们从功能特性、使用体验以及标准支持上对这两个服务器进行了对比，从中，我们可以看出 Liberty 在轻量级服务器中所具有的独特优势：</p><h5>表 1. Liberty VS Tomcat</h5><table summary="" border="0" cellpadding="0" cellspacing="0"><thead><tr><th><strong>对比项</strong></th><th><strong>Tomcat</strong></th><th><strong>Liberty</strong></th></tr></thead><tbody><tr><td>大小</td><td>&lt;30M</td><td>&lt;50M</td></tr><tr><td>启动速度</td><td>&lt;5s</td><td>&lt;5s</td></tr><tr><td>Java EE 标准支持</td><td>JSP 2.2, Servlet 3.0, JSTL 1.2 用户需要添加相关的 jar 包来实现对其它标准的支持</td><td>JSP  2.2, Servlet 3.0, JSF 2.0, JSTL 1.2, JPA 2.0, JDBC 4.0, JAX-RS 1.0,  JNDI 1.0, Bean Validation 1.0, SSL 1.0, Security 1.0, Web Security 1.0,  JMX 1.0 可动态加载或卸载对应的 feature</td></tr><tr><td>OSGi 编程模型</td><td>否</td><td>是，支持 Blue Print 1.0, WAB 1.0</td></tr><tr><td>开发工具</td><td>支持 Eclipse</td><td>支持 eclipse, IBM Rational Application Developer</td></tr><tr><td>支持的操作系统</td><td>Linux, Windows</td><td>Linux, Windows, AIX, Mac, HP-UX, Solaris, iSeries, zSeries</td></tr><tr><td>性能</td><td>一般</td><td>与传统 WAS 具有相同的核心代码，性能好</td></tr><tr><td>应用程序热部署</td><td>支持</td><td>支持</td></tr><tr><td>配置文件</td><td>多个配置文件，更新后需重启服务器</td><td>一个配置文件，更新后及时生效，无需重启</td></tr><tr><td>可移植性</td><td>您可以利用 IBM Application Migration Toolkit 将 Tomcat 上开发的应用快速移植到 WebSphere 应用服务器。反之，则不然。</td><td>Liberty 和传统 WAS 对编程模型和标准的支持一致。在 Liberty 上开发的应用可以直接运行在传统 WAS 之上</td></tr><tr><td>文档</td><td>官方文档涵盖内容有限，但网络上相关内容（包括：blog，技术文章等）广泛。</td><td>http://wasdev.net 上提供下载地址、文档、视频、音频、样本引用等。还有 WAS 的信息中心也有大量文档可供参考阅读。</td></tr><tr><td>社区</td><td>http://tomcat.apache.org 有 dev 和 user mailing list，没有官方支持，有时回复不够及时。</td><td>http://wasdev.net，可以与开发人员直接交流</td></tr><tr><td>长期战略优势</td><td>一般用于开发环境，生产环产能用的比较少。支持的并发度不高，可扩展性不强。</td><td>  Liberty 与传统 WAS 共享同一代码，天生具有其高效稳定的特点。开发 - 测试 - 生产切换零代价。可扩展性高，支持多个 server 间的负载均衡和故障恢复。 </td></tr></tbody></table><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>Demo：使用 Eclipse 和 Liberty 开发 Web 应用</h2><p>通 过上面的介绍，相信大家对 Liberty 已经有了一个大概的认识，接下来我们通过一个 Demo 来向大家展示如何使用 Liberty 和  Eclipse 开发 Web 应用。开始 Demo 之前，请大家根据上文的介绍，搭建自己的 Liberty 开发环境，并安装好 JDK  并且配置好环境变量。</p><p>Demo 程序很简单，包含一个 Servlet，实现打印当前时间的功能。步骤如下：</p><ol type="1"><li>打开 Eclipse，选择 File &gt; New &gt; Web&gt;Dynamic Web Project</li><li>设置如下属性值： 				  <ol type="a"><li>Project name: Demo</li><li>Target runtime: WebSphere Application Server V8.5 Liberty Profile</li></ol><h5>图 14. 创建动态 Web 工程</h5><img alt="图 14. 创建动态 Web 工程" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image14.jpg" width="495" /></li><li>点击 Next 两次，然后点击 Finish，完成工程的创建。 			  <p>此时，你可以在左侧的资源导航页面看到刚刚创建完成的 Demo 工程，展开工程就可以看到一些默认创建的资源。</p></li><li>右击 Src 目录，选择 New &gt; Class</li><li>设置如下属性值： 				  <ol type="a"><li>Package: com.date.demo</li><li>Name: DateProvider</li></ol><h5>图 15. 创建 java 文件</h5><img alt="图 15. 创建 java 文件" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image15.jpg" width="490" /></li><li>点击 Finish</li><li>编辑如下代码到 DateProvider.java  			  <h5>清单 3. DateProvider.java</h5><div><pre> package com.date.demo;    import java.util.Date;    public class DateProvider {    public String getDate() {   // TODO Auto-generated method stub   return new Date().toString();   }   }</pre></div><p>该文件只包含一个方法，getDate() 用来获得当前时间。</p></li><li>右击 Src，选择 New &gt; Servlet</li><li>设置如下属性值  				  <ol type="a"><li>Java package: com.date.demo</li><li>Class name: DatePrintServlet</li></ol><h5>图 16. 创建 Servlet 文件</h5><img alt="图 16. 创建 Servlet 文件" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image16.jpg" width="494" /></li><li>点击 Finish，完成创建。</li><li>编辑如下内容到 DatePrintServlet.java  			  <h5>清单 4. DatePrintServlet.java</h5><div><pre> package com.date.demo;    import java.io.IOException;   import javax.servlet.ServletException;   import javax.servlet.annotation.WebServlet;   import javax.servlet.http.HttpServlet;   import javax.servlet.http.HttpServletRequest;   import javax.servlet.http.HttpServletResponse;    /**   * Servlet implementation class DatePrintServlet   */   @WebServlet("/DatePrintServlet")   public class DatePrintServlet extends HttpServlet {   private static final long serialVersionUID = 1L;            /**       * @see HttpServlet#HttpServlet()       */      public DatePrintServlet() {          super();          // TODO Auto-generated constructor stub      }   /**   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)   */   protected void doGet(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {   // TODO Auto-generated method stub   DateProvider dateProvider=new DateProvider();   response.getWriter().println(dateProvider.getDate());   }    /**   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)   */   protected void doPost(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {   // TODO Auto-generated method stub   }    }</pre></div></li><li>在左侧导航栏选择 DatePrintServlet，点击右键 Run As &gt; Run on Server , 如下图： 			 <h5>图 17. 选择 Liberty 服务器</h5><img alt="图 17. 选择 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image17.jpg" width="553" /></li><li>点击 Finish，Liberty 开发工具将会为我们部署上面的 Demo 程序，并启动 Liberty 服务器。从 console 的日志里我们可以看到如下描述：</li></ol><p>[AUDIT   ] CWWKZ0001I: Application Demo started in 1.235 seconds.</p><p>表明 Demo 应用已经成功部署了，同时，在 Eclipse 自带的浏览器里可以看到如下页面信息：</p><h5>图 18. Demo 运行页面</h5><img alt="图 18. Demo 运行页面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image18.jpg" width="580" /><p>让我们回过头来看看 server.xml 里面的内容：</p><h5>清单 5. server.xml</h5><div><pre> &lt;server description="new server"&gt;       &lt;!-- Enable features --&gt;      &lt;featureManager&gt;          &lt;feature&gt;jsp-2.2&lt;/feature&gt;          &lt;feature&gt;localConnector-1.0&lt;/feature&gt;       &lt;/featureManager&gt;       &lt;httpEndpoint host="localhost" httpPort="9080" httpsPort="9443"      id="defaultHttpEndpoint"/&gt;       &lt;applicationMonitor updateTrigger="mbean"/&gt;       &lt;application id="Demo" location="Demo.war" name="Demo" type="war"/&gt;   &lt;/server&gt;</pre></div><p>其中：</p><p>&lt;feature /&gt; 包含了应用程序中所用到的功能包，如果你启用了 jsp-2.2，那么 Liberty 默认支持对 Servlet 3.0。</p><p>&lt;httpEndpoint /&gt; 指定了 HTTP 访问的端口，我们可以在这里改变默认的端口。</p><p>&lt;applicationMonitor  /&gt; 用来配置对应用程序的监控模式，updateTrigger 属性是用来控制动态更新的，通过 Liberty 工具部署应用时  updateTrigger 的值设置为 mbean，当我们直接把应用程序拖进 dropins 时，需要将 updateTrigger 设为  polled，当然，如果我们不需要应用的动态更新功能，可以将这个值设为 disabled.</p><p>&lt;application /&gt; 用来指定和应用本身相关的属性，id 和 name 是应用的唯一标识，type 指定了应用的类型，location 指定应用所在的位置，默认是在 apps 目录里面，我们可以通过配置修改这个默认设置。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>总结</h2><p>通 过上面的介绍，相信读者已经对 WAS V8.5 最重要的特性 Liberty 有了一个全面的认识，作为新一代轻量级应用服务器，Liberty  采用了和传统 WAS 相同的代码，继承了传统 WAS 的优点，无论在性能上还是在稳定性上都优越于其他同类产品。Liberty  无论是在开发环境中还是在产品环境中，都具有其他产品不可比拟的优势。我们有理由相信，在追求开发效率和软件质量的今天，每一个程序员都会很快的接受这个  WAS 家族的&#8220;小块头&#8221;。</p>   </div> </div>         <h2>参考资料 </h2><h3>学习</h3><ul><li> 			访问 <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp">WebSphere Application Server V8.5 信息中心</a> 了解更多关于 WAS 的信息。             </li><li> 			访问 <a href="http://wasdev.net/">wasdev.net 主页</a> 学习更多 Liberty 的知识，并直接和开发人员进行交流。            </li><li> 			访问 <a href="http://publib.boulder.ibm.com/infocenter/radhelp/v8r5/index.jsp">WebSphere Developer Tools V8.5 信息中心</a> 学习更多 WDT 的知识。            </li><li><a href="http://www.ibm.com/developerworks/cn/websphere/">IBM developerWorks 中国 WebSphere 专区</a>：为使用 WebSphere 产品的开发人员准备的技术信息和资料。这里提供产品下载、how-to 信息、支持资源以及免费技术库，包含 2000 多份技术文章、教程、最佳实践、IBM Redbook 和在线产品手册。</li></ul><h3>获得产品和技术</h3><ul><li><a href="http://www.ibm.com/developerworks/cn/websphere/downloads/"> 最受欢迎的 WebSphere 试用软件下载</a>：下载关键 WebSphere 产品的免费试用版。</li><li><a href="http://www.ibm.com/developerworks/cn/downloads/">IBM developerWorks 软件下载资源中心</a>：IBM deveperWorks 最新的软件下载。</li><li><a href="http://www.ibm.com/developerworks/cn/offers/kits/">IBM developerWorks 工具包</a>：下载关键 WebSphere 最新的产品工具包。</li></ul><h3>讨论</h3><ul><li>加入 <a href="http://www.ibm.com/developerworks/cn/community/">developerWorks 中文社区</a>，developerWorks 社区是一个面向全球 IT 专业人员，可以提供博客、书签、wiki、群组、联系、共享和协作等社区功能的专业社交网络社区。</li><li>加入 <a href="https://www.ibm.com/developerworks/mydeveloperworks/groups/service/html/communityview?communityUuid=38997896-bb16-451a-aa97-189a27a3cd5a/?lang=zh">IBM 软件下载与技术交流群组</a>，参与在线交流。</li></ul></div><img src ="http://www.blogjava.net/longturi/aggbug/408839.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-01-13 11:11 <a href="http://www.blogjava.net/longturi/archive/2014/01/13/408839.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> websphere application server v8.5 liberty profile试用 </title><link>http://www.blogjava.net/longturi/archive/2014/01/10/408782.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 10 Jan 2014 10:36:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/01/10/408782.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/408782.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/01/10/408782.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/408782.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/408782.html</trackback:ping><description><![CDATA[<div><div id="article_content">  <p>IBM邀请我们公司试用websphere application server v8.5 liberty profile,因此经理让我下载下来安装,测试一下,正好我正对这个新东西也挺感兴趣的,所以在此把过程记录下来.</p> <p>一、简介<br /> Liberty profile是WAS  V8.5的一个新特性，它代表WAS服务器上的App正常运行必须的一组运行时环境集合,这个环境是可以动态配置的。简单说Liberty  profile就是WAS8.5的精简版，具有占用空间少、启动速度快、调试方便、完全支持JavaEE、App无缝移植到WAS8.5等特性，特别适合 开发测试阶段使用。<br /> <br /> <br /> 二、安装,部署<br /> <br /> <br /> 1.前提：<br /> 确保计算机上正确安装了JDK1.6或以上版本，Eclipse3.7或以上版本（可选）。<br /> 2.安装Liberty profile<br /> 将下载得到的Zip包was4d-20111202-0614.zip，解 压到磁盘任意目录下，无误后安装完毕。可以参照根目录下的readme.txt文件，掌握Liberty  profile的基本配置管理。在这里假设Liberty profile的安装目录为&lt;install.dir&gt;。<br /> 3.创建server实例<br /> Liberty  profile继承了WAS的profile特性，即运行时环境可以以实例的形式单独动态配置，实例之间互不影响。因此，进入cmd模式下 cd bin  ,然后was4d.bat create  myserver，这样就创建了一个名称为myserver的运行时环境实例，其磁盘路径为&lt;install.dir&gt;\usr \servers\myserver，我们开发的App可以部署到myserver目录下的dropins文件夹中运行，供外界访问。<br /> 4.安装Liberty profile Eclipse开发插件<br /> 在Eclipse Marketplace中键入websphere，在随后的结果列表中找到websphere application server v8.5 liberty profile beta一项，点击install安装，完毕后重启Eclipse。<br /> 5.在Eclipse中引用myserver实例<br /> 在Eclipse 中的Server视图中右击  New-Server,在弹出框中选择IBM- websphere application server v8.5 liberty profile  beta,然后根据提示选择myserver实例即可，无误完毕后会在Server视图中出现websphere application  server v8.5 liberty profile beta at localhost 一项，右击websphere  application server v8.5 liberty profile beta at  localhost选择start，此时Console视图会出现myserver启动日志，&#8220;The feature update is  complete after &#8230;&#8221;表示启动成功。<br /> 6.开发App<br /> 在Eclipse中新建一个简单的Java Web App 命名为hello-app，在其index.jsp页面中输入hello world即可。<br /> 7.App部署和卸载&nbsp;<br /> 部署和卸载行为可以在两个地方发生,一个是server.xml配置文件中,另一个是dropins目录.<br /> (1) 在 myserver目录下找到server.xml文件并打开,加入&#8221;&lt;application id="hello-app"  location="hello-app.war" name="hello-app"  type="war"/&gt;&#8221;即可完成部署,删除这句话即可完成卸载，即便myserver处于运行状态也可以这样操作，因为server.xml是 可以即时更新的，所做的修改能够马上生效。相对于tomcat这是Liberty  profile的一个优势，当tomcat的server.xml内容被修改修改时必须重启才能生效。这种部署方式适用于开发阶段。<br /> (2) 直接将war包扔进myserver目录下的dropins文件夹中即可完成部署，删除此war包机完成卸载，这种部署适用于实施阶段。<br /> 8.访问App&nbsp;<br /> 在浏览器中键入http://localhost:9080/hello-app/index.jsp，页面显示hello world，说明App部署成功，运行正常。<br /> <br /> <br /> 三、Liberty,Tomcat6,was比较<br /> Tomcat  和was的比较很简单,一个开源一个商用,开源的Tomcat小巧,灵活适合做开发测试,商用的was它提供了一个平台，你可以基于各种增值功能、使用 Process Server、MQ等等更先进而稳定的架构来构建应用.对于并发,高性能访问的处理能力会更强.<br /> 由于Liberty profile 是 was 的简易版本,所以Liberty profile只适合开发相对比较简单的App,而这个App可以无缝移植到WAS上.<br /> </p> <p>Tomcat6 与 Liberty profile的比较，红色为各自的优势<br /> </p> <p>Tomcat6  Liberty profile&nbsp;<br /> </p> <p>占用空间  27MB 56MB<br /> </p> <p>启动时间  996ms 1600ms<br /> </p> <p>配置复杂度  较复杂,配置文件较多 很简单,可以无配置文件<br /> <br /> Server.xml<br /> 即时更新 不支持,需重启生效支持,即时生效<br /> <br /> 运行环境<br /> 多实例 不支持,灵活性较差支持,灵活性较高<br /> <br /> Java EE<br /> 规范支持 不支持serverlet3.0支持serverlet3.0<br /> 支持jpa2.0  支持jpa2.0<br /> 不支持EJB  不支持EJB<br /> <br /> 四、总结<br /> 之前开发WAS应用时,如果这个App不依赖于容器,我们通常的做法是在Tomcat中开发测试,在WAS中部署运行,而部署时App的配置文件必定要做相应的修改,比如JNDI。<br /> 现在不用了，我们有了Liberty profile----WAS的一组运行时环境，它与Tomcat一样免费，轻巧，快速，灵活，而且开发的应用不做任何修改就能移植到WAS上。<br /> 相对于与Tomcat6，Liberty profile支持最新的JavaEE规范，增加了很多功能更加强大，使用非常方便的特性，所以Liberty  profile比Tomcat更优秀，即便App不是基于WAS也可以使用Liberty profile进行开发测试。</p>  </div></div><img src ="http://www.blogjava.net/longturi/aggbug/408782.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-01-10 18:36 <a href="http://www.blogjava.net/longturi/archive/2014/01/10/408782.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>新一代轻量级应用服务器 — WebSphere Liberty Profile Server 介绍</title><link>http://www.blogjava.net/longturi/archive/2014/01/10/408781.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 10 Jan 2014 10:31:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/01/10/408781.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/408781.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/01/10/408781.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/408781.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/408781.html</trackback:ping><description><![CDATA[<div>http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html</div><br /><div><div id="dw-summary-area"> 		<div> 		<p>2012 年  6 月 15 日，IBM 正式发布了 WebSphere Application Server V8.5 版本（简称 WAS  V8.5）。WebSphere Liberty Profile Server（简称 Liberty）是 WAS V8.5  中最主要的新特性，它是一个基于 OSGi 内核，高模块化，高动态性的轻量级 WebSphere  应用服务器，其安装极为简单（解压即可）、启动非常快、占用很少的磁盘和内存空间，支持 Web、mobile 和 OSGi  应用的开发，旨在提高开发人员的生产效率。</p><p>在本文中，我们将详细介绍什么是 Liberty 以及如何使用 Liberty 快速的开发和部署应用，使读者迅速的掌握这一全新的轻量级应用服务器。</p> 		<p ibm-ind-link"="">  			 			<span id="nCmts">0<img alt="" src="http://dw1.s81c.com/developerworks/i/v17/dw-cmts-arrow.png" height="7" width="7" /> <a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#icomments">评论：</a></span> 		</p> 		</div> 		<div dw-toc-margin"=""> 			<p><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#authorN10017">朱 修磊</a>, 软件工程师, IBM</p>  			<p>2012 年 7 月 19 日</p> 			   			<div id="dw-toc"><div><ul><li><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#toggle"  ibm-twisty-trigger-closed"=""><img src="http://www.ibm.com/i/c.gif" alt="+" /></a>内容</li></ul></div></div> 		</div> 	</div> 	             <div> <div>  <h2>什么是 WebSphere Liberty Profile Server ？</h2><p>Liberty 是一款全新的轻量级应用服务器，它将用户的良好开发体验作为最主要的出发点。其主要特点和内容包括：</p><ul><li>高 模块化&#8212;&#8212;该功能允许用户根据自己应用程序的需求启用或者禁用相关的 feature（所谓  feature，在这里指的是运行应用程序所需要的各种资源的支持。比如，应用程序用到了 JSP，我们就需要启动 JSP 这个  feature，如果不在需要此 feature，就可以将其禁用。通过这种模块化的控制，我们可以按需启动不同的 feature，包括 JSP,  Servlet, JPA 等等，这种控制是实现轻量级应用服务器的基础）。</li><li>轻量级&#8212;&#8212; Liberty 采用了多种技术进行瘦身和优化（主要是 OSGi 的应用），与传统的 WAS 相比，极大的减少了运行时的内存消耗。</li><li>高动态性&#8212;&#8212;由于采用了 OSGi 的架构，程序员在开发的时候，可以动态修改配置文件，应用程序以及服务器的运行时信息，这些修改都是实时生效的，不需要重启服务器。</li><li>快速&#8212;&#8212;由于采用了高模块化的设计，Liberty 应用服务器会&#8220;按需启动&#8221;，自身消耗的系统资源很少，对执行任务的反应时间也非常短，例如，一般来说 Liberty 的启动时间小于 5 秒。</li><li>配置简单&#8212;&#8212;在整个开发过程中，用户只需要和一个配置文件（server.xml）打交道，而且配置的使用也非常灵活。</li></ul><p>尽 管 Liberty 与传统 WAS 相比只是一个&#8220;小块头&#8221;，但是在 Web 和 OSGi 应用程序的开发上，Liberty 与传统 WAS  完全保持一致，在 Liberty 上开发的程序，可以直接移植到传统 WAS 上，不需要做任何的改变。相比传统 WAS 的庞大，Liberty  在为用户提供良好的开发体验上遥遥领先。</p><p>作为应用服务器，Liberty 支持与多种开发工具的结合：</p><ul><li>支持在 Rational Application Developer 中使用 Liberty，推荐在企业级应用开发中使用这种方式，因为这种方式支持最大范围的编程模型以及 Cloud。</li><li>支 持在 Eclipse 3.6(Helios) 或者 3.7(Indigo) 中使用 Liberty, 需要从 Eclipse  Marketplace 安装 WebSphere Application Server V8.5 Developer Tools for  Eclipse 或者 WebSphere Application Server V8.5 Liberty Profile Developer  Tools for Eclipse。在 Eclipse 中使用 Liberty 是完全免费的，当然，如果你需要得到 IBM  工程师的支持，则需要支付额外的费用。</li></ul><p>同时，Liberty 服务器也支持多种主流的操作系统平台，包括  Windows、Linux、Unix、z/OS 以及 Mac OS 等。Liberty 既可以用在开发环境中，也可以用于产品环境（Mac OS  除外）。Liberty 同时支持 Oracle 和 IBM JDK，支持的最低版本分别是：Oracle Java&#8482; 6 update 26 和  IBM Java 6.0 (J9 2.6) SR 1。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>初探 WebSphere Liberty Profile Server</h2><h3>快速安装</h3><p>在 本文中我们主要介绍 Eclipse 与 Liberty 的结合使用，在开始搭建 Liberty 的开发环境前，读者需要自行下载和安装  Oracle 或者 IBM JDK，并配置好环境变量，这是 Liberty 能正常运行的必要条件。如果是以开发为目的，那么使用 Liberty  以及 Liberty 工具是完全免费的，并且没有时间限制。</p><p><strong>在线安装 Liberty 开发工具</strong></p><p>打开 Eclipse，依次点击 Help &gt; Eclipse MarketPlace，在出现的页面搜索栏里输入 websphere，并点击搜索。</p><h5>图 1. 安装 Liberty 开发工具</h5><img alt="图 1. 安装 Liberty 开发工具" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image01.jpg" width="582" /><p>在 搜索结果中会看到如上红色方框标注的工具，其中 WebSphere Application Server V8.5 Liberty Profile  Developer Tools 是 WebSphere Application Server V8.5 Developer Tools  的子集，对于搭建 Liberty 开发环境，直接安装前者就可以，如果读者还需要将 Eclipse 与传统的 WAS  结合使用，那么就需要安装后一个工具。在本文中，我们直接安装 WebSphere Application Server V8.5 Liberty  Profile Developer Tools。在安装过程结束后，需要重启 Eclipse。待 Eclipse 重启后，选择 Servers  视图，右击新建一个服务器，出现如下图所示，则表明 Liberty 开发工具已经成功安装</p><h5>图 2. 验证 Liberty 开发工具安装成功</h5><img alt="图 2. 验证 Liberty 开发工具安装成功" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image02.jpg" width="495" /><p><strong>创建 Liberty 服务器</strong></p><p>在安装好 Liberty 开发工具后，我们需要在 Eclipse 中创建 Liberty 服务器，接着图 2 所示，选择 WebSphere Application Server V8.5 Liberty Profile，点击 Next</p><h5>图 3. 选择 Liberty 的安装位置</h5><img alt="图 3. 选择 Liberty 的安装位置" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image03.jpg" width="500" /><p>在 上图中，我们需要指定 Liberty 服务器的安装位置，对于如何下载 Liberty 服务器，有两种选择：1. 访问 wasdev.net  站点，下载 Liberty 的安装文件，Liberty 安装文件只有不到 50M，下载成功后只需要解压该文件到磁盘的任何一个位置即可完成  Liberty 的安装，&#8220;解压即安装&#8221;，安装 Liberty 就是如此简单。然后，点击 Browser 选择 Liberty  的安装位置，即可继续创建 Liberty 服务器；2. 直击点击上图的 Download or  install，安装提示进行操作，只需要几分钟就可以在线下载并安装一个全新的 Liberty  服务器。在这里我们需要指出的是，您也可以选择直接使用 Liberty 服务器，而不是将其与 Eclipse 搭配起来使用，直接解压下载的  Liberty 到任意目录，就可以使用了。点击 Next，因为 Liberty 默认是没有创建服务器的，所以可以得到下图</p><h5>图 4. 空白的 Liberty 服务器</h5><img alt="图 4. 空白的 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image04.jpg" width="500" /><p>点击 New，创建你的第一个 Liberty 服务器</p><h5>图 5. 创建 Liberty 服务器</h5><img alt="图 5. 创建 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image05.jpg" width="435" /><p>为你的 Liberty 任意指定一个名字，点击 Finish 完成创建。在 Servers 视图中，我们将看到创建好的 DemoServer。</p><h5>图 6. Liberty 服务器概览</h5><img alt="图 6. Liberty 服务器概览" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image06.jpg" width="494" /><p>从上图中我们可以看到 DemoServer 是停止状态，右键 DemoServer，选择 Start 启动 Liberty 服务器，在 Console 视图中检查 log，可以看到 Liberty 已经正常启动。</p><h5>清单 1. Liberty 启动日志</h5><div><pre> Launching DemoServer (wlp-1.0.0.20120428-1251/websphere-kernel_1.0.0)   on Java HotSpot(TM) Client VM, version 1.7.0_01-b08 (en_US)   [AUDIT   ] CWWKE0001I: The server DemoServer has been launched.   [AUDIT   ] CWWKZ0058I: Monitoring dropins for applications.   [AUDIT   ] CWWKF0011I: The server DemoServer is ready to run a smarter planet.</pre></div><p>在上图中，双击 Server Configuration，可以看到如下配置文件（server.xml）。</p><h5>清单 2. 初始的 server.xml 文件</h5><div><pre> &lt;server description="new server"&gt;       &lt;!-- Enable features --&gt;      &lt;featureManager&gt;          &lt;feature&gt;jsp-2.2&lt;/feature&gt;      &lt;/featureManager&gt;       &lt;httpEndpoint id="defaultHttpEndpoint"                   host="localhost"                   httpPort="9080"                   httpsPort="9443" /&gt;    &lt;/server&gt;</pre></div><p>这个 server.xml 就是 Liberty  服务器中唯一的配置文件，我们在开发过程中对应用程序或者 Liberty 运行时的配置都是在这个文件中完成。在默认情况下，Liberty  已经启用了 JSP 功能，我们可以动态的根据应用的需求为 Liberty 增加各种功能支持，方法如下：</p><p>在 server.xml 编辑窗口下方，选择 Design 模式，</p><h5>图 7. 图形化编辑配置文件</h5><img alt="图 7. 图形化编辑配置文件" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image07.jpg" width="582" /><p>选择左侧 Feature Manager，然后选择右侧 Add，出现下图列表，根据需要添加相应的功能支持。</p><h5>图 8. Features 列表</h5><img alt="图 8. Features 列表" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image08.jpg" width="439" /><p>当 然，读者也可以直接手工编辑 server.xml，手动添加需要的 Feature，但是要注意遵循 Liberty  配置文件的编写规范。到此，我们已经成功的安装了 Liberty 服务器，并搭建好了 Liberty  服务器的开发环境。开始我们的例子程序之前，下文首先向读者更深层次的介绍 Liberty 的功能特性。</p><h3>简化服务器配置</h3><p>在  Liberty 中，和用户打交道的只有一个配置文件  server.xml。关于应用程序或者服务器运行时的所有配置都是在这一个文件中完成的，简化了服务器的配置，也减轻了程序员的负担。我们可以在  Eclipse 中直接编辑该文件，修改内容会实时生效。这个配置文件是可以被导出，也可以被不同的服务器共享。</p><h3>灵活的服务器配置</h3><h5>图 9. 灵活配置</h5><img alt="图 9. 灵活配置" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image09.jpg" width="511" /><p>对 于配置文件的使用是非常灵活的，例如：如果有很多个 Liberty  都需要用到同一个配置文件，那么可以将该文件单独导出，存放在一个共享的位置，单个的 Liberty 服务器可以利用 &lt;incluse  /&gt;  属性导入共享的配置文件；又比如配置文件的内容非常多而且繁杂，我们就可以将其中的内容分别写在不同的配置文件中（称为不同的配置文件片段），同样利用  &lt;include /&gt; 将这些片段文件导入到主配置文件中，运行时会负责去实时的解析这些片段文件。</p><h3>应用部署</h3><p>在 Liberty 中部署应用也是非常简单的事情，打开你的 Liberty 安装目录 &lt;Liberty_Install_dir&gt;\usr\servers\server_name ，可以看到如下目录结构 :</p><h5>图 10. 应用部署目录</h5><img alt="图 10. 应用部署目录" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image10.jpg" width="582" /><p>在 上图中 apps 和 dropins 是两个存放安装的应用的文件夹，我们可以通过 Eclipse 部署应用到 Liberty，应用文件将被放在  apps 下面（这个是应用部署的默认目录，也可以通过配置，将应用文件部署到其他任何位置）。我们也可以直接拷贝应用程序（例如 war 文件）到  dropins 目录，当 Liberty  启动的时候，就会自动扫描上面的两个文件夹，然后启动文件夹内的应用程序。当然，启动应用前，要确保已经配置好 server.xml 里的相关信息。</p><h3>动态加载模块</h3><h5>图 11. 动态化加载</h5><img alt="图 11. 动态化加载" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image11.jpg" width="582" /><p>与 传统 WAS 不同的是，Liberty  并不是一个静态的服务器，它是动态的，可以根据应用程序的需要动态加载相应的模块。这些模块是以&#8220;feature&#8221;来定义的，比如 JSP,  Servlet 等，都是不同的 feature。可以将 feature 看作是一个独立的模块，它由一到多个 OSGi bundle  组成，共同来完成某一个特定的任务。这些 feature 可是随时被添加和移除，而不需要重启服务器，正是得益于这样的动态化设计，Liberty  无论在启动时间还是反应时间上都更胜一筹，为程序员带来了快速的开发体验。</p><h3>运行时动态更新</h3><h5>图 12. 动态更新</h5><img alt="图 12. 动态更新" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image12.jpg" width="533" /><p>Liberty  为我们提供了一个可以动态实时更新的运行时，无论你是修改了应用程序，还是修改配置文件都会实时的被 Liberty  检测到，并立即更新运行时到最新状态，无需重启 Liberty 服务器。新的 feature 可以被随时的添加到 server.xml  中，运行时为负责实时启动相应的功能模块，这一切都与程序员来说都是透明的。例如：我们首先启动 Liberty 服务器，然后将一个 JSP 应用放到  dropins 目录里，如果你没有在 server.xml 中启动 JSP  功能，那么该应用就不会被启动。你将会得到一个警告信息，提示你应该首先启用 JSP 功能，然后该应用才会被实时的启动。同样，如果你将 JSP  功能从 server.xml 中移除，该应用也会被立刻停止。</p><h3>新型的软件部署方式</h3><h5>图 13. 集中管理 Liberty 服务器</h5><img alt="图 13. 集中管理 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image13.jpg" width="582" /><p>当 我们使用 Liberty 开发完应用程序后，Liberty 为我们提供了一个全新的软件部署方式，我们可以将 Liberty  服务器和应用程序一起打包为 ZIP 文件，然后将这个 ZIP  传输到需要部署软件的服务器上直接解压即可。为了支持适合云端和大规模应用的部署，WebSpere（传统  WAS）还提供了集中管理部署的功能（需要安装 WAS ND 版本），使用该功能可以将我们事先打好的 ZIP  包远程的传输到多个服务器上，在传送完成后，WAS 还会负责解压和安装。另外，WAS 的集中管理功能还提供了远程启动、停止和卸载 Liberty  服务器的功能。</p><h3>Liberty 之于开发人员</h3><p>对于开发人员来说，Liberty  的出现是一个十分振奋人心的消息。首先，Liberty 作为一个轻量级的应用服务器，和 Eclipse  可以完美的结合，其最重要的特性就是关注程序员的开发体验，包括快速的下载、安装和环境搭建，在开发过程中，实时的应用更新而无需重启服务器，这些都会极 大的提高程序员的开发效率；其次，在开发，测试和部署应用的过程中，Liberty 都极其友好和方便，其与传统 WAS  的完全兼容，也为应用程序的迁移提供了有力的保障。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>与主流 WEB 容器的对比</h2><p>从某种程度上来讲，目前，Liberty 与 Tomcat 处在同一个产品层次上，我们从功能特性、使用体验以及标准支持上对这两个服务器进行了对比，从中，我们可以看出 Liberty 在轻量级服务器中所具有的独特优势：</p><h5>表 1. Liberty VS Tomcat</h5><table summary="" border="0" cellpadding="0" cellspacing="0"><thead><tr><th><strong>对比项</strong></th><th><strong>Tomcat</strong></th><th><strong>Liberty</strong></th></tr></thead><tbody><tr><td>大小</td><td>&lt;30M</td><td>&lt;50M</td></tr><tr><td>启动速度</td><td>&lt;5s</td><td>&lt;5s</td></tr><tr><td>Java EE 标准支持</td><td>JSP 2.2, Servlet 3.0, JSTL 1.2 用户需要添加相关的 jar 包来实现对其它标准的支持</td><td>JSP  2.2, Servlet 3.0, JSF 2.0, JSTL 1.2, JPA 2.0, JDBC 4.0, JAX-RS 1.0,  JNDI 1.0, Bean Validation 1.0, SSL 1.0, Security 1.0, Web Security 1.0,  JMX 1.0 可动态加载或卸载对应的 feature</td></tr><tr><td>OSGi 编程模型</td><td>否</td><td>是，支持 Blue Print 1.0, WAB 1.0</td></tr><tr><td>开发工具</td><td>支持 Eclipse</td><td>支持 eclipse, IBM Rational Application Developer</td></tr><tr><td>支持的操作系统</td><td>Linux, Windows</td><td>Linux, Windows, AIX, Mac, HP-UX, Solaris, iSeries, zSeries</td></tr><tr><td>性能</td><td>一般</td><td>与传统 WAS 具有相同的核心代码，性能好</td></tr><tr><td>应用程序热部署</td><td>支持</td><td>支持</td></tr><tr><td>配置文件</td><td>多个配置文件，更新后需重启服务器</td><td>一个配置文件，更新后及时生效，无需重启</td></tr><tr><td>可移植性</td><td>您可以利用 IBM Application Migration Toolkit 将 Tomcat 上开发的应用快速移植到 WebSphere 应用服务器。反之，则不然。</td><td>Liberty 和传统 WAS 对编程模型和标准的支持一致。在 Liberty 上开发的应用可以直接运行在传统 WAS 之上</td></tr><tr><td>文档</td><td>官方文档涵盖内容有限，但网络上相关内容（包括：blog，技术文章等）广泛。</td><td>http://wasdev.net 上提供下载地址、文档、视频、音频、样本引用等。还有 WAS 的信息中心也有大量文档可供参考阅读。</td></tr><tr><td>社区</td><td>http://tomcat.apache.org 有 dev 和 user mailing list，没有官方支持，有时回复不够及时。</td><td>http://wasdev.net，可以与开发人员直接交流</td></tr><tr><td>长期战略优势</td><td>一般用于开发环境，生产环产能用的比较少。支持的并发度不高，可扩展性不强。</td><td>  Liberty 与传统 WAS 共享同一代码，天生具有其高效稳定的特点。开发 - 测试 - 生产切换零代价。可扩展性高，支持多个 server 间的负载均衡和故障恢复。 </td></tr></tbody></table><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>Demo：使用 Eclipse 和 Liberty 开发 Web 应用</h2><p>通 过上面的介绍，相信大家对 Liberty 已经有了一个大概的认识，接下来我们通过一个 Demo 来向大家展示如何使用 Liberty 和  Eclipse 开发 Web 应用。开始 Demo 之前，请大家根据上文的介绍，搭建自己的 Liberty 开发环境，并安装好 JDK  并且配置好环境变量。</p><p>Demo 程序很简单，包含一个 Servlet，实现打印当前时间的功能。步骤如下：</p><ol type="1"><li>打开 Eclipse，选择 File &gt; New &gt; Web&gt;Dynamic Web Project</li><li>设置如下属性值： 				  <ol type="a"><li>Project name: Demo</li><li>Target runtime: WebSphere Application Server V8.5 Liberty Profile</li></ol><h5>图 14. 创建动态 Web 工程</h5><img alt="图 14. 创建动态 Web 工程" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image14.jpg" width="495" /></li><li>点击 Next 两次，然后点击 Finish，完成工程的创建。 			  <p>此时，你可以在左侧的资源导航页面看到刚刚创建完成的 Demo 工程，展开工程就可以看到一些默认创建的资源。</p></li><li>右击 Src 目录，选择 New &gt; Class</li><li>设置如下属性值： 				  <ol type="a"><li>Package: com.date.demo</li><li>Name: DateProvider</li></ol><h5>图 15. 创建 java 文件</h5><img alt="图 15. 创建 java 文件" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image15.jpg" width="490" /></li><li>点击 Finish</li><li>编辑如下代码到 DateProvider.java  			  <h5>清单 3. DateProvider.java</h5><div><pre> package com.date.demo;    import java.util.Date;    public class DateProvider {    public String getDate() {   // TODO Auto-generated method stub   return new Date().toString();   }   }</pre></div><p>该文件只包含一个方法，getDate() 用来获得当前时间。</p></li><li>右击 Src，选择 New &gt; Servlet</li><li>设置如下属性值  				  <ol type="a"><li>Java package: com.date.demo</li><li>Class name: DatePrintServlet</li></ol><h5>图 16. 创建 Servlet 文件</h5><img alt="图 16. 创建 Servlet 文件" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image16.jpg" width="494" /></li><li>点击 Finish，完成创建。</li><li>编辑如下内容到 DatePrintServlet.java  			  <h5>清单 4. DatePrintServlet.java</h5><div><pre> package com.date.demo;    import java.io.IOException;   import javax.servlet.ServletException;   import javax.servlet.annotation.WebServlet;   import javax.servlet.http.HttpServlet;   import javax.servlet.http.HttpServletRequest;   import javax.servlet.http.HttpServletResponse;    /**   * Servlet implementation class DatePrintServlet   */   @WebServlet("/DatePrintServlet")   public class DatePrintServlet extends HttpServlet {   private static final long serialVersionUID = 1L;            /**       * @see HttpServlet#HttpServlet()       */      public DatePrintServlet() {          super();          // TODO Auto-generated constructor stub      }   /**   * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)   */   protected void doGet(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {   // TODO Auto-generated method stub   DateProvider dateProvider=new DateProvider();   response.getWriter().println(dateProvider.getDate());   }    /**   * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)   */   protected void doPost(HttpServletRequest request, HttpServletResponse response)   throws ServletException, IOException {   // TODO Auto-generated method stub   }    }</pre></div></li><li>在左侧导航栏选择 DatePrintServlet，点击右键 Run As &gt; Run on Server , 如下图： 			 <h5>图 17. 选择 Liberty 服务器</h5><img alt="图 17. 选择 Liberty 服务器" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image17.jpg" width="553" /></li><li>点击 Finish，Liberty 开发工具将会为我们部署上面的 Demo 程序，并启动 Liberty 服务器。从 console 的日志里我们可以看到如下描述：</li></ol><p>[AUDIT   ] CWWKZ0001I: Application Demo started in 1.235 seconds.</p><p>表明 Demo 应用已经成功部署了，同时，在 Eclipse 自带的浏览器里可以看到如下页面信息：</p><h5>图 18. Demo 运行页面</h5><img alt="图 18. Demo 运行页面" src="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/images/image18.jpg" width="580" /><p>让我们回过头来看看 server.xml 里面的内容：</p><h5>清单 5. server.xml</h5><div><pre> &lt;server description="new server"&gt;       &lt;!-- Enable features --&gt;      &lt;featureManager&gt;          &lt;feature&gt;jsp-2.2&lt;/feature&gt;          &lt;feature&gt;localConnector-1.0&lt;/feature&gt;       &lt;/featureManager&gt;       &lt;httpEndpoint host="localhost" httpPort="9080" httpsPort="9443"      id="defaultHttpEndpoint"/&gt;       &lt;applicationMonitor updateTrigger="mbean"/&gt;       &lt;application id="Demo" location="Demo.war" name="Demo" type="war"/&gt;   &lt;/server&gt;</pre></div><p>其中：</p><p>&lt;feature /&gt; 包含了应用程序中所用到的功能包，如果你启用了 jsp-2.2，那么 Liberty 默认支持对 Servlet 3.0。</p><p>&lt;httpEndpoint /&gt; 指定了 HTTP 访问的端口，我们可以在这里改变默认的端口。</p><p>&lt;applicationMonitor  /&gt; 用来配置对应用程序的监控模式，updateTrigger 属性是用来控制动态更新的，通过 Liberty 工具部署应用时  updateTrigger 的值设置为 mbean，当我们直接把应用程序拖进 dropins 时，需要将 updateTrigger 设为  polled，当然，如果我们不需要应用的动态更新功能，可以将这个值设为 disabled.</p><p>&lt;application /&gt; 用来指定和应用本身相关的属性，id 和 name 是应用的唯一标识，type 指定了应用的类型，location 指定应用所在的位置，默认是在 apps 目录里面，我们可以通过配置修改这个默认设置。</p><p ibm-back-to-top"=""><a href="http://www.ibm.com/developerworks/cn/websphere/library/techarticles/1207_zhuxl_liberty/1207_zhuxl_liberty.html#ibm-pcon">回页首</a></p><h2>总结</h2><p>通 过上面的介绍，相信读者已经对 WAS V8.5 最重要的特性 Liberty 有了一个全面的认识，作为新一代轻量级应用服务器，Liberty  采用了和传统 WAS 相同的代码，继承了传统 WAS 的优点，无论在性能上还是在稳定性上都优越于其他同类产品。Liberty  无论是在开发环境中还是在产品环境中，都具有其他产品不可比拟的优势。我们有理由相信，在追求开发效率和软件质量的今天，每一个程序员都会很快的接受这个  WAS 家族的&#8220;小块头&#8221;。</p>   </div> </div>         <h2>参考资料 </h2><h3>学习</h3><ul><li> 			访问 <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp">WebSphere Application Server V8.5 信息中心</a> 了解更多关于 WAS 的信息。             </li><li> 			访问 <a href="http://wasdev.net/">wasdev.net 主页</a> 学习更多 Liberty 的知识，并直接和开发人员进行交流。            </li><li> 			访问 <a href="http://publib.boulder.ibm.com/infocenter/radhelp/v8r5/index.jsp">WebSphere Developer Tools V8.5 信息中心</a> 学习更多 WDT 的知识。            </li><li><a href="http://www.ibm.com/developerworks/cn/websphere/">IBM developerWorks 中国 WebSphere 专区</a>：为使用 WebSphere 产品的开发人员准备的技术信息和资料。这里提供产品下载、how-to 信息、支持资源以及免费技术库，包含 2000 多份技术文章、教程、最佳实践、IBM Redbook 和在线产品手册。</li></ul><h3>获得产品和技术</h3><ul><li><a href="http://www.ibm.com/developerworks/cn/websphere/downloads/"> 最受欢迎的 WebSphere 试用软件下载</a>：下载关键 WebSphere 产品的免费试用版。</li><li><a href="http://www.ibm.com/developerworks/cn/downloads/">IBM developerWorks 软件下载资源中心</a>：IBM deveperWorks 最新的软件下载。</li><li><a href="http://www.ibm.com/developerworks/cn/offers/kits/">IBM developerWorks 工具包</a>：下载关键 WebSphere 最新的产品工具包。</li></ul></div><img src ="http://www.blogjava.net/longturi/aggbug/408781.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-01-10 18:31 <a href="http://www.blogjava.net/longturi/archive/2014/01/10/408781.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>WebSphere Application Server V8.5 常见问题及解答</title><link>http://www.blogjava.net/longturi/archive/2014/01/10/408761.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 10 Jan 2014 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2014/01/10/408761.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/408761.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2014/01/10/408761.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/408761.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/408761.html</trackback:ping><description><![CDATA[<div><div> <p>WebSphere Application Server V8.5 的最重要的新特性是新的 Liberty Profile                             以及智能管理。本 FAQ 为您汇集了关于 WAS V8.5 的问题集锦，从智能管理、 Liberty                             Profile、性能等方面帮助您解答您使用过程中可能遇到的问题。</p><h2>Liberty 和                             tWAS是两个产品吗？目前 tWAS和 Liberty 所支持的功能有什么不同？</h2><p>Liberty 作为 WAS V8.5 发布的一部分，和 tWAS 作为两个单独的介质供用户使用。在功能上 Liberty 是                             tWAS 的一个子集。tWAS 是一个完整的 J2EE 服务器，支持 J2EE 规范，而 liberty 目前只支持                             Web, OSGi 和 Mobile 应用的开发。</p><h2>Liberty                             是如何提供给用户的？是以插件的形式吗？</h2><p>Liberty 是以一个单独的运行时环境提供给用户的。用户下载 Liberty                             的安装介质后解压缩即可作为运行时环境部署应用。同时 Liberty 可以很好的跟开发工具如 Eclipse、RAD                             等结合使用，有很好的开发者体验。</p><h2>Liberty                             有哪些优点？</h2><ol type="1"><li>简单安装（可以通过 IM 进行安装，或者直接下载免安装版本）</li><li>快速启动</li><li>灵活的配置（只需要在 server.xml 文件里面进行配置即可）</li><li>实时更新（采用 OSGi 架构，server 不需重启，更改即可生效）</li><li>动态加载，Liberty                                 对所支持的功能特性实施动态加载的机制，即当使用某些特性的时候才将该特性相关的类加载的运行时当中。</li></ol><h2>Liberty                             是否支持文件夹形式的 bundle 应用？</h2><p>Liberty 目前不支持文件夹形式的 bundle 应用，但是支持将 EBA 格式的 OSGi                             应用解压安装，应用名称的格式应为 xxx.eba。</p><h2> Liberty                             采用动态加载的方式，那么当新添加特性时，Liberty 服务器是否会重启？</h2><p>当添加新的功能特性时，功能特性动态生效，Liberty 服务器不会被自动重启。</p><h2>在 Liberty                             上开发的应用能直接迁移到 tWAS 上进行使用吗？需要做什么修改吗？</h2><p>用 Liberty 开发的应用可以无缝地迁移到 tWAS 上面，不需要对应用进行修改，只需要在 tWAS                             对数据源等应用所需要的资源做相应的设置即可。</p><h2>Liberty                             上部署应用有两种方式，即 Monitored Directory 和                             Configuration，两种方式有什么不同？</h2><p>通过 Monitored Directory 的方式，用户只需把应用放在特定目录下面，Liberty                             会自动去检查到该应用，然后自动帮助用户进行安装。</p><p>而通过 Configuration 的方式，Liberty 不会自动去进行安装，用户需要手动去进行安装，比如通过命令行或者                             Eclipse 开发平台。</p><h2>相比较与                             Tomcat，开发者选择 Liberty 的原因将会是什么？ Liberty 会带来哪些新体验 ?</h2><table border="0" cellpadding="0" cellspacing="0"><caption>内容</caption><thead><tr><th>对比项</th><th>Tomcat</th><th>Liberty</th></tr></thead><tbody><tr><td>Java EE 标准支持</td><td>JSP 2.2, Servlet 3.0, JSTL 1.2<br />用户需要添加相关的 jar                                         包来实现对其它标准的支持</td><td>JSP 2.2, Servlet 3.0, JSF 2.0, JSTL 1.2, JPA 2.0,                                         JDBC 4.0, JAX-RS 1.0, JNDI 1.0, Bean Validation                                         1.0, SSL 1.0, Security 1.0, Web Security 1.0, JMX                                         1.0<br />可动态加载或卸载对应的特性包</td></tr><tr><td>OSGi 编程模型支持</td><td>否</td><td>是，支持 Blue Print 1.0, WAB 1.0</td></tr><tr><td>开发工具</td><td>支持 Eclipse</td><td>支持 Eclipse, IBM Rational Application Developer                                     </td></tr><tr><td>性能</td><td>一般</td><td>与传统 WAS 具有相同的核心代码，性能好</td></tr><tr><td>支持的操作系统</td><td>Linux, Windows</td><td>Linux, Windows, AIX, Mac, HP-UX, Solaris, iSeries,                                         zSeries</td></tr><tr><td>配置文件</td><td>多个配置文件，更新后需重启服务器</td><td>一个配置文件，更新后及时生效，无需重启</td></tr><tr><td>可移植性</td><td>您可以利用 IBM Application Migration Toolkit 将 Tomcat                                         上开发的应用快速移植到 WebSphere 应用服务器。反之，则不然。</td><td>Liberty 和传统 WAS 对编程模型和标准的支持一致。在 Liberty                                         上开发的应用可以直接运行在传统 WAS 之上。</td></tr><tr><td>社区</td><td><a href="http://tomcat.apache.org/">http://tomcat.apache.org</a><br />                                         有开发人员和用户的邮件列表，没有官方支持，有时回复不够及时。</td><td><a href="http://wasdev.net/">http://wasdev.net</a>，可以与开发人员直接交流</td></tr><tr><td>文档</td><td>官方文档涵盖内容有限，但网络上相关内容（包括：blog，技术文章等）广泛。</td><td><a href="http://wasdev.net/">http://wasdev.net</a>                                         上提供下载地址、文档、视频、音频、样本引用等。</td></tr><tr><td>长期战略优势</td><td>一般用于开发环境，生产环产应用的比较少。<br /> 支持的并发度不高，可扩展性不强。</td><td>Liberty 与传统 WAS 共享同一代码，天生具有其高效稳定的特点。开发 - 测试 -                                         生产切换零代价。<br />可扩展性高，支持多个 server 间的负载均衡和故障恢复。</td></tr></tbody></table><h2>Liberty                             高速缓冲可以由 eXtreme Scale 提供吗？</h2><p>可以，Liberty 可以和 eXtreme Scale 进行集成带来高速缓存的特性。</p><h2> Liberty                             支持 IBM iSeries 吗？</h2><p>支持，在 IBM iSeries 上的使用和在其他平台上相同。</p><h2>用户可以在                             Eclipse 中管理 Liberty 吗？比如启动和停止？</h2><p>可以，在 Eclipse 控制台的 Servers 标签中，展开您的 Liberty                             下拉列表，会显示出当前部署在该应用服务器上的全部应用，右击某一应用，可以进行相关的启 / 停 / 移除操作，参见截图</p><img src="http://www.ibm.com/developerworks/cn/websphere/zones/faqs/was85faqs/images/image01.jpg" alt="图 1 . Servers 控制" height="203" width="500" /><p>但是在运行时环境里面，暂时不支持启动和停止某一个特定的应用。</p><h2>Liberty 能在                             mobile 的设备上做开发（比如 ipad）吗？</h2><p>目前不支持这样做，但是 Liberty 支持在 MAC 系统上进行开发。</p><h2>Liberty                             是如何自动添加所需的功能特性的？</h2><p>在开发环境，即 Eclipse+WDT+Liberty runtime 时，Liberty                             可以自动为应用添加所需的特性。此功能是 WDT                             来实现的，其会自动扫描应用，判断应用所采用的编程模型，然后为应用添加相应的功能支持。</p><p>如果直接使用 Liberty runtime 部署应用，Liberty 是不会自动为应用添加所需的特性的。</p><h2>Liberty                             如何处理不同的应用 /server 的端口冲突？</h2><p>通过在 Liberty 的运行时环境下面的 bootstrap.properties 和 server.xml                             两个文件进行相应的配置，该项配置需要重启 Liberty。参考 <a href="http://pic.dhe.ibm.com/infocenter/wasinfo/v8r5/index.jsp?topic=%2Fcom.ibm.websphere.wlp.nd.multiplatform.doc%2Ftopics%2Ftwlp_inst_bootstrap.html&amp;resultof%3D%2522%2562%256f%256f%2574%2573%2574%2572%2561%2570%252e%2570%2572%256f%2570%2565%2572%2574%2569%2565%2573%2522%2520">信息中心</a>进行配置。</p><h2>除了 Liberty                             之外，还有其他产品是基于 OSGi 架构的？</h2><p>Liberty 是完全基于 OSGi 的产品，其在构建中完全遵循了 OSGi                             的编程模型规范。在应用服务器领域暂时还没有发现其他的产品也完全采用 OSGi 的编程模型进行构建。</p><h2>当启用某个                             Liberty 的特性时，Liberty 是及时动态的加载属于该特性的 JAR 包，还是在 Liberty                             启动的时候就已经加载，只是此时才开始使用？</h2><p>一般来说，根据 bundle 的 Bundle-ActivationPolicy 值来确定是立刻启动 bundle                             还是按需启动 bundle（lazy）。但是在 Liberty 中，大多数 bundle 都没有设定这个值，默认的行为就是当                             Liberty 启动的时候 bundle 会被立即启动，但是，我们需要说明的是：</p><ol type="1"><li>liberty 中对于 bundle 的使用采用的 DS 的方式（声明服务），bundle 与 bundle                                 之间是通过服务的调用来实现的，只有当去主动请求一个服务时，该服务的 bundle                                 提供者才会被加载，所以，当采用服务的管理模式后，我们并不需要特别在意 bundle 的加载方式。</li><li>在 liberty 中，只有很少的 bundle 设定了 Bundle-ActivationPolicy                                 值，此刻，这些 bundle 会根据值的设定选择立刻或者按需启动。</li></ol> </div></div><img src ="http://www.blogjava.net/longturi/aggbug/408761.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2014-01-10 11:31 <a href="http://www.blogjava.net/longturi/archive/2014/01/10/408761.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>dom4j解析xml字符串实例</title><link>http://www.blogjava.net/longturi/archive/2013/11/22/406702.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 22 Nov 2013 13:00:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/11/22/406702.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/406702.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/11/22/406702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/406702.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/406702.html</trackback:ping><description><![CDATA[来自：<div>http://www.cnblogs.com/macula/archive/2011/07/27/2118003.html</div><br /><div><span style="font-family: 微软雅黑; font-size: medium;"><strong>DOM4J</strong></span> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">&nbsp; &nbsp;  与利用DOM、SAX、JAXP机制来解析xml相比，DOM4J  表现更优秀，具有性能优异、功能强大和极端易用使用的特点，只要懂得DOM基本概念，就可以通过dom4j的api文档来解析xml。dom4j是一套开 源的api。实际项目中，往往选择dom4j来作为解析xml的利器。</span></p> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">先来看看dom4j中对应XML的DOM树建立的继承关系</span></p> <p><span style="font-family: 微软雅黑; font-size: small;">&nbsp;<img src="http://images.cnblogs.com/cnblogs_com/macula/430750/r_bbb.png" alt="" height="352" width="536" /></span>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">针对于XML标准定义，对应于图2-1列出的内容，dom4j提供了以下实现：</span></p> <p><span style="font-family: 微软雅黑; font-size: small;">&nbsp;<img src="http://images.cnblogs.com/cnblogs_com/macula/430750/r_ccc.jpg" alt="" height="362" width="535" /></span>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">同时，dom4j的NodeType枚举实现了XML规范中定义的node类型。如此可以在遍历xml文档的时候通过常量来判断节点类型了。</span></p> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;"><strong>常用API</strong></span></p> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">class org.dom4j.io.SAXReader</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">read&nbsp; 提供多种读取xml文件的方式，返回一个Domcument对象 </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.Document</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">iterator&nbsp; 使用此法获取node </span></li><li><span style="font-family: 微软雅黑; font-size: small;">getRootElement&nbsp; 获取根节点 </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.Node </span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">getName&nbsp; 获取node名字，例如获取根节点名称为bookstore </span></li><li><span style="font-family: 微软雅黑; font-size: small;">getNodeType&nbsp; 获取node类型常量值，例如获取到bookstore类型为1&#8212;&#8212;Element </span></li><li><span style="font-family: 微软雅黑; font-size: small;">getNodeTypeName&nbsp; 获取node类型名称，例如获取到的bookstore类型名称为Element </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.Element</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">attributes&nbsp; 返回该元素的属性列表 </span></li><li><span style="font-family: 微软雅黑; font-size: small;">attributeValue&nbsp; 根据传入的属性名获取属性值 </span></li><li><span style="font-family: 微软雅黑; font-size: small;">elementIterator&nbsp; 返回包含子元素的迭代器 </span></li><li><span style="font-family: 微软雅黑; font-size: small;">elements&nbsp; 返回包含子元素的列表 </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.Attribute</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">getName&nbsp; 获取属性名 </span></li><li><span style="font-family: 微软雅黑; font-size: small;">getValue&nbsp; 获取属性值 </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.Text</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">getText&nbsp; 获取Text节点值 </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.CDATA</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">getText&nbsp; 获取CDATA Section值 </span></li></ul> <p>&nbsp;</p> <p><span style="font-family: 微软雅黑; font-size: small;">interface org.dom4j.Comment</span></p> <p>&nbsp;</p> <ul><li><span style="font-family: 微软雅黑; font-size: small;">getText&nbsp; 获取注释&nbsp;</span></li></ul> <p><span style="font-family: 微软雅黑; font-size: small;">&nbsp;</span></p> <p>&nbsp;</p> <p>实例一：</p> <div><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div> <pre><span style="color: #008080;">  1</span> <span style="color: #008000;">//</span><span style="color: #008000;">先加入dom4j.jar包 </span> <span style="color: #008080;">  2</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.HashMap; </span><span style="color: #008080;">  3</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.Iterator; </span><span style="color: #008080;">  4</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> java.util.Map; </span><span style="color: #008080;">  5</span>  <span style="color: #008080;">  6</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> org.dom4j.Document; </span><span style="color: #008080;">  7</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> org.dom4j.DocumentException; </span><span style="color: #008080;">  8</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> org.dom4j.DocumentHelper; </span><span style="color: #008080;">  9</span> <span style="color: #0000ff;">import</span><span style="color: #000000;"> org.dom4j.Element; </span><span style="color: #008080;"> 10</span>  <span style="color: #008080;"> 11</span> <span style="color: #008000;">/**</span>    <span style="color: #008080;"> 12</span> <span style="color: #008000;">* @Title: TestDom4j.java </span><span style="color: #008080;"> 13</span> <span style="color: #008000;">* @Package  </span><span style="color: #008080;"> 14</span> <span style="color: #008000;">* @Description: 解析xml字符串 </span><span style="color: #008080;"> 15</span> <span style="color: #008000;">* </span><span style="color: #808080;">@author</span><span style="color: #008000;"> 无处不在 </span><span style="color: #008080;"> 16</span> <span style="color: #008000;">* @date 2012-11-20 下午05:14:05 </span><span style="color: #008080;"> 17</span> <span style="color: #008000;">* </span><span style="color: #808080;">@version</span><span style="color: #008000;"> V1.0    </span><span style="color: #008080;"> 18</span> <span style="color: #008000;">*/</span> <span style="color: #008080;"> 19</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> TestDom4j { </span><span style="color: #008080;"> 20</span>  <span style="color: #008080;"> 21</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> readStringXml(String xml) { </span><span style="color: #008080;"> 22</span>         Document doc = <span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #008080;"> 23</span>         <span style="color: #0000ff;">try</span><span style="color: #000000;"> { </span><span style="color: #008080;"> 24</span>  <span style="color: #008080;"> 25</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 读取并解析XML文档 </span><span style="color: #008080;"> 26</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> SAXReader就是一个管道，用一个流的方式，把xml文件读出来 </span><span style="color: #008080;"> 27</span>             <span style="color: #008000;">//</span>  <span style="color: #008080;"> 28</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> SAXReader reader = new SAXReader(); </span><span style="color: #008000;">//</span><span style="color: #008000;">User.hbm.xml表示你要解析的xml文档 </span><span style="color: #008080;"> 29</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> Document document = reader.read(new File("User.hbm.xml")); </span><span style="color: #008080;"> 30</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 下面的是通过解析xml字符串的</span> <span style="color: #008080;"> 31</span>             doc = DocumentHelper.parseText(xml); <span style="color: #008000;">//</span><span style="color: #008000;"> 将字符串转为XML</span> <span style="color: #008080;"> 32</span>  <span style="color: #008080;"> 33</span>             Element rootElt = doc.getRootElement(); <span style="color: #008000;">//</span><span style="color: #008000;"> 获取根节点</span> <span style="color: #008080;"> 34</span>             System.out.println("根节点：" + rootElt.getName()); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到根节点的名称</span> <span style="color: #008080;"> 35</span>  <span style="color: #008080;"> 36</span>             Iterator iter = rootElt.elementIterator("head"); <span style="color: #008000;">//</span><span style="color: #008000;"> 获取根节点下的子节点head </span><span style="color: #008080;"> 37</span>  <span style="color: #008080;"> 38</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历head节点</span> <span style="color: #008080;"> 39</span>             <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iter.hasNext()) { </span><span style="color: #008080;"> 40</span>  <span style="color: #008080;"> 41</span>                 Element recordEle =<span style="color: #000000;"> (Element) iter.next(); </span><span style="color: #008080;"> 42</span>                 String title = recordEle.elementTextTrim("title"); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到head节点下的子节点title值</span> <span style="color: #008080;"> 43</span>                 System.out.println("title:" +<span style="color: #000000;"> title); </span><span style="color: #008080;"> 44</span>  <span style="color: #008080;"> 45</span>                 Iterator iters = recordEle.elementIterator("script"); <span style="color: #008000;">//</span><span style="color: #008000;"> 获取子节点head下的子节点script </span><span style="color: #008080;"> 46</span>  <span style="color: #008080;"> 47</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历Header节点下的Response节点</span> <span style="color: #008080;"> 48</span>                 <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iters.hasNext()) { </span><span style="color: #008080;"> 49</span>  <span style="color: #008080;"> 50</span>                     Element itemEle =<span style="color: #000000;"> (Element) iters.next(); </span><span style="color: #008080;"> 51</span>  <span style="color: #008080;"> 52</span>                     String username = itemEle.elementTextTrim("username"); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到head下的子节点script下的字节点username的值</span> <span style="color: #008080;"> 53</span>                     String password = itemEle.elementTextTrim("password"<span style="color: #000000;">); </span><span style="color: #008080;"> 54</span>  <span style="color: #008080;"> 55</span>                     System.out.println("username:" +<span style="color: #000000;"> username); </span><span style="color: #008080;"> 56</span>                     System.out.println("password:" +<span style="color: #000000;"> password); </span><span style="color: #008080;"> 57</span> <span style="color: #000000;">                } </span><span style="color: #008080;"> 58</span> <span style="color: #000000;">            } </span><span style="color: #008080;"> 59</span>             Iterator iterss = rootElt.elementIterator("body"); <span style="color: #008000;">//</span><span style="color: #008000;">/获取根节点下的子节点body </span><span style="color: #008080;"> 60</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历body节点</span> <span style="color: #008080;"> 61</span>             <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iterss.hasNext()) { </span><span style="color: #008080;"> 62</span>  <span style="color: #008080;"> 63</span>                 Element recordEless =<span style="color: #000000;"> (Element) iterss.next(); </span><span style="color: #008080;"> 64</span>                 String result = recordEless.elementTextTrim("result"); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到body节点下的子节点result值</span> <span style="color: #008080;"> 65</span>                 System.out.println("result:" +<span style="color: #000000;"> result); </span><span style="color: #008080;"> 66</span>  <span style="color: #008080;"> 67</span>                 Iterator itersElIterator = recordEless.elementIterator("form"); <span style="color: #008000;">//</span><span style="color: #008000;"> 获取子节点body下的子节点form </span><span style="color: #008080;"> 68</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历Header节点下的Response节点</span> <span style="color: #008080;"> 69</span>                 <span style="color: #0000ff;">while</span><span style="color: #000000;"> (itersElIterator.hasNext()) { </span><span style="color: #008080;"> 70</span>  <span style="color: #008080;"> 71</span>                     Element itemEle =<span style="color: #000000;"> (Element) itersElIterator.next(); </span><span style="color: #008080;"> 72</span>  <span style="color: #008080;"> 73</span>                     String banlce = itemEle.elementTextTrim("banlce"); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到body下的子节点form下的字节点banlce的值</span> <span style="color: #008080;"> 74</span>                     String subID = itemEle.elementTextTrim("subID"<span style="color: #000000;">); </span><span style="color: #008080;"> 75</span>  <span style="color: #008080;"> 76</span>                     System.out.println("banlce:" +<span style="color: #000000;"> banlce); </span><span style="color: #008080;"> 77</span>                     System.out.println("subID:" +<span style="color: #000000;"> subID); </span><span style="color: #008080;"> 78</span> <span style="color: #000000;">                } </span><span style="color: #008080;"> 79</span> <span style="color: #000000;">            } </span><span style="color: #008080;"> 80</span>         } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (DocumentException e) { </span><span style="color: #008080;"> 81</span> <span style="color: #000000;">            e.printStackTrace(); </span><span style="color: #008080;"> 82</span>  <span style="color: #008080;"> 83</span>         } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) { </span><span style="color: #008080;"> 84</span> <span style="color: #000000;">            e.printStackTrace(); </span><span style="color: #008080;"> 85</span>  <span style="color: #008080;"> 86</span> <span style="color: #000000;">        } </span><span style="color: #008080;"> 87</span> <span style="color: #000000;">    } </span><span style="color: #008080;"> 88</span>  <span style="color: #008080;"> 89</span>     <span style="color: #008000;">/**</span> <span style="color: #008080;"> 90</span> <span style="color: #008000;">     * @description 将xml字符串转换成map </span><span style="color: #008080;"> 91</span> <span style="color: #008000;">     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> xml </span><span style="color: #008080;"> 92</span> <span style="color: #008000;">     * </span><span style="color: #808080;">@return</span><span style="color: #008000;"> Map </span><span style="color: #008080;"> 93</span>      <span style="color: #008000;">*/</span> <span style="color: #008080;"> 94</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span><span style="color: #000000;"> Map readStringXmlOut(String xml) { </span><span style="color: #008080;"> 95</span>         Map map = <span style="color: #0000ff;">new</span><span style="color: #000000;"> HashMap(); </span><span style="color: #008080;"> 96</span>         Document doc = <span style="color: #0000ff;">null</span><span style="color: #000000;">; </span><span style="color: #008080;"> 97</span>         <span style="color: #0000ff;">try</span><span style="color: #000000;"> { </span><span style="color: #008080;"> 98</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 将字符串转为XML</span> <span style="color: #008080;"> 99</span>             doc =<span style="color: #000000;"> DocumentHelper.parseText(xml);  </span><span style="color: #008080;">100</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 获取根节点</span> <span style="color: #008080;">101</span>             Element rootElt =<span style="color: #000000;"> doc.getRootElement();  </span><span style="color: #008080;">102</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到根节点的名称</span> <span style="color: #008080;">103</span>             System.out.println("根节点：" +<span style="color: #000000;"> rootElt.getName());  </span><span style="color: #008080;">104</span>  <span style="color: #008080;">105</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 获取根节点下的子节点head</span> <span style="color: #008080;">106</span>             Iterator iter = rootElt.elementIterator("head"<span style="color: #000000;">);  </span><span style="color: #008080;">107</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历head节点</span> <span style="color: #008080;">108</span>             <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iter.hasNext()) { </span><span style="color: #008080;">109</span>  <span style="color: #008080;">110</span>                 Element recordEle =<span style="color: #000000;"> (Element) iter.next(); </span><span style="color: #008080;">111</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到head节点下的子节点title值</span> <span style="color: #008080;">112</span>                 String title = recordEle.elementTextTrim("title"<span style="color: #000000;">);  </span><span style="color: #008080;">113</span>                 System.out.println("title:" +<span style="color: #000000;"> title); </span><span style="color: #008080;">114</span>                 map.put("title"<span style="color: #000000;">, title); </span><span style="color: #008080;">115</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 获取子节点head下的子节点script</span> <span style="color: #008080;">116</span>                 Iterator iters = recordEle.elementIterator("script"<span style="color: #000000;">);  </span><span style="color: #008080;">117</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历Header节点下的Response节点</span> <span style="color: #008080;">118</span>                 <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iters.hasNext()) { </span><span style="color: #008080;">119</span>                     Element itemEle =<span style="color: #000000;"> (Element) iters.next(); </span><span style="color: #008080;">120</span>                     <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到head下的子节点script下的字节点username的值</span> <span style="color: #008080;">121</span>                     String username = itemEle.elementTextTrim("username"<span style="color: #000000;">);  </span><span style="color: #008080;">122</span>                     String password = itemEle.elementTextTrim("password"<span style="color: #000000;">); </span><span style="color: #008080;">123</span>  <span style="color: #008080;">124</span>                     System.out.println("username:" +<span style="color: #000000;"> username); </span><span style="color: #008080;">125</span>                     System.out.println("password:" +<span style="color: #000000;"> password); </span><span style="color: #008080;">126</span>                     map.put("username"<span style="color: #000000;">, username); </span><span style="color: #008080;">127</span>                     map.put("password"<span style="color: #000000;">, password); </span><span style="color: #008080;">128</span> <span style="color: #000000;">                } </span><span style="color: #008080;">129</span> <span style="color: #000000;">            } </span><span style="color: #008080;">130</span>  <span style="color: #008080;">131</span>             <span style="color: #008000;">//</span><span style="color: #008000;">获取根节点下的子节点body</span> <span style="color: #008080;">132</span>             Iterator iterss = rootElt.elementIterator("body"<span style="color: #000000;">);  </span><span style="color: #008080;">133</span>             <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历body节点</span> <span style="color: #008080;">134</span>             <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iterss.hasNext()) { </span><span style="color: #008080;">135</span>                 Element recordEless =<span style="color: #000000;"> (Element) iterss.next(); </span><span style="color: #008080;">136</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到body节点下的子节点result值</span> <span style="color: #008080;">137</span>                 String result = recordEless.elementTextTrim("result"<span style="color: #000000;">);  </span><span style="color: #008080;">138</span>                 System.out.println("result:" +<span style="color: #000000;"> result); </span><span style="color: #008080;">139</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 获取子节点body下的子节点form</span> <span style="color: #008080;">140</span>                 Iterator itersElIterator = recordEless.elementIterator("form"<span style="color: #000000;">);  </span><span style="color: #008080;">141</span>                 <span style="color: #008000;">//</span><span style="color: #008000;"> 遍历Header节点下的Response节点</span> <span style="color: #008080;">142</span>                 <span style="color: #0000ff;">while</span><span style="color: #000000;"> (itersElIterator.hasNext()) { </span><span style="color: #008080;">143</span>                     Element itemEle =<span style="color: #000000;"> (Element) itersElIterator.next(); </span><span style="color: #008080;">144</span>                     <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到body下的子节点form下的字节点banlce的值</span> <span style="color: #008080;">145</span>                     String banlce = itemEle.elementTextTrim("banlce"<span style="color: #000000;">);  </span><span style="color: #008080;">146</span>                     String subID = itemEle.elementTextTrim("subID"<span style="color: #000000;">); </span><span style="color: #008080;">147</span>  <span style="color: #008080;">148</span>                     System.out.println("banlce:" +<span style="color: #000000;"> banlce); </span><span style="color: #008080;">149</span>                     System.out.println("subID:" +<span style="color: #000000;"> subID); </span><span style="color: #008080;">150</span>                     map.put("result"<span style="color: #000000;">, result); </span><span style="color: #008080;">151</span>                     map.put("banlce"<span style="color: #000000;">, banlce); </span><span style="color: #008080;">152</span>                     map.put("subID"<span style="color: #000000;">, subID); </span><span style="color: #008080;">153</span> <span style="color: #000000;">                } </span><span style="color: #008080;">154</span> <span style="color: #000000;">            } </span><span style="color: #008080;">155</span>         } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (DocumentException e) { </span><span style="color: #008080;">156</span> <span style="color: #000000;">            e.printStackTrace(); </span><span style="color: #008080;">157</span>         } <span style="color: #0000ff;">catch</span><span style="color: #000000;"> (Exception e) { </span><span style="color: #008080;">158</span> <span style="color: #000000;">            e.printStackTrace(); </span><span style="color: #008080;">159</span> <span style="color: #000000;">        } </span><span style="color: #008080;">160</span>         <span style="color: #0000ff;">return</span><span style="color: #000000;"> map; </span><span style="color: #008080;">161</span> <span style="color: #000000;">    } </span><span style="color: #008080;">162</span>  <span style="color: #008080;">163</span>     <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) { </span><span style="color: #008080;">164</span>  <span style="color: #008080;">165</span>         <span style="color: #008000;">//</span><span style="color: #008000;"> 下面是需要解析的xml字符串例子</span> <span style="color: #008080;">166</span>         String xmlString = "&lt;html&gt;" + "&lt;head&gt;" + "&lt;title&gt;dom4j解析一个例子&lt;/title&gt;" <span style="color: #008080;">167</span>                 + "&lt;script&gt;" + "&lt;username&gt;yangrong&lt;/username&gt;" <span style="color: #008080;">168</span>                 + "&lt;password&gt;123456&lt;/password&gt;" + "&lt;/script&gt;" + "&lt;/head&gt;" <span style="color: #008080;">169</span>                 + "&lt;body&gt;" + "&lt;result&gt;0&lt;/result&gt;" + "&lt;form&gt;" <span style="color: #008080;">170</span>                 + "&lt;banlce&gt;1000&lt;/banlce&gt;" + "&lt;subID&gt;36242519880716&lt;/subID&gt;" <span style="color: #008080;">171</span>                 + "&lt;/form&gt;" + "&lt;/body&gt;" + "&lt;/html&gt;"<span style="color: #000000;">; </span><span style="color: #008080;">172</span>  <span style="color: #008080;">173</span>         <span style="color: #008000;">/*</span> <span style="color: #008080;">174</span> <span style="color: #008000;">         * Test2 test = new Test2(); test.readStringXml(xmlString); </span><span style="color: #008080;">175</span>          <span style="color: #008000;">*/</span> <span style="color: #008080;">176</span>         Map map =<span style="color: #000000;"> readStringXmlOut(xmlString); </span><span style="color: #008080;">177</span>         Iterator iters =<span style="color: #000000;"> map.keySet().iterator(); </span><span style="color: #008080;">178</span>         <span style="color: #0000ff;">while</span><span style="color: #000000;"> (iters.hasNext()) { </span><span style="color: #008080;">179</span>             String key = iters.next().toString(); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到键</span> <span style="color: #008080;">180</span>             String val = map.get(key).toString(); <span style="color: #008000;">//</span><span style="color: #008000;"> 拿到值</span> <span style="color: #008080;">181</span>             System.out.println(key + "=" +<span style="color: #000000;"> val); </span><span style="color: #008080;">182</span> <span style="color: #000000;">        } </span><span style="color: #008080;">183</span> <span style="color: #000000;">    } </span><span style="color: #008080;">184</span>  <span style="color: #008080;">185</span> }</pre> <div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div></div> <p>　　</p> <p>实例二：</p> <div><div><a title="复制代码"><img src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></div> <pre><span style="color: #008080;"> 1</span> <span style="color: #008000;">/**</span> <span style="color: #008080;"> 2</span> <span style="color: #008000;"> * 解析包含有DB连接信息的XML文件 </span><span style="color: #008080;"> 3</span> <span style="color: #008000;"> * 格式必须符合如下规范： </span><span style="color: #008080;"> 4</span> <span style="color: #008000;"> * 1. 最多三级，每级的node名称自定义； </span><span style="color: #008080;"> 5</span> <span style="color: #008000;"> * 2. 二级节点支持节点属性，属性将被视作子节点； </span><span style="color: #008080;"> 6</span> <span style="color: #008000;"> * 3. CDATA必须包含在节点中，不能单独出现。 </span><span style="color: #008080;"> 7</span> <span style="color: #008000;"> * </span><span style="color: #008080;"> 8</span> <span style="color: #008000;"> * 示例1&#8212;&#8212;三级显示： </span><span style="color: #008080;"> 9</span> <span style="color: #008000;"> * &lt;db-connections&gt; </span><span style="color: #008080;">10</span> <span style="color: #008000;"> *         &lt;connection&gt; </span><span style="color: #008080;">11</span> <span style="color: #008000;"> *            &lt;name&gt;DBTest&lt;/name&gt; </span><span style="color: #008080;">12</span> <span style="color: #008000;"> *            &lt;jndi&gt;&lt;/jndi&gt; </span><span style="color: #008080;">13</span> <span style="color: #008000;"> *            &lt;url&gt; </span><span style="color: #008080;">14</span> <span style="color: #008000;"> *                &lt;![CDATA[jdbc:mysql://localhost:3306/db_test?useUnicode=true&amp;characterEncoding=UTF8]]&gt; </span><span style="color: #008080;">15</span> <span style="color: #008000;"> *             &lt;/url&gt; </span><span style="color: #008080;">16</span> <span style="color: #008000;"> *            &lt;driver&gt;org.gjt.mm.mysql.Driver&lt;/driver&gt; </span><span style="color: #008080;">17</span> <span style="color: #008000;"> *             &lt;user&gt;test&lt;/user&gt; </span><span style="color: #008080;">18</span> <span style="color: #008000;"> *            &lt;password&gt;test2012&lt;/password&gt; </span><span style="color: #008080;">19</span> <span style="color: #008000;"> *            &lt;max-active&gt;10&lt;/max-active&gt; </span><span style="color: #008080;">20</span> <span style="color: #008000;"> *            &lt;max-idle&gt;10&lt;/max-idle&gt; </span><span style="color: #008080;">21</span> <span style="color: #008000;"> *            &lt;min-idle&gt;2&lt;/min-idle&gt; </span><span style="color: #008080;">22</span> <span style="color: #008000;"> *            &lt;max-wait&gt;10&lt;/max-wait&gt; </span><span style="color: #008080;">23</span> <span style="color: #008000;"> *            &lt;validation-query&gt;SELECT 1+1&lt;/validation-query&gt; </span><span style="color: #008080;">24</span> <span style="color: #008000;"> *         &lt;/connection&gt; </span><span style="color: #008080;">25</span> <span style="color: #008000;"> * &lt;/db-connections&gt; </span><span style="color: #008080;">26</span> <span style="color: #008000;"> * </span><span style="color: #008080;">27</span> <span style="color: #008000;"> * 示例2&#8212;&#8212;节点属性： </span><span style="color: #008080;">28</span> <span style="color: #008000;"> * &lt;bookstore&gt; </span><span style="color: #008080;">29</span> <span style="color: #008000;"> *         &lt;book category="cooking"&gt; </span><span style="color: #008080;">30</span> <span style="color: #008000;"> *            &lt;title lang="en"&gt;Everyday Italian&lt;/title&gt; </span><span style="color: #008080;">31</span> <span style="color: #008000;"> *            &lt;author&gt;Giada De Laurentiis&lt;/author&gt; </span><span style="color: #008080;">32</span> <span style="color: #008000;"> *            &lt;year&gt;2005&lt;/year&gt; </span><span style="color: #008080;">33</span> <span style="color: #008000;"> *            &lt;price&gt;30.00&lt;/price&gt; </span><span style="color: #008080;">34</span> <span style="color: #008000;"> *         &lt;/book&gt; </span><span style="color: #008080;">35</span> <span style="color: #008000;"> * </span><span style="color: #008080;">36</span> <span style="color: #008000;"> *         &lt;book category="children" title="Harry Potter" author="J K. Rowling" year="2005" price="$29.9"/&gt; </span><span style="color: #008080;">37</span> <span style="color: #008000;"> * &lt;/bookstore&gt; </span><span style="color: #008080;">38</span> <span style="color: #008000;"> * </span><span style="color: #008080;">39</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> configFile </span><span style="color: #008080;">40</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@return</span> <span style="color: #008080;">41</span> <span style="color: #008000;"> * </span><span style="color: #808080;">@throws</span><span style="color: #008000;"> Exception </span><span style="color: #008080;">42</span>  <span style="color: #008000;">*/</span> <span style="color: #008080;">43</span> <span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> List&lt;Map&lt;String, String&gt;&gt; parseDBXML(String configFile) <span style="color: #0000ff;">throws</span><span style="color: #000000;"> Exception { </span><span style="color: #008080;">44</span>     List&lt;Map&lt;String, String&gt;&gt; dbConnections = <span style="color: #0000ff;">new</span> ArrayList&lt;Map&lt;String, String&gt;&gt;<span style="color: #000000;">(); </span><span style="color: #008080;">45</span>     InputStream is = Parser.<span style="color: #0000ff;">class</span><span style="color: #000000;">.getResourceAsStream(configFile); </span><span style="color: #008080;">46</span>     SAXReader saxReader = <span style="color: #0000ff;">new</span><span style="color: #000000;"> SAXReader(); </span><span style="color: #008080;">47</span>     Document document =<span style="color: #000000;"> saxReader.read(is); </span><span style="color: #008080;">48</span>     Element connections =<span style="color: #000000;"> document.getRootElement(); </span><span style="color: #008080;">49</span>  <span style="color: #008080;">50</span>     Iterator&lt;Element&gt; rootIter =<span style="color: #000000;"> connections.elementIterator(); </span><span style="color: #008080;">51</span>     <span style="color: #0000ff;">while</span><span style="color: #000000;"> (rootIter.hasNext()) { </span><span style="color: #008080;">52</span>         Element connection =<span style="color: #000000;"> rootIter.next(); </span><span style="color: #008080;">53</span>         Iterator&lt;Element&gt; childIter =<span style="color: #000000;"> connection.elementIterator(); </span><span style="color: #008080;">54</span>         Map&lt;String, String&gt; connectionInfo = <span style="color: #0000ff;">new</span> HashMap&lt;String, String&gt;<span style="color: #000000;">(); </span><span style="color: #008080;">55</span>         List&lt;Attribute&gt; attributes =<span style="color: #000000;"> connection.attributes(); </span><span style="color: #008080;">56</span>         <span style="color: #0000ff;">for</span> (<span style="color: #0000ff;">int</span> i = 0; i &lt; attributes.size(); ++i) { <span style="color: #008000;">//</span><span style="color: #008000;"> 添加节点属性</span> <span style="color: #008080;">57</span> <span style="color: #000000;">            connectionInfo.put(attributes.get(i).getName(), attributes.get(i).getValue()); </span><span style="color: #008080;">58</span> <span style="color: #000000;">        } </span><span style="color: #008080;">59</span>         <span style="color: #0000ff;">while</span> (childIter.hasNext()) { <span style="color: #008000;">//</span><span style="color: #008000;"> 添加子节点</span> <span style="color: #008080;">60</span>             Element attr =<span style="color: #000000;"> childIter.next(); </span><span style="color: #008080;">61</span> <span style="color: #000000;">            connectionInfo.put(attr.getName().trim(), attr.getText().trim()); </span><span style="color: #008080;">62</span> <span style="color: #000000;">        } </span><span style="color: #008080;">63</span> <span style="color: #000000;">        dbConnections.add(connectionInfo); </span><span style="color: #008080;">64</span> <span style="color: #000000;">    } </span><span style="color: #008080;">65</span>  <span style="color: #008080;">66</span>     <span style="color: #0000ff;">return</span><span style="color: #000000;"> dbConnections; </span><span style="color: #008080;">67</span> }</pre></div></div><img src ="http://www.blogjava.net/longturi/aggbug/406702.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-11-22 21:00 <a href="http://www.blogjava.net/longturi/archive/2013/11/22/406702.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Dom4j中XPath的使用参考</title><link>http://www.blogjava.net/longturi/archive/2013/11/22/406701.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 22 Nov 2013 12:56:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/11/22/406701.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/406701.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/11/22/406701.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/406701.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/406701.html</trackback:ping><description><![CDATA[<div><div id="blog_content">     <p style="margin: 20px auto 10px;" g_t_wrap="" g_t_left="" g_t_20="" g_c_pdin=""  c07"=""><span style="font-family: '微软雅黑','黑体',Arial,Helvetica,Sans-Serif;">转自：<a href="http://txy920.blog.163.com/blog/static/1494427820095922212262/">http://txy920.blog.163.com/blog/static/1494427820095922212262/</a></span></p> <p style="margin: 20px auto 10px;" g_t_wrap="" g_t_left="" g_t_20="" g_c_pdin=""  c07"="">关键字：dom4j xpath</p> <div> <div g_c_pdin="" g_p_center="" c07=""  content"=""> <div> <ol><li>获取Document  <ul><li>SAXReader saxReader = new SAXReader(); </li><li>Document document = saxReader.read(FileUtil.getFileInputStream(fileName));<br /> </li></ul> </li><li>查询Element  <ul><li>String xpath ="/composites/composite[@type='onDelete']";//查询属性type='ondDelete'的composite </li><li>List&lt;Element&gt; composites = document.selectNodes(xpath);<br /> </li></ul> </li><li>xpath语法</li></ol> <div style="margin-left: 40px;"> <div> <h2>选取节点</h2> <p>XPath 使用路径表达式在 XML 文档中选取节点。节点是通过沿着路径或者 step 来选取的。</p> <h3>下面列出了最有用的路径表达式：</h3>  表达式 描述 <table border="0"> <tbody><tr></tr> <tr> <td>nodename</td> <td>选取此节点的所有子节点</td> </tr> <tr> <td>/</td> <td>从根节点选取</td> </tr> <tr> <td>//</td> <td>从匹配选择的当前节点选择文档中的节点，而不考虑它们的位置</td> </tr> <tr> <td>.</td> <td>选取当前节点</td> </tr> <tr> <td>..</td> <td>选取当前节点的父节点</td> </tr> <tr> <td>@</td> <td>选取属性</td> </tr> </tbody></table> <h3>实例</h3> <p>在下面的表格中，我们已列出了一些路径表达式以及表达式的结果：</p>  路径表达式 结果 <table border="0"> <tbody><tr></tr> <tr> <td>bookstore</td> <td>选取 bookstore 元素的所有子节点</td> </tr> <tr> <td>/bookstore</td> <td> <p>选取根元素 bookstore</p> <p>注释：假如路径起始于正斜杠( / )，则此路径始终代表到某元素的绝对路径！</p> </td> </tr> <tr> <td>bookstore/book</td> <td>选取所有属于 bookstore 的子元素的 book 元素。</td> </tr> <tr> <td>//book</td> <td>选取所有 book 子元素，而不管它们在文档中的位置。</td> </tr> <tr> <td>bookstore//book</td> <td>选择所有属于 bookstore 元素的后代的 book 元素，而不管它们位于 bookstore 之下的什么位置。</td> </tr> <tr> <td>//@lang</td> <td>选取所有名为 lang 的属性。</td> </tr> </tbody></table> </div> <div> <h2>谓语（Predicates）</h2> <p>谓语用来查找某个特定的节点或者包含某个指定的值的节点。</p> <p>谓语被嵌在方括号中。</p> <h3>实例</h3> <p>在下面的表格中，我们列出了带有谓语的一些路径表达式，以及表达式的结果：</p>  路径表达式 结果 <table border="0"> <tbody><tr></tr> <tr> <td>/bookstore/book[1]</td> <td>选取属于 bookstore 子元素的第一个 book 元素。</td> </tr> <tr> <td>/bookstore/book[last()]</td> <td>选取属于 bookstore 子元素的最后一个 book 元素。</td> </tr> <tr> <td>/bookstore/book[last()-1]</td> <td>选取属于 bookstore 子元素的倒数第二个 book 元素。</td> </tr> <tr> <td>/bookstore/book[position()&lt;3]</td> <td>选取最前面的两个属于 bookstore 元素的子元素的 book 元素。</td> </tr> <tr> <td>//title[@lang]</td> <td>选取所有拥有名为 lang 的属性的 title 元素。</td> </tr> <tr> <td>//title[@lang='eng']</td> <td>选取所有 title 元素，且这些元素拥有值为 eng 的 lang 属性。</td> </tr> <tr> <td>/bookstore/book[price&gt;35.00]</td> <td>选取所有 bookstore 元素的 book 元素，且其中的 price 元素的值须大于 35.00。</td> </tr> <tr> <td>/bookstore/book[price&gt;35.00]/title</td> <td>选取所有 bookstore 元素中的 book 元素的 title 元素，且其中的 price 元素的值须大于 35.00。</td> </tr> </tbody></table> </div> <div> <h2>选取未知节点</h2> <p>XPath 通配符可用来选取未知的 XML 元素。</p>  通配符 描述 <table border="0"> <tbody><tr></tr> <tr> <td>*</td> <td>匹配任何元素节点</td> </tr> <tr> <td>@*</td> <td>匹配任何属性节点</td> </tr> <tr> <td>node()</td> <td>匹配任何类型的节点</td> </tr> </tbody></table> <h3>实例</h3> <p>在下面的表格中，我们列出了一些路径表达式，以及这些表达式的结果：</p>  路径表达式 结果 <table border="0"> <tbody><tr></tr> <tr> <td>/bookstore/*</td> <td>选取 bookstore 元素的所有子节点</td> </tr> <tr> <td>//*</td> <td>选取文档中的所有元素</td> </tr> <tr> <td>//title[@*]</td> <td>选取所有带有属性的 title 元素。</td> </tr> </tbody></table> </div> <div> <h2>选取若干路径</h2> <p>通过在路径表达式中使用&#8220;|&#8221;运算符，您可以选取若干个路径。</p> <h3>实例</h3> <p>在下面的表格中，我们列出了一些路径表达式，以及这些表达式的结果：</p>  路径表达式 结果 <table border="0"> <tbody><tr></tr> <tr> <td>//book/title | //book/price</td> <td>选取所有 book 元素的 title 和 price 元素。</td> </tr> <tr> <td>//title | //price</td> <td>选取所有文档中的 title 和 price 元素。</td> </tr> <tr> <td>/bookstore/book/title | //price</td> <td>选取所有属于 bookstore 元素的 book 元素的 title 元素，以及文档中所有的 price 元素。</td> </tr> </tbody></table> </div> <br /><br /><div> <h2>XPath 轴</h2> <p>轴可定义某个相对于当前节点的节点集。</p>  轴名称 结果 <table border="0"> <tbody><tr></tr> <tr> <td>ancestor</td> <td>选取当前节点的所有先辈（父、祖父等）</td> </tr> <tr> <td>ancestor-or-self</td> <td>选取当前节点的所有先辈（父、祖父等）以及当前节点本身</td> </tr> <tr> <td>attribute</td> <td>选取当前节点的所有属性</td> </tr> <tr> <td>child</td> <td>选取当前节点的所有子元素。</td> </tr> <tr> <td>descendant</td> <td>选取当前节点的所有后代元素（子、孙等）。</td> </tr> <tr> <td>descendant-or-self</td> <td>选取当前节点的所有后代元素（子、孙等）以及当前节点本身。</td> </tr> <tr> <td>following</td> <td>选取文档中当前节点的结束标签之后的所有节点。</td> </tr> <tr> <td>namespace</td> <td>选取当前节点的所有命名空间节点</td> </tr> <tr> <td>parent</td> <td>选取当前节点的父节点。</td> </tr> <tr> <td>preceding</td> <td>选取文档中当前节点的开始标签之前的所有节点。</td> </tr> <tr> <td>preceding-sibling</td> <td>选取当前节点之前的所有同级节点。</td> </tr> <tr> <td>self</td> <td>选取当前节点。</td> </tr> </tbody></table> </div> <div> <h2>位置路径表达式</h2> <p>位置路径可以是绝对的，也可以是相对的。</p> <p>绝对路径起始于正斜杠( / )，而相对路径不会这样。在两种情况中，位置路径均包括一个或多个步，每个步均被斜杠分割：</p> <h3>绝对位置路径：</h3> <pre>/step/step/...</pre> <h3>相对位置路径：</h3> <pre>step/step/...</pre> <p>每个步均根据当前节点集之中的节点来进行计算。</p> <h3>步（step）包括：</h3>  <dt>轴（axis） </dt> <dd>定义所选节点与当前节点之间的树关系 </dd> <dt>节点测试（node-test） </dt> <dd>识别某个轴内部的节点 </dd> <dt>零个或者更多谓语（predicate） </dt> <dd>更深入地提炼所选的节点集</dd>  <h3>步的语法：</h3> <pre>轴名称::节点测试[谓语]</pre> <h3>实例</h3>  例子 结果 <table border="0"> <tbody><tr></tr> <tr> <td>child::book</td> <td>选取所有属于当前节点的子元素的 book 节点</td> </tr> <tr> <td>attribute::lang</td> <td>选取当前节点的 lang 属性</td> </tr> <tr> <td>child::*</td> <td>选取当前节点的所有子元素</td> </tr> <tr> <td>attribute::*</td> <td>选取当前节点的所有属性</td> </tr> <tr> <td>child::text()</td> <td>选取当前节点的所有文本子节点</td> </tr> <tr> <td>child::node()</td> <td>选取当前节点的所有子节点</td> </tr> <tr> <td>descendant::book</td> <td>选取当前节点的所有 book 后代</td> </tr> <tr> <td>ancestor::book</td> <td>选择当前节点的所有 book 先辈</td> </tr> <tr> <td>ancestor-or-self::book</td> <td>选取当前节点的所有book先辈以及当前节点（假如此节点是book节点的话）</td> </tr> <tr> <td>child::*/child::price</td> <td>选取当前节点的所有 price 孙。</td> </tr> </tbody></table> </div> <br /><div> <h2>XPath 运算符</h2> <p>下面列出了可用在 XPath 表达式中的运算符：</p>  运算符 描述 实例 返回值 <table border="0"> <tbody><tr></tr> <tr> <td>|</td> <td>计算两个节点集</td> <td>//book | //cd</td> <td>返回所有带有 book 和 ck 元素的节点集</td> </tr> <tr> <td>+</td> <td>加法</td> <td>6 + 4</td> <td>10</td> </tr> <tr> <td>-</td> <td>减法</td> <td>6 - 4</td> <td>2</td> </tr> <tr> <td>*</td> <td>乘法</td> <td>6 * 4</td> <td>24</td> </tr> <tr> <td>div</td> <td>除法</td> <td>8 div 4</td> <td>2</td> </tr> <tr> <td>=</td> <td>等于</td> <td>price=9.80</td> <td> <p>如果 price 是 9.80，则返回 true。</p> <p>如果 price 是 9.90，则返回 fasle。</p> </td> </tr> <tr> <td>!=</td> <td>不等于</td> <td>price!=9.80</td> <td> <p>如果 price 是 9.90，则返回 true。</p> <p>如果 price 是 9.80，则返回 fasle。</p> </td> </tr> <tr> <td>&lt;</td> <td>小于</td> <td>price&lt;9.80</td> <td> <p>如果 price 是 9.00，则返回 true。</p> <p>如果 price 是 9.90，则返回 fasle。</p> </td> </tr> <tr> <td>&lt;=</td> <td>小于或等于</td> <td>price&lt;=9.80</td> <td> <p>如果 price 是 9.00，则返回 true。</p> <p>如果 price 是 9.90，则返回 fasle。</p> </td> </tr> <tr> <td>&gt;</td> <td>大于</td> <td>price&gt;9.80</td> <td> <p>如果 price 是 9.90，则返回 true。</p> <p>如果 price 是 9.80，则返回 fasle。</p> </td> </tr> <tr> <td>&gt;=</td> <td>大于或等于</td> <td>price&gt;=9.80</td> <td> <p>如果 price 是 9.90，则返回 true。</p> <p>如果 price 是 9.70，则返回 fasle。</p> </td> </tr> <tr> <td>or</td> <td>或</td> <td>price=9.80 or price=9.70</td> <td> <p>如果 price 是 9.80，则返回 true。</p> <p>如果 price 是 9.50，则返回 fasle。</p> </td> </tr> <tr> <td>and</td> <td>与</td> <td>price&gt;9.00 and price&lt;9.90</td> <td> <p>如果 price 是 9.80，则返回 true。</p> <p>如果 price 是 8.50，则返回 fasle。</p> </td> </tr> <tr> <td>mod</td> <td>计算除法的余数</td> <td>5 mod 2</td> <td>1</td> </tr> </tbody></table> </div> <div>参考：</div> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://itren.iteye.com/blog/163901">http://itren.iteye.com/blog/163901</a> </div> </div> </div> </div> </div>   </div></div><img src ="http://www.blogjava.net/longturi/aggbug/406701.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-11-22 20:56 <a href="http://www.blogjava.net/longturi/archive/2013/11/22/406701.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java文件读写操作大全</title><link>http://www.blogjava.net/longturi/archive/2013/11/20/406585.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Wed, 20 Nov 2013 08:46:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/11/20/406585.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/406585.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/11/20/406585.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/406585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/406585.html</trackback:ping><description><![CDATA[<div><br />转自http://blog.sina.com.cn/s/blog_4a9f789a0100ik3p.html<br /><br />&nbsp;<br /><br />一.获得控制台用户输入的信息<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; public String getInputMessage() throws IOException...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("请输入您的命令&#8758;");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte buffer[]=new byte[1024];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count=System.in.read(buffer);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char[] ch=new char[count-2];//最后两位为结束符，删去不要<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;count-2;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ch[i]=(char)buffer[i];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String str=new String(ch);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return str;<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 可以返回用户输入的信息，不足之处在于不支持中文输入，有待进一步改进。<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 二.复制文件<br />&nbsp;&nbsp;&nbsp;&nbsp; 1.以文件流的方式复制文件<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; public void copyFile(String src,String dest) throws IOException...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileInputStream in=new FileInputStream(src);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File(dest);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!file.exists())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.createNewFile();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputStream out=new FileOutputStream(file);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int c;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte buffer[]=new byte[1024];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((c=in.read(buffer))!=-1)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;c;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.write(buffer[i]);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.close();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 该方法经过测试，支持中文处理，并且可以复制多种类型，比如txt，xml，jpg，doc等多种格式<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 三.写文件<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 1.利用PrintStream写文件<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp; public void PrintStreamDemo()...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try ...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputStream out=new FileOutputStream("D:/test.txt");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PrintStream p=new PrintStream(out);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;10;i++)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p.println("This is "+i+" line");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (FileNotFoundException e) ...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e.printStackTrace();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 2.利用StringBuffer写文件<br />public void StringBufferDemo() throws IOException......{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File("/root/sms.log");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!file.exists())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.createNewFile();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileOutputStream out=new FileOutputStream(file,true);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;10000;i++)......{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer sb=new StringBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sb.append("这是第"+i+"行:前面介绍的各种方法都不关用,为什么总是奇怪的问题 ");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.write(sb.toString().getBytes("utf-8"));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.close();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 该方法可以设定使用何种编码，有效解决中文问题。<br />四.文件重命名<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public void renameFile(String path,String oldname,String newname)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!oldname.equals(newname))...{//新的文件名和以前文件名不同时,才有必要进行重命名<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File oldfile=new File(path+"/"+oldname);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File newfile=new File(path+"/"+newname);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(newfile.exists())//若在该目录下已经有一个文件和新文件名相同，则不允许重命名<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(newname+"已经存在！");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldfile.renameTo(newfile);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp; 五.转移文件目录<br />&nbsp;&nbsp;&nbsp;&nbsp; 转移文件目录不等同于复制文件，复制文件是复制后两个目录都存在该文件，而转移文件目录则是转移后，只有新目录中存在该文件。<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public void changeDirectory(String filename,String oldpath,String newpath,boolean cover)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!oldpath.equals(newpath))...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File oldfile=new File(oldpath+"/"+filename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File newfile=new File(newpath+"/"+filename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(newfile.exists())...{//若在待转移目录下，已经存在待转移文件<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(cover)//覆盖<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldfile.renameTo(newfile);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("在新目录下已经存在："+filename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldfile.renameTo(newfile);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 六.读文件<br />&nbsp;&nbsp;&nbsp;&nbsp; 1.利用FileInputStream读取文件<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public String FileInputStreamDemo(String path) throws IOException...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File(path);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!file.exists()||file.isDirectory())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new FileNotFoundException();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileInputStream fis=new FileInputStream(file);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; byte[] buf = new byte[1024];<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer sb=new StringBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((fis.read(buf))!=-1)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sb.append(new String(buf));&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf=new byte[1024];//重新生成，避免和上次读取的数据重复<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sb.toString();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />2.利用BufferedReader读取<br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 在IO操作，利用BufferedReader和BufferedWriter效率会更高一点<br /><br /><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public String BufferedReaderDemo(String path) throws IOException...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File(path);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!file.exists()||file.isDirectory())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new FileNotFoundException();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedReader br=new BufferedReader(new FileReader(file));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String temp=null;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; StringBuffer sb=new StringBuffer();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp=br.readLine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while(temp!=null)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sb.append(temp+" ");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp=br.readLine();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return sb.toString();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br /><br />&nbsp;&nbsp;&nbsp;&nbsp; 3.利用dom4j读取xml文件<br /><br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public Document readXml(String path) throws DocumentException, IOException...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File(path);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BufferedReader bufferedreader = new BufferedReader(new FileReader(file));<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SAXReader saxreader = new SAXReader();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Document document = (Document)saxreader.read(bufferedreader);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bufferedreader.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return document;<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 七.创建文件(文件夹)<br /><br /><br />1.创建文件夹 &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public void createDir(String path)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File dir=new File(path);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!dir.exists())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir.mkdir();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />2.创建新文件<br />&nbsp;&nbsp;&nbsp;&nbsp; public void createFile(String path,String filename) throws IOException...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File(path+"/"+filename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(!file.exists())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.createNewFile();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; 八.删除文件(目录)<br />1.删除文件&nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public void delFile(String path,String filename)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File file=new File(path+"/"+filename);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(file.exists()&amp;&amp;file.isFile())<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; file.delete();<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />2.删除目录<br />要利用File类的delete()方法删除目录时，必须保证该目录下没有文件或者子目录，否则删除失败，因此在实际应用中，我们要删除目录，必须利用递归删除该目录下的所有子目录和文件，然后再删除该目录。 &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp; public void delDir(String path)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File dir=new File(path);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(dir.exists())...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; File[] tmp=dir.listFiles();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(int i=0;i&lt;tmp.length;i++)...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(tmp[i].isDirectory())...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; delDir(path+"/"+tmp[i].getName());<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else...{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp[i].delete();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir.delete();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp; }<br />From zhuocheng (cnblogs.com/zhuocheng)<br /></div><img src ="http://www.blogjava.net/longturi/aggbug/406585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-11-20 16:46 <a href="http://www.blogjava.net/longturi/archive/2013/11/20/406585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux查看文件的最初创建时间</title><link>http://www.blogjava.net/longturi/archive/2013/10/24/405601.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Thu, 24 Oct 2013 06:17:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/10/24/405601.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/405601.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/10/24/405601.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/405601.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/405601.html</trackback:ping><description><![CDATA[<div>http://article.pchome.net/content-1409199.html</div><br /><div><p>在Linux中，没有文件创建时间的概念。只有文件的访问时间、修改时间、状态改变时间。也就是说不能知道文件的创建时间。但如果文件创建后就没有 修改过，修改时间=创建时间;如果文件创建后，状态就没有改变过，那么状态改变时间=创建时间;如果文件创建后，没有被读取过，那么访问时间=创建时间， 这个基本不太可能。</p> <p>与文件相关的几个时间：</p> <p>1、访问时间，读一次这个文件的内容，这个时间就会更新。比如对这个文件使用more命令。ls、stat命令都不会修改文件的访问时间。</p> <p>2、修改时间，对文件内容修改一次，这个时间就会更新。比如：vi后保存文件。ls -l列出的时间就是这个时间。</p> <p>3、状态改变时间。通过chmod命令更改一次文件属性，这个时间就会更新。查看文件的详细的状态、准确的修改时间等，可以通过stat命令 文件名。</p> <p>比如： [jing@zhjh c]$ stat temp.c</p> <p>引用:</p> <p>File: 'temp.c'</p> <p>Size: 66 Blocks: 8 IO Block: 4096 u4e00u822cu6587u4ef6</p> <p>Device: 807h/2055d Inode: 1191481 Links: 1</p> <p>Access: (0664/-rw-rw-r--) Uid: ( 500/ jing) Gid: ( 500/ jing)</p> <p>Access: 2008-03-12 20:19:45.000000000 0800</p> <p>Modify: 2008-03-12 20:19:45.000000000 0800</p> <p>Change: 2008-03-12 20:19:45.000000000 0800</p> <p>说明：Access访问时间。Modify修改时间。Change状态改变时间。可以stat *查看这个目录所有文件的状态。</p></div><img src ="http://www.blogjava.net/longturi/aggbug/405601.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-10-24 14:17 <a href="http://www.blogjava.net/longturi/archive/2013/10/24/405601.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux命令行下常用svn命令</title><link>http://www.blogjava.net/longturi/archive/2013/10/18/405406.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 18 Oct 2013 06:01:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/10/18/405406.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/405406.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/10/18/405406.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/405406.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/405406.html</trackback:ping><description><![CDATA[<div>http://soft.chinabyte.com/os/291/11696291.shtml</div><br /><div><strong>&nbsp;&nbsp;&nbsp;&nbsp; 1、<a href="http://www.chinabyte.com/keyword/Linux/" target="_blank">Linux</a>命令行下将文件checkout到本地目录 </strong><p>　　svn checkout path(path是<a href="http://server.chinabyte.com/" target="_blank">服务器</a>上的目录)</p> <p>　　例如：svn checkout svn://192.168.1.1/pro/domain</p> <p>　　简写：svn co</p> <p>　　<strong>2、Linux命令行下往版本库中添加新的文件</strong></p> <p>　　svn add file</p> <p>　　例如：svn add test.php(添加test.php)</p> <p>　　svn add *.php(添加当前目录下所有的php文件)</p> <p>　　<strong>3、Linux命令行下将改动的文件提交到版本库</strong></p> <p>　　svn commit -m &#8220;LogMessage&#8220; [-N] [--no-unlock] PATH(如果选择了保持锁，就使用&#8211;no-unlock开关)</p> <p>　　例如：svn commit -m &#8220;add test file for my test&#8220; test.php</p> <p>　　简写：svn ci</p> <p>　　<strong>4、Linux命令行下的加锁/解锁</strong></p> <p>　　svn lock -m &#8220;LockMessage&#8220; [--force] PATH</p> <p>　　例如：svn lock -m &#8220;lock test file&#8220; test.php</p> <p>　　svn unlock PATH</p> <p>　　<strong>5、Linux命令行下更新到某个版本</strong></p> <p>　　svn update -r m path</p> <p>　　例如：</p> <p>　　svn update如果后面没有目录，默认将当前目录以及子目录下的所有文件都更新到最新版本。</p> <p>　　svn update -r 200 test.php(将版本库中的文件test.php还原到版本200)</p> <p>　　svn update test.php(更新，于版本库同步。如果在提交的时候提示过期的话，是因为冲突，需要先update，修改文件，然后清除svn resolved，最后再提交commit)</p> <p>　　简写：svn up</p> <p>　　<strong>6、Linux命令行下查看文件或者目录状态</strong></p> <p>　　1)svn status path(目录下的文件和子目录的状态，正常状态不显示)</p> <p>　　【?：不在svn的控制中;M：内容被修改;C：发生冲突;A：预定加入到版本库;K：被锁定】</p> <p>　　2)svn status -v path(显示文件和子目录状态)</p> <p>　　第一列保持相同，第二列显示工作版本号，第三和第四列显示最后一次修改的版本号和修改人。</p> <p>　　注：svn status、svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的，原因是svn在本地的.svn中保留了本地版本的原始拷贝。</p> <p>　　简写：svn st</p> <p>　　<strong>7、Linux命令行下删除文件</strong></p> <p>　　svn delete path -m &#8220;delete test fle&#8220;</p> <p>　　例如：svn delete svn://192.168.1.1/pro/domain/test.php -m &#8220;delete test file&#8221;</p> <p>　　或者直接svn delete test.php 然后再svn ci -m &#8216;delete test file&#8216;，推荐使用这种</p> <p>　　简写：svn (del, remove, rm)</p> <p>　　<strong>8、Linux命令行下查看日志</strong></p> <p>　　svn log path</p> <p>　　例如：svn log test.php 显示这个文件的所有修改记录，及其版本号的变化</p> <p>　　<strong>9、Linux命令行下查看文件详细信息</strong></p> <p>　　svn info path</p> <p>　　例如：svn info test.php</p> <p>　　<strong>10、Linux命令行下比较差异</strong></p> <p>　　svn diff path(将修改的文件与基础版本比较)</p> <p>　　例如：svn diff test.php</p> <p>　　svn diff -r m:n path(对版本m和版本n比较差异)</p> <p>　　例如：svn diff -r 200:201 test.php</p> <p>　　简写：svn di</p> <p>　　<strong>11、Linux命令行下将两个版本之间的差异合并到当前文件</strong></p> <p>　　svn merge -r m:n path</p> <p>　　例如：svn merge -r 200:205 test.php(将版本200与205之间的差异合并到当前文件，但是一般都会产生冲突，需要处理一下)</p> <p>　　<strong>12、Linux命令行下SVN 帮助</strong></p> <p>　　svn help</p> <p>　　svn help ci</p> <p>　　以上是常用命令，下面写几个不经常用的</p> <p>　　<strong>13、Linux命令行下版本库下的文件和目录列表</strong></p> <p>　　svn list path</p> <p>　　显示path目录下的所有属于版本库的文件和目录</p> <p>　　简写：svn ls</p> <p>　　<strong>14、Linux命令行下创建纳入版本控制下的新目录</strong></p> <p>　　svn mkdir: 创建纳入版本控制下的新目录。</p> <p>　　用法: 1、mkdir PATH&#8230;</p> <p>　　2、mkdir URL&#8230;</p> <p>　　创建版本控制的目录。</p> <p>　　1、每一个以工作副本 PATH 指定的目录，都会创建在本地端，并且加入新增调度，以待下一次的提交。</p> <p>　　2、每个以URL指定的目录，都会透过立即提交于仓库中创建.在这两个情况下，所有的中间目录都必须事先存在。</p> <p>　　<strong>15、Linux命令行下恢复本地修改</strong></p> <p>　　svn revert: 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert:</p> <p>　　用法: revert PATH&#8230;</p> <p>　　注意: 本子命令不会存取网络，并且会解除冲突的状况。但是它不会恢复被删除的目录</p> <p>　　<strong>16、Linux命令行下代码库URL变更</strong></p> <p>　　svn switch (sw): 更新工作副本至不同的URL。</p> <p>　　用法: 1、switch URL [PATH]</p> <p>　　2、switch &#8211;relocate FROM TO [PATH...]</p> <p>　　1、更新你的工作副本，映射到一个新的URL，其行为跟&#8220;svn update&#8221;很像，也会将服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的方法。</p> <p>　　2、改写工作副本的URL元数据，以反映单纯的URL上的改变。当仓库的根URL变动(比如<a href="http://solution.chinabyte.com/new/" target="_blank">方案</a>名或是主机名称变动)，但是工作副本仍旧对映到同一仓库的同一目录时使用这个命令更新工作副本与仓库的对应关系。</p> <p>　　<strong>17、Linux命令行下解决冲突</strong></p> <p>　　svn resolved: 移除工作副本的目录或文件的&#8220;冲突&#8221;状态。</p> <p>　　用法: resolved PATH&#8230;</p> <p>　　注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的相关文件，然后让 PATH 可以再次提交。</p> <p>　　<strong>18、Linux命令行下输出指定文件或URL的内容。</strong></p> <p>　　svn cat 目标[@版本]&#8230;如果指定了版本，将从指定的版本开始查找。</p> <p>　　svn cat -r PREV filename &gt; filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)</p></div><img src ="http://www.blogjava.net/longturi/aggbug/405406.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-10-18 14:01 <a href="http://www.blogjava.net/longturi/archive/2013/10/18/405406.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>svn co  </title><link>http://www.blogjava.net/longturi/archive/2013/10/18/405398.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 18 Oct 2013 03:29:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/10/18/405398.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/405398.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/10/18/405398.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/405398.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/405398.html</trackback:ping><description><![CDATA[<div><div fc05="" fc11="" nbw-blog="" ztag=""  js-fs2"=""><div><div>http://blog.163.com/wb_zhaoyuwei/blog/static/183075439201301535012961/</div><br /><br />首先需要知道一点， &nbsp;svn co &nbsp;只能check &nbsp;目录， 不能co文件； 如果需要co文件， 需要用 svn export;</div><div></div>svn &nbsp;co &nbsp;的用法经常有两种： &nbsp;&nbsp;<wbr><div>第一种： &nbsp;直接 &nbsp;svn &nbsp;co &nbsp; &nbsp;http://svnserver/mypro/trunk</div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 此时， 会在你的当前目录下， 增加一个 trunk文件夹； &nbsp;svn的trunk文件的内容， 在trunk文件夹中。</div><div></div><div>第二种： &nbsp;svn &nbsp;co &nbsp;&nbsp;<span style="line-height: 22px;">http://svnserver/mypro/trunk &nbsp; code</span></div><div><span style="line-height: 22px;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;此时， 会在你的当前目录下， 增加一个 code的文件夹， &nbsp;svn的trunk的文件的内容， 在code中。</span></div></div></div><img src ="http://www.blogjava.net/longturi/aggbug/405398.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-10-18 11:29 <a href="http://www.blogjava.net/longturi/archive/2013/10/18/405398.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Bugzilla中通过SMTP发通知邮件</title><link>http://www.blogjava.net/longturi/archive/2013/09/27/404568.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 27 Sep 2013 10:40:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/09/27/404568.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/404568.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/09/27/404568.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/404568.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/404568.html</trackback:ping><description><![CDATA[<div>From:<br />http://www.cnitblog.com/201/archive/2011/05/25/74069.html</div><br /><div>在Bugzilla中通过SMTP发通知邮件<br />Posted on 2011/04/05 by admin<br /><br />Bugzilla 4.0注册验证通知等邮件可以通过SendMail之类的来发送，配置也很简单，但是它发出去的邮件后缀地址是localhost.localdomain之类的地址，会被一些邮箱拦截，从而收不到邮件。所以通过SMTP来发邮件还是很必要的。<br />文档上说的配置SMTP也很简单，但是我在配置的时候遇到几个问题，在此记录下来<br />1、The new value for smtp_username is invalid: SMTP Authentication is not available. Run checksetup.pl for more details.<br />这是我在Bugzilla中Create New Account的时候发验证邮件时产生的，这个的原因是Perl有个模块没有安装，安装下就可以了<br />sudo perl install-module.pl Authen::SASL<br />自己先可以通过$ ./checksetup.pl &#8211;check-modules查看下已经安装了哪些模块<br />只要安装好，上述的这个问题就解决了<br /><br />所以再次试着注册一个用户，提示邮件发送成功了，于是下面的问题产生了<br /><br />2、提示邮件成功发送，但是实际邮件没有发送出去，因为我填的邮箱没有收到邮件<br />在这里我原先是开启了use_mailer_queue这个功能<br />于是我选择使用Test模式(Parameters -&gt; Email -&gt; mail_delivery_method -&gt; SMTP)再发了一次，mailer.testfile木有邮件<br /><br />网 络上有人和我是一样的问题，发不出去邮件，我参看这里http://hi.baidu.com/ever__love/blog/item  /62473a9772800846d0135e2c.html的方法，把use_mailer_queue关闭(Parameters -&gt;  Email -&gt; use_mailer_queue -&gt; Off)，再试着发送一次，果真mailer.testfile当中有邮件了<br /><br />这样就基本定位到问题use_mailer_queue没有正常工作<br /><br />于是又把use_mailer_queue开启<br />执行下面的命令<br />$ $BUGZILLA_HOME/jobqueue.pl check<br />Configuration looks okay<br />jobqueue.pl running &#8211; pid 5317<br />9 jobs in the queue.<br /><br />看起来似乎正常，但是提示9 jobs in the queue，并且这个数目一直没有减少，这说明邮件几乎都被堵塞在这里了，而并没有发出去<br /><br />于是又Debug发现<br />$ $BUGZILLA_HOME/jobqueue.pl -f -d restart<br />Killing 9657<br />Starting up&#8230;<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once found no jobs<br /><br />几乎神了，这里又说没有错误，那到底是哪里出问题了呢？<br />目前无解，求解ING。。。<br /><br />UPDATE 后来经过分析解决了此问题<br />虽然debug jobqueue出来的信息开头几个没有发现什么异常，但是经过很多个&#8220;TheSchwartz::work_once found no jobs&#8221;之后出来一些错误信息，如下：<br />&#8230;&#8230;<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once found no jobs<br />&#8230;&#8230;.<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once got job of class &#8216;Bugzilla::Job::Mailer&#8217;<br />Working on Bugzilla::Job::Mailer &#8230;<br />Use of uninitialized value $hostname in concatenation (.) or string at Bugzilla/Mailer.pm line 153.<br />job failed. considering retry. is max_retries of 725 &gt;= failures of 5?<br />job failed: There was an error sending mail from &#8216;bugzilla_admin@&#8217; to<br />&#8216;xxxxx@aol.com&#8217;:Can&#8217;t call method &#8220;address&#8221; on an undefined value at<br />lib/Email/Send/SMTP.pm line 25.<br />TheSchwartz::work_once found no jobs<br />&#8230;&#8230;<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once got job of class &#8216;Bugzilla::Job::Mailer&#8217;<br />Working on Bugzilla::Job::Mailer &#8230;<br />Use of uninitialized value $hostname in concatenation (.) or string at Bugzilla/Mailer.pm line 153.<br />job failed. considering retry. is max_retries of 725 &gt;= failures of 5?<br />job failed: There was an error sending mail from &#8216;bugzilla_admin@&#8217; to<br />&#8216;xxxxxx@gmail.com&#8217;:Can&#8217;t call method &#8220;address&#8221; on an undefined value<br />at lib/Email/Send/SMTP.pm line 25.<br />TheSchwartz::work_once found no jobs<br />&#8230;&#8230;<br />TheSchwartz::work_once found no jobs<br /><br />&#8230;&#8230;是我省略掉了很多这样相同的状态<br /><br />看起来这个jobqueue当中的任务不是立即就执行了的，它可能是经过某种算法才执行的<br />否则不应该出现第一个就是&#8220;TheSchwartz::work_once found no jobs&#8221;，到后面才有任务执行的<br /><br />并且进一步发现这些任务队列都是放在数据库当中的一张表(ts_job)中的，任务成功一个就把它从这张表中删除<br /><br />不过此时问题还没有解决，认真看下错误，并且看了指出的错误地方的源代码，觉得应该是mailfrom填错了，可能我这里填的不完整<br /><br />又打开SMTP的调试开关(Parameters -&gt; Email -&gt; smtp_debug -&gt; On)，这样能看到更多的详细信息，基本觉得问题就在这了<br /><br />于是我填写了标准的邮件格式&#8220;username@example.com&#8221;之后再试，邮件还不没有发出去，jobqueue的的数量又增加了一个，<br />看来可能前面的这些包含错误信息的队列已经将后面的阻塞了，于是我试着将ts_job表当中的数据删除<br />truncate table ts_job; // 反正我这里是直接truncate掉了的，我不知道这里delete和truncate有没有区别<br /><br />再次注册了一遍，看到后台输出通知邮件发送成功的信息，如下：<br />TheSchwartz::work_once found no jobs<br />TheSchwartz::work_once got job of class &#8216;Bugzilla::Job::Mailer&#8217;<br />Working on Bugzilla::Job::Mailer &#8230;<br />Net::SMTP&gt;&gt;&gt; Net::SMTP(2.31)<br />Net::SMTP&gt;&gt;&gt; Net::Cmd(2.29)<br />Net::SMTP&gt;&gt;&gt; Exporter(5.63)<br />Net::SMTP&gt;&gt;&gt; IO::Socket::INET(1.31)<br />Net::SMTP&gt;&gt;&gt; IO::Socket(1.31)<br />Net::SMTP&gt;&gt;&gt; IO::Handle(1.28)<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 220 esmtp4.qq.com Esmtp QQ Mail Server<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; EHLO localhost.localdomain<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250-esmtp4.qq.com<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250-PIPELINING<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250-SIZE 52428800<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250-AUTH LOGIN PLAIN<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250-AUTH=LOGIN<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250 8BITMIME<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; AUTH LOGIN<br />&#8230;&#8230;<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 235 Authentication successful<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; MAIL FROM:<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250 Ok<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; RCPT TO:<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250 Ok<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; DATA<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 354 End data with .<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; From: xxxxxx@qq.com<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; To: xxxxxx@gmail.com<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; Subject: Bugzilla: confirm account creation<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; X-Bugzilla-Type: admin<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; X-Bugzilla-URL:<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; Auto-Submitted: auto-generated<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; Content-Type: text/plain; charset=&#8221;UTF-8&#8243;<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; MIME-Version: 1.0<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; Date: Tue, 05 Apr 2011 16:05:23 +0800<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt;<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; Bugzilla has received a request to create a user account<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; using your email address (xxxxxx@gmail.com).<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt;<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; To continue creating an account using this email address, visit the<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; following link by April 8, 2011 at 16:05 CST:<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt;<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; token.cgi?t=FegLL6OpYM&amp;a=request_new_account<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; PRIVACY NOTICE: Bugzilla is an open bug tracking system. Activity on most<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; bugs, including email addresses, will be visible to the public. We recommend<br />&#8230;&#8230;<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; .<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 250 Ok: queued as<br />Net::SMTP=GLOB(0xb79ce68)&gt;&gt;&gt; QUIT<br />Net::SMTP=GLOB(0xb79ce68)&lt;&lt;&lt; 221 Bye<br />job completed<br />TheSchwartz::work_once found no jobs<br /><br />到QQ Mail也看到发送成功的邮件，在Gmail也收到了邮件，到此才算基本成功。<br /><br />Parameters -&gt; Email里面我的基本几项数据如下<br />mailfrom : xxxxxx@qq.com // 出现问题就是这里填的不标准<br />use_mailer_queue : on<br />smtpserver : smtp.qq.com<br />smtp_username : xxxxxx@qq.com<br />smtp_password : ******<br /><br />如果mail_delivery_method你选择SendMail或者Test，那么SMTP相关的参数就可以不用填了，如果你是通过SSL加密的SMTP链接，应该是要新装插件了<br /><br />P.S. 关于use_mailer_queue的信息请挪步http://www.bugzilla.org/releases/4.0/release-notes.html#v34_feat_async 		</div><img src ="http://www.blogjava.net/longturi/aggbug/404568.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-09-27 18:40 <a href="http://www.blogjava.net/longturi/archive/2013/09/27/404568.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>bugzilla安装过程，已验证成功！</title><link>http://www.blogjava.net/longturi/archive/2013/09/27/404544.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Fri, 27 Sep 2013 06:18:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/09/27/404544.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/404544.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/09/27/404544.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/404544.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/404544.html</trackback:ping><description><![CDATA[From: <div>http://hi.baidu.com/najftulhmndgswr/item/6d8ba9f0d02e9004d89e7294</div><br /><br /><div>本文安装过程主要参考：<br /><strong><br /><a target="_blank" href="http://www.bugzilla.org/docs/3.6/en/html/installation.html">http://www.bugzilla.org/docs/3.6/en/html/installation.html</a><br /><br /><a target="_blank" href="http://www.thegeekstuff.com/2010/05/install-bugzilla-on-linux/">http://www.thegeekstuff.com/2010/05/install-bugzilla-on-linux/</a><br /><br /><br />安装流程：<br /><br />1. 先检测下 Perl是否安装了</strong><br /><br />$ perl -v<br />如果没有安装，下载安装<br /><br /><strong>2.&nbsp; 安装一个数据库，推荐使用 MySQL</strong><br /><br />$ mysql -V<br />如果没有安装的话，用 apt-get即可，server和client都装下。<br />在装 mysql-server的时候会提示输入 password，记住，再后面创建数据库的时候会用到。<br /><br /><strong>3.&nbsp; 安装apache２</strong><br /><br />apt-get install 即可。<br /><br />测试apache2是否正常：<br /><br />在浏览器的URL栏输入:&nbsp; http://localhost&nbsp; 或者　 http://127.0.0.1;<br />只要出现：　It works!<br />表示服务器已经正常启动。<br /><br /><strong>４.&nbsp; 下载并安装　Bugzilla　</strong><br /><br />下载 Bugzilla 3.6.1，地址：　<a target="_blank" href="http://www.bugzilla.org/download/">http://www.bugzilla.org/download/</a><br /><br />下载后在　/var/www/目录下解压，然后进入目录<br /><br /><strong>１）</strong>Perl 模块的安装<br /><br />a)首先查看下缺少的模块<br /><br />bash# ./checksetup.pl --check-modules　<br /><br />b)然后利用这个命令将所缺模块安装上<br /><br />bash# perl install-module.pl &lt;modulename&gt;<br /><br />必须安装的模块有这些：<br /><br />1. CGI (3.21)<br />2. Date::Format (2.21)<br />3. DateTime (0.28)<br />4. DateTime::TimeZone (0.71)<br />5. DBI (1.41)<br />6. DBD::mysql (4.00) if using MySQL<br />7. Digest::SHA (any)<br />8. Email::Send (2.00)<br />9. Email::MIME (1.861)<br />10. Email::MIME::Encodings (1.313)<br />11. Email::MIME::Modifier (1.442)<br />12. Template (2.22)<br />13. URI (any) <br /><br /><strong>如果未安装模块太多,可以执行下列命令，全体安装：<br /></strong>（注意：由于安装模块的时候会有权限问题，所以在执行下列命令前，<br />sudo chmod 777 -R bugzilla-3.6.1）<br /><br />bash# /usr/bin/perl install-module.pl --all<br /><br />（关于DateTime::TimeZone 模块安装失败的问题，请参考此网站的最后回复，Build）<br /><a href="http://www.experts-exchange.com/OS/Linux/Q_25111007.html" target="_blank">http://www.experts-exchange.com/OS/Linux/Q_25111007.html</a><br />需要自己下载DateTIme模块，然后重新编译，在解压目录 perl Build.PL,然后按照上面网站所说！！！<br /><strong><br />2)</strong>成功装完后，生成本地config<br /><br />bash# ./checksetup.pl<br /><br />bash# vi ./localconfig<br />修改：　$db_pass = 'akaedu';<br />修改：&nbsp;&nbsp; $webservergroup = 'www-data';<br />保存退出 <br /><br /><strong>3)</strong>之后在mysql数据库中加入信息<br /><br />bash# mysql -u root -p　<br />（如果这里要输入密码一直过不去，请参考<br /><a target="_blank" href="http://hi.baidu.com/ever__love/blog/item/1c9b3c19cd0866f7af5133c7.html">http://hi.baidu.com/ever__love/blog/item/1c9b3c19cd0866f7af5133c7.html</a>）<br /><br />mysql&gt; GRANT SELECT, INSERT,<br />UPDATE, DELETE, INDEX, ALTER, CREATE, LOCK TABLES,<br />CREATE TEMPORARY TABLES, DROP, REFERENCES ON bugs.*<br />TO bugs@localhost IDENTIFIED BY 'akaedu';<br /><br />mysql&gt; FLUSH PRIVILEGES;<br />mysql&gt; quit;<br /><br />mysql的命令必须都以分号结束。<br /><br /><strong>4)</strong> 再次安装<br /><br />bash# ./checksetup.pl<br /><br />如果上述一切正常，这次安装过程中将提示你输入　邮箱，真名，密码。<br />邮箱是你登录bugzilla的root用户名，密码就是密码。<br /><br /><br /><strong>5. 配置apache的config，与bugzilla的index链接</strong><br /><br />bash# vi /etc/apache2/apache2.conf<br /><br />在内部添加这样一段：<br />&lt;Directory /var/www/bugzilla-3.6.1&gt;<br />AddHandler cgi-script .cgi<br />Options +Indexes +ExecCGI<br />DirectoryIndex index.cgi<br />AllowOverride Limit<br />&lt;/Directory&gt;<br /><br />然后重启apache2<br /><br />bash# /etc/init.d/apache2 restart<br /><br /><strong>6.&nbsp; 到这里应该就能正常访问bugzilla的主页了</strong><br /><br />URL:&nbsp;&nbsp;&nbsp; http://localhost/bugzilla&nbsp; (如果不行，就把bugzilla的版本号加上)<br />就会看到如下图像，表示正常登录bugzilla了。<br /><br /><img src="http://hiphotos.baidu.com/ever__love/pic/item/6620a44c1b31a948b2de0546.jpg" height="473" width="758"  alt="" /><br /><br /><br />大功告成<br /><br />进入后，选一个 &#8220;File a bug&#8221;， 然后输入root用户名(邮箱)以及密码就正常登录，可以使用了。<br />目前遗留问题，无法注册普通用户，因为注册时候会发送确认信件，发送显示成功（没有报错），但目标信件收不到，不知是哪里出了问题。TODO！<br /><br /><br />上述邮件发送问题已经解决了！！！<br /><br />解决方法：<br />感觉应该是 bugzilla的设置问题，在bugzilla网页上登录后，点击上端菜单中的<br />Administration, 然后选择 Parameters, 在左侧栏中选择E-mail，然后在 mail_delivery_method中选择  Test，虽然你点击了发送邮件，但会被bugzilla自己截获，存入  data/mailer.testfile文件中。如果发不出邮件，可以选择Test，在data/mailer.testfile文件中如果有信息，那 说明邮件服务器有问题，但如果此文件中没有信息，那就说明有别的问题。<br />我发送邮件显示正常，但目标收不到邮件，检查 data/mailer.testfile文件，发现是空的。之前用telnet  smtp测试，能正常连通smtp.163.com，思来想去，应该就是bugzilla的设置问题。这个不成功的版本是在同时电脑上测试的，我自己的已 经成功，只不过过程中修改的东西太多，不知如何调试了。于是乎我就想到了diff，网页上的配置信息对应到源码中，就是  data/params文件，于是我将我的文件与我同事电脑上的这个文件进行了diff，其中有一项 use_mailer_queue。&nbsp; 不成功：  'use_mailer_queue' =&gt; '1', 成功的'use_mailer_queue' =&gt; 0, 于是将不成功的修改为  0，结果再尝试Test， data/mailer.testfile中已经有信息了，将  mail_delivery_method修改为SMTP，也能正常发送邮件了！</div><img src ="http://www.blogjava.net/longturi/aggbug/404544.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-09-27 14:18 <a href="http://www.blogjava.net/longturi/archive/2013/09/27/404544.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> Tomcat下使用war包发布项目 </title><link>http://www.blogjava.net/longturi/archive/2013/09/19/404234.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Thu, 19 Sep 2013 05:04:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/09/19/404234.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/404234.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/09/19/404234.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/404234.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/404234.html</trackback:ping><description><![CDATA[From：<div>http://blog.csdn.net/wy818/article/details/7240294</div><br /><br /><div><div id="app-share-content"> <p>有两种方法: <br /> 1.将项目打成war包,复制到${tomcat.home}\webapps目录下.当tomcat启动时会自动将其解包.</p> <p><span style="color:olive"><span style="color:#000000">有人说，</span>不能直接将war文件夹直接复制到${tomcat.home}\webapps目录下.</span></p> <p>但是我试过之后，可以。将war包解压，解压出的文件夹要和war文件同名（后面可没有 .war），然后将文件夹放到webapps下面就可以了</p> <p>2.修改${tomcat.home}\conf\server.xml文件.在Host节点下增加如下参考代码:</p> <p><span>&lt;Context docBase=<span style="color:#0000ff">"D:\pafalearning\userapp\dist\tomcat\userapp.war"</span> path=<span style="color:#0000ff">"/userapp"</span><span>  reloadable=</span><span style="color:#0000ff">"true"</span>/&gt;&nbsp;&nbsp;</span></p> <div bg_java"=""><div><div><strong>[java]</strong> <a href="http://blog.csdn.net/wy818/article/details/7240294#" title="view plain">view plain</a><a href="http://blog.csdn.net/wy818/article/details/7240294#" title="copy">copy</a></div></div><ol start="1"><li><span>&lt;Context&nbsp;docBase="D:\pafalearning\userapp\dist\tomcat\userapp.war"&nbsp;path="/userapp"&nbsp;reloadable="true"/&gt;&nbsp;&nbsp;</span></li></ol></div> <p><strong>docBase</strong>:指向项目的根目录所在的路径,由于我将项目打成了war包,所以直接指向这个war包就可以了(我的项目名为:userapp).<br /> <strong>path</strong>:是一个虚拟目录,这里设置成了"<span style="color:brown">userapp</span>",则启动Tomcat后,你将通过http://localhost:8080/<span style="color:brown">userapp</span>/*.jsp来访问项目的相关页面.<br /> <strong>reloadable</strong>:如果设置为"true",则表示当你修改jsp文件后,不需要重启服务器就可以实现页面显示的同步. <br /> <br /> <strong>可以这样理解</strong>:将docBase实际目录下的项目,映射到${tomcat.home}\webapps目录下的虚拟项目path(这里的配置指的是userapp项目).</p>  <p>也许有些人还不懂war包是什么，其实就是你的项目下的WebRoot文件夹中的内容（不加WebRoot这个文件夹）打成一个压缩包，后缀用war，其实和rar差不多，不过tomcat就认war。</p> <p>那为什么war包可以讲项目这个发布出来呢？</p> <p>1.因为所有新建的文件夹都在WebRoot文件夹下</p> <p>2.所有的页面都在WebRoot文件夹下</p> <p>3.所有的后台代码都编译成了 .class文件，在WebRoot \ WEB-INF \ classes 下面</p> <p>4.我们习惯将所有的 .jar包放在WebRoot \ WEB-INF \ lib 下面</p> <p>有了这些，就相当于一个项目完全考到了tomcat下面，这就是用war包发布项目的原理</p> </div></div><img src ="http://www.blogjava.net/longturi/aggbug/404234.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-09-19 13:04 <a href="http://www.blogjava.net/longturi/archive/2013/09/19/404234.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java MessageFormat.format格式化字符串大括号以及单引号问题 </title><link>http://www.blogjava.net/longturi/archive/2013/09/17/404166.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Tue, 17 Sep 2013 04:35:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/09/17/404166.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/404166.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/09/17/404166.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/404166.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/404166.html</trackback:ping><description><![CDATA[<div><p>&nbsp;</p><div>http://blog.csdn.net/jeamking/article/details/7226656</div><br /><p>&nbsp;</p><p><br /></p><p>在MessageFormat.format方法中组装jason数据字符串：{code:"w1",des:"w2"}，起止分别有左大括号和右大括号。方法是将单引号把大括号包含起来。如下：<br /> </p>  &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; String responseTemplate = "'{'code:\"{0}\",des:\"{1}\"'}'";<br /> <p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;System.out.println(MessageFormat.format(responseTemplate, "w1","w2"));</p> <p>如果格式化字符串中包含单引号，处理方法是用2个单引号进行转义：</p> <p>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; String responseTemplate = "'{'code:''{0}'',des:''{1}'''}'";<br /> &nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;System.out.println(MessageFormat.format(responseTemplate, "w1","w2"));</p> 处理结果：{code:'w1',des:'w2'}</div><img src ="http://www.blogjava.net/longturi/aggbug/404166.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-09-17 12:35 <a href="http://www.blogjava.net/longturi/archive/2013/09/17/404166.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> java保留两位小数 </title><link>http://www.blogjava.net/longturi/archive/2013/09/17/404164.html</link><dc:creator>ZT文萃</dc:creator><author>ZT文萃</author><pubDate>Tue, 17 Sep 2013 04:22:00 GMT</pubDate><guid>http://www.blogjava.net/longturi/archive/2013/09/17/404164.html</guid><wfw:comment>http://www.blogjava.net/longturi/comments/404164.html</wfw:comment><comments>http://www.blogjava.net/longturi/archive/2013/09/17/404164.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/longturi/comments/commentRss/404164.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/longturi/services/trackbacks/404164.html</trackback:ping><description><![CDATA[<div><p><strong>java保留两位小数问题：</strong></p> <p><strong>方式一：</strong></p> <p><strong>四舍五入&nbsp;&nbsp;<br />double&nbsp;&nbsp; f&nbsp;&nbsp; =&nbsp;&nbsp; 111231.5585;&nbsp;&nbsp;<br />BigDecimal&nbsp;&nbsp; b&nbsp;&nbsp; =&nbsp;&nbsp; new&nbsp;&nbsp; BigDecimal(f);&nbsp;&nbsp;<br />double&nbsp;&nbsp; f1&nbsp;&nbsp; =&nbsp;&nbsp; b.setScale(2,&nbsp;&nbsp; BigDecimal.ROUND_HALF_UP).doubleValue();&nbsp;&nbsp;<br />保留两位小数&nbsp;&nbsp;<br />---------------------------------------------------------------&nbsp;&nbsp;</strong></p> <p><strong>方式二：</strong></p> <p><strong>java.text.DecimalFormat&nbsp;&nbsp; df&nbsp;&nbsp; =new&nbsp;&nbsp; java.text.DecimalFormat("#.00");&nbsp;&nbsp;<br />df.format(你要格式化的数字);</strong></p> <p><strong>例：new java.text.DecimalFormat("#.00").format(3.1415926)</strong></p> <p><strong>#.00 表示两位小数 #.0000四位小数 以此类推...</strong></p> <p><strong>方式三：</strong></p> <p><strong>double d = 3.1415926;</strong></p> <p><strong>String result = String .format("%.2f");</strong></p> <p><strong>%.2f %. 表示 小数点前任意位数&nbsp;&nbsp; 2 表示两位小数 格式后的结果为f 表示浮点型</strong></p> <p><strong>方式四：</strong></p> <p><strong>NumberFormat ddf1=NumberFormat.getNumberInstance() ; </strong></p> <p><strong>void setMaximumFractionDigits(int digits) <br />digits 显示的数字位数 <br />为格式化对象设定小数点后的显示的最多位,显示的最后位是舍入的</strong></p> <p>import java.text.* ; <br />import java.math.* ; <br />class TT <br />{ <br />public static void main(String args[]) <br />{ double x=23.5455; <br />NumberFormat ddf1=NumberFormat.getNumberInstance() ; <br /><br /><br />ddf1.setMaximumFractionDigits(2); <br />String s= ddf1.format(x) ; <br />System.out.print(s); <br />} <br />}</p></div><img src ="http://www.blogjava.net/longturi/aggbug/404164.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/longturi/" target="_blank">ZT文萃</a> 2013-09-17 12:22 <a href="http://www.blogjava.net/longturi/archive/2013/09/17/404164.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>