﻿<?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-轻松-随笔分类-JAVA转贴</title><link>http://www.blogjava.net/relax/category/351.html</link><description>记述我学习java的里程</description><language>zh-cn</language><lastBuildDate>Fri, 16 May 2008 02:40:44 GMT</lastBuildDate><pubDate>Fri, 16 May 2008 02:40:44 GMT</pubDate><ttl>60</ttl><item><title>JDK1.5中对XML的简单操作</title><link>http://www.blogjava.net/relax/archive/2008/05/15/200676.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Thu, 15 May 2008 08:44:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2008/05/15/200676.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/200676.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2008/05/15/200676.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/200676.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/200676.html</trackback:ping><description><![CDATA[//TestXML.xml<br />
&lt;?xml version="1.0" encoding="GB2312" ?&gt; <br />
&lt;book&gt; <br />
&lt;title&gt;Java实例一百例&lt;/title&gt; <br />
&lt;page id="1"&gt; <br />
&lt;title&gt;基础知识篇&lt;/title&gt; <br />
&lt;file&gt;base.htm&lt;/file&gt; <br />
&lt;/page&gt; <br />
&lt;page id="3"&gt; <br />
&lt;title&gt;SWING篇&lt;/title&gt; <br />
&lt;file&gt;swing.htm&lt;/file&gt; <br />
&lt;/page&gt; <br />
&lt;page id="28"&gt; <br />
&lt;title&gt;EJB篇&lt;/title&gt; <br />
&lt;file&gt;ejb.htm&lt;/file&gt; <br />
&lt;/page&gt; <br />
&lt;page id="33"&gt; <br />
&lt;title&gt;DOM篇&lt;/title&gt; <br />
&lt;file&gt;xmldom.htm&lt;/file&gt; <br />
&lt;/page&gt; <br />
&lt;/book&gt; <br />
<br />
<br />
//TestXML.java<br />
import javax.xml.parsers.*; <br />
import org.w3c.dom.*; <br />
import java.io.*; <br />
<br />
public class TestXML { <br />
public static void main(String[] args) { <br />
try { <br />
//创建解析工厂 <br />
DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); <br />
//指定DocumentBuilder <br />
DocumentBuilder builder = dbfactory.newDocumentBuilder(); <br />
//从文件构造一个Document，因为XML文件中已经指定了编码，所以这里不必了 <br />
Document doc = builder.parse(new File("TestXML.xml")); <br />
//得到Document的根（节点名：book） <br />
Element root = doc.getDocumentElement(); <br />
System.out.println("根节点标记名：" + root.getTagName()); <br />
<br />
System.out.println("****下面遍历XML元素****"); <br />
//获得page元素 <br />
NodeList list = root.getElementsByTagName("page"); <br />
//遍历page元素 <br />
for (int i=0; i &lt; list.getLength() ; i++) { <br />
//获得page的元素 <br />
Element element = (Element)list.item(i); <br />
//获得ID属性 <br />
String id = element.getAttribute("id"); <br />
//获得title属性 <br />
NodeList titleList = element.getElementsByTagName("title"); <br />
//获得title元素 <br />
Element titleElement = (Element)titleList.item(0); <br />
//获得title元素的第一个值 <br />
String title = titleElement.getFirstChild().getNodeValue(); <br />
//获得file元素名称 <br />
NodeList fileList = element.getElementsByTagName("file"); <br />
//获得file元素 <br />
Element fileElement = (Element)fileList.item(0); <br />
//获得file元素的第一个值 <br />
String file = fileElement.getFirstChild().getNodeValue(); <br />
<br />
System.out.println("ID：" + id + " " + <br />
"标题：" + title + " " + <br />
"文件：" + file); <br />
} <br />
}<br />
catch (Exception e) { <br />
e.printStackTrace(); <br />
} <br />
} <br />
}
<img src ="http://www.blogjava.net/relax/aggbug/200676.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2008-05-15 16:44 <a href="http://www.blogjava.net/relax/archive/2008/05/15/200676.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java.lang.OutOfMemoryError的解決方法集</title><link>http://www.blogjava.net/relax/archive/2008/04/02/190438.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Wed, 02 Apr 2008 11:30:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2008/04/02/190438.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/190438.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2008/04/02/190438.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/190438.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/190438.html</trackback:ping><description><![CDATA[<p><font face="Verdana" color="#000000" size="4">Java虚拟机默认分配64M内存，如果你的应用比较大，超出64M内存，Java虚拟机就会抛出OutOfMemoryError，并停止运行。不管是什么应用（Web应用、Application等），只需要修改你的机器上的运行Java命令，在java&nbsp;xxx命令中添加-Xms(最小使用内存)、-Xmx（最大使用内存）即可解决。当然，这儿的内存容量都是指物理内存，不能超出你的机器的物理内存的总容量。</font></p>
<p><font face="Verdana" color="#000000" size="4">一、Ant使用中的OutOfMemoryError解决：</font></p>
<p><font face="Verdana"><font color="#000000" size="4">到你的Ant的安装目录，在bin子目录中找到ant.bat，使用文字编辑器打开，修改:runAnt处的允许命令，添加如下参数：<br />
<br />
:runAnt<br />
"%_JAVACMD%"&nbsp;-Xms128m&nbsp;-Xmx512m&nbsp;-classpath&nbsp;&#8230;&#8230;<br />
<br />
如果你安装了Jike，使用Jike编译器，则需要修改:runAntWithJikes处的运行命令，同上。</font></font></p>
<p><font face="Verdana"><font color="#000000" size="4">二、tomcat中的内存溢出优化</font></font></p>
<p><font size="4">安装版的：</font></p>
<p>设置的java选项卡有啦。</p>
<p>&nbsp;</p>
<p><font size="4">非安装版的：</font></p>
<p><font size="4">打开编辑catalina.bat，在文件开头处增加如下参数：</font></p>
<p><font face="Verdana"><font color="#000000" size="4">set JAVA_OPTS=-Xms128m -Xmx512m<br />
</font></font></p>
<p><font face="Verdana"><font color="#000000" size="4"><br />
转自:http://blog.csdn.net/zzr173/archive/2006/12/11/1438691.aspx</font></font></p>
<img src ="http://www.blogjava.net/relax/aggbug/190438.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2008-04-02 19:30 <a href="http://www.blogjava.net/relax/archive/2008/04/02/190438.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于提高自己JAVA水平的十大技术讨论</title><link>http://www.blogjava.net/relax/archive/2007/12/21/169224.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Fri, 21 Dec 2007 01:36:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2007/12/21/169224.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/169224.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2007/12/21/169224.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/169224.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/169224.html</trackback:ping><description><![CDATA[　本文列出了当今计算机软件开发和应用领域最重要十种关键
<p><nobr><strong class="kgb" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&ai=BbACgHRZrR4CiIpDE6wORqaVXjL-ZNcCwgIcFwI23AaDRGRABGAEgrYXQDSgUOABQ5-Cz9ARgndnQgZQFqgEKMjAwMDAzNjEyN7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMjIwLzExMTkyNy5odG1sgAIByAL8iYoDqAMB6AO3AvUDAAQAAA&num=1&adurl=http://www.asus.com.cn/EVENT/2007/1026F8/&client=ca-pub-5186439242807756");GgKwClickStat("技术","www.asus.com.cn","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u6280_u672F"' onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u6280_u672F";KeyGate_ads.ShowGgAds(this,"_u6280_u672F",event)' style="border: 0px none ; margin: 0px; padding: 0px; color: #0000ff; font-weight: normal; text-decoration: underline;">技术</strong></nobr>排名，如果你想保证你现在以及未来的几年不失业，那么你最好跟上这些技术的发展。虽然你不必对这十种技术样样精通，但至少应该对它们非常熟悉。</p>
<p>　<strong>　一、XML</strong></p>
<p>　　在十种技术中，最重要的一种技术我想应该非XML莫属。这里不仅仅指XML规范本身，还包括一系列有关的基于XML的语言：主要有XHTML，
XSLT，XSL，DTDs，XML
Schema(XSD)，XPath，XQuery和SOAP.如果你现在还对XML一无所知，那么赶快狂补吧。XML是包含类似于HTML标签的一个文
本文件，在这个文件中定义了一个树型结构来描述它所保存的<nobr><strong class="kgb" onclick='javascript:window.open("http://s4.17luntan.com/ClickPortal/WebClick.aspx?id=-100850&k=%u6570%u636E&siteid=0098295a-e262-40f7-ae50-7a6fbbdb678b&url=http%3A//news.csdn.net/n/20071220/111927.html&gourl=http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2488&parm=78041F5FDC78F73FFC82FDA498786D500E8C3D164E60120E&alliedsiteid=0");' onmouseout="isShowAds = false;isShowAds2 = false" onmouseover='isShowAds = true;isShowAds2 = true;KeyGate_ads.Move(this,"","%u4E00%u4E2A%u771F%u6B63%u7684%u591A%u4EFB%u52A1%u7CFB%u7EDF","-100850","数据","AIX%20V5.3%20%u7CFB%u7EDF%u7BA1%u7406","http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2488", event)' style="border: 0px none ; color: #0000ff; font-weight: normal; text-decoration: underline;">数据</strong></nobr>。</p>
<p>　　XML最大的优点是你既可以在这个文本文件中存储结构化数据，也可以在其中存储非结构化数据——也就是说，它能包含和描述"粗糙的"文档数据，就象它描述"规则的"表格数据一样。</p>
<p>　　XHTML是目前编写HTML的首选方法;因为XHTML本身就是格式良好的XML，与通常畸形的HTML文档相比， XHTML格式文档更容易处理。</p>
<p>　　XSLT和XSL是对XML文档进行转换的语言。它们可以将XML文档转换成各种格式，比如另一个文本文件、PDF文件、HTML文件、逗号分割的文件，或者转换成其它的XML文档。</p>
<p>　　DTDs 和XML Schema用来描述XML文件所包含的数据内容的类型，使你不用编写定制的代码就能对XML文档的内容进行"有效性"检查，使内容强行遵守给出的规则。</p>
<p>　　XPath 和 XQuery是查询语言，用它们可以从XML文档中吸取单个的数据项或者数据项列表。XQuery的功能特别强大，因为它对XPath查询进行了扩展。实际上，XQuery和XML的关系就像SQL之于关系数据库一样。</p>
<p>　　SOAP是Web services间进行通讯的标准协议。你不必知道SOAP协议的所有细节，但是你应该熟悉其常用规则及其工作原理，这样你才能使用它。</p>
<p>　<strong>　二、Web Services</strong></p>
<p>　　Web<nobr><strong class="kgb" onclick='javascript:window.open("http://s4.17luntan.com/ClickPortal/WebClick.aspx?id=-100849&k=%u670D%u52A1&siteid=0098295a-e262-40f7-ae50-7a6fbbdb678b&url=http%3A//news.csdn.net/n/20071220/111927.html&gourl=http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2473&parm=78041F5FDC78F73FFC82FDA498786D500E8C3D164E60120E&alliedsiteid=0");' onmouseout="isShowAds = false;isShowAds2 = false" onmouseover='isShowAds = true;isShowAds2 = true;KeyGate_ads.Move(this,"","%u4E00%u6B3E%u5F00%u6E90%u7684%u6027%u80FD%u6D4B%u8BD5%u5DE5%u5177","-100849","服务","%u5C06%20Ajax%20%u7528%u4E8E%u591A%u5A92%u4F53","http%3A//ibm.csdn.net/ISN_J.aspx%3Faction%3DJMP%26pointid%3D2473", event)' style="border: 0px none ; color: #0000ff; font-weight: normal; text-decoration: underline;">服务</strong></nobr>是XML
流行后的直接产物。因为XML可以描述数据和对象，XML大纲可以保证XML文档数据的有效性，因为XML的基于文本的规范，因而XML文档极其适合于作
为一种跨平台通讯标准的基本格式。如果你还没有接触过Web服务，那么过不了多久你肯定会碰到它，所以必须熟练掌握Web服务，最好是精通它，因为它是迄
今为止应用程序间跨不同种类机器、语言、平台和位置通讯的最简单的一种方式。不管你需不需要它，Web服务都会是将来互用性的主要趋势。</p>
<p>　　XML工作组的John Bosak曾说过："XML使得Java有事可做"，那么，我们也可以说，Web服务使得所有语言都有事可做。Web服务让运行在大型机上的COBOL应用程序与运行在手持设备上的应用程序相互沟通;让Java小应用与。NET<nobr><strong class="kgb" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&ai=BaKT_HRZrR4CiIpDE6wORqaVXj_qTLZ_H-fYDwI23AfDXHBATGBMgrYXQDSgUOABQ7pejEmCd2dCBlAWqAQoyMDAwMDM2MTI3sgENbmV3cy5jc2RuLm5ldMgBAdoBK2h0dHA6Ly9uZXdzLmNzZG4ubmV0L24vMjAwNzEyMjAvMTExOTI3Lmh0bWypAscbcxfeNoI-yALTg-EBqAMB6AO3AvUDAAQAAA&num=19&adurl=http://www.joysuccess.com/proList.aspx&client=ca-pub-5186439242807756");GgKwClickStat("服务器","www.joysuccess.com","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u670D_u52A1_u5668"' onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u670D_u52A1_u5668";KeyGate_ads.ShowGgAds(this,"_u670D_u52A1_u5668",event)' style="border: 0px none ; margin: 0px; padding: 0px; color: #0000ff; font-weight: normal; text-decoration: underline;">服务器</strong></nobr>相互通讯，让桌面应用与Web服务器进行无缝交互，不但为商业数据处理，同时也为商业功能提供了方便的实现——并且这种实现与语言、平台、和位置无关。</p>
<p>　　<strong>三、面向对象编程</strong></p>
<p>　　许多程序员仍然认为OOP乃技术的象牙之塔，但是细细想一下过去十年里在面向对象领域里占据过统治地位的开发语言之后，你就不会这么认为了，
OOP理念从Smalltalk开始，然后蔓延到C++和Pascal(Delphi)，到Java成为真正的主流，几年之后，VB.NET 和
C#的出现可以说是OOP发展到了登峰造极的地步。虽然使用这些语言不必了解OOP的概念，但如果你缺乏一些OOP的基本知识和方法，我想你很难在逐渐疲
软的就业市场中找到工作。</p>
<p><strong>　四、Java， C++， C#， VB.NET</strong> </p>
<p>　　如果你热衷于技术，并且热爱编程，那么我想你应该轻松玩转这些高级语言，我说的玩转并不一定要你成为超级编程高手。而是能看懂用这些语言编写的
代码即可。如果你还有精力用它们编码那就更好了。其实这种机会甚少。但是看代码的机会很多，学习编程的最有效的一种方式就是看源代码——浩如烟海的源代码
中很多都不是用你所钟爱的开发语言编写的。</p>
<p>　　在过去的几年里，各个语言功能的发展基本上都差不多。现在你完全可以用VB.NET来写Windows服务、Web应用或者命令行程序。即使你
只用其中的一种语言写程序。我认为也完全有必要学习另外一种语言，使自己能阅读和理解它们现有的例子代码，并且能将一种语言编写的代码转换成你首选的编程
语言代码。这里列出的四种语言可谓是一个强大的开发语言工具箱，如果你掌握了它们，毫无疑问你一定是一个众人仰慕的高手。这里我要声明一下：那就是我并没
有要忽略和排除其它的高级语言，如：FORTRAN、COBOL、APL、ADA、Perl和Lisp等等，根据你所从事的领域不同，应该选择适合的语言
和工具。</p>
<p>　　<strong>五、JavaScript</strong></p>
<p>　　Java
和JavaScript两者的名字尽管很类似，但它们之间并没有什么关系。为什么一种脚本语言会如此重要，以至于将它列入十种关键技术之一呢?仔细想一下
就知道了，目前所有主流的浏览器都使用JavaScript.如果你要编写Web应用程序，那么JavaScript不可或缺。此外，
JavaScript还能作为一种<nobr><strong class="kgb" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&ai=BAAJVHRZrR4CiIpDE6wORqaVXpeHNHpne-fQDwI23AcCaDBAEGAQgrYXQDSgUOABQuPTpKGCd2dCBlAWgAaugr_oDqgEKMjAwMDAzNjEyN7IBDW5ld3MuY3Nkbi5uZXTIAQHaAStodHRwOi8vbmV3cy5jc2RuLm5ldC9uLzIwMDcxMjIwLzExMTkyNy5odG1sgAIBqQLHG3MX3jaCPsgC7bnWAagDAegDtwL1AwAEAAA&num=4&adurl=http://www.shenmo.sh.cn/product/product-MAGMA.html&client=ca-pub-5186439242807756");GgKwClickStat("服务器端","www.shenmo.sh.cn","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u670D_u52A1_u5668_u7AEF"' onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u670D_u52A1_u5668_u7AEF";KeyGate_ads.ShowGgAds(this,"_u670D_u52A1_u5668_u7AEF",event)' style="border: 0px none ; margin: 0px; padding: 0px; color: #0000ff; font-weight: normal; text-decoration: underline;">服务器端</strong></nobr>的
脚本语言，如将它嵌入在ASP、ASP.NET中，或者嵌入XSLT来扩展功能。目前JavaScript在Mozilla/Netscape中是激活基
于XUL界面的首选语言，它派生出了ActionScript，成为Flash
MX应用的编程语言。还有就是JavaScript极有可能成为未来新设备的脚本语言以及主流应用的宏语言。</p>
<p>　　相比之下，VBScript虽然在微软的产品中得到很好的支持，但从长远来看，没有迹象表明它会有美好前途。微软自己都趋向于用
JavaScript(或者用由JavaScript派生的JScript)来编写其客户端脚本代码。因此，如果你要选择脚本语言，非
JavaScript莫属。</p>
<p>　<strong>　六、Regular Expressions</strong></p>
<p>　　从所周知，关系数据库的查询使用SQL，搜索XML文档用XPath
和XQuery，而正则表达式则用来搜索纯文本。例如，你可以用一个命令来查找或删除HTML格式文件中的注释内容。大家都用过"IndexOf"、
"InStr"以及"Like"这些内建在JavaScript或VB中的文本搜索函数，这些函数虽然很容易使用，但是它们的功能却无法与正则表达式同日
而语——现在每一种主流的开发语言都提供对正则表达式的存取。尽管有人认为正则表达式本身的读写艰涩难懂，但毕竟它的功能强大，使用它的领域也越来越多。</p>
<p>　　<strong>七、Design Patterns</strong></p>
<p>　　就像OOP通过创建和分类对象来简化编程一样，设计模式将普通的对象交互分类成指定的模型，这是一个从一般到具体的过程。OOP的成分使用得越多，设计模式就显得越有用武之地。所以你必须理解它们，跟上其总体理论的发展。</p>
<p>　<strong>　八、Flash MX</strong></p>
<p>　　当你需要比HTML和CSS所能提供的更多的客户端图形和编程能力时，Flash是最佳选择。在Flash中编程比用Java小应用或者。NET代码来得快得多，也容易得多。</p>
<p>　　在最新版本中(MX)，Flash不仅可以画图和进行动画打包，它还是个高度的可编程应用环境。具备强大的与SOAP
Web服务沟通的能力，可以调用运行在远端服务器上的ColdFusion、Java或。NET代码。可以说Flash几乎无处不在，包括手持设备、置顶
盒、甚至是新的平板电脑，你到处都可以见到它的身影，所以使用它实际上可以扩展和延伸你的应用程序使用领域。</p>
<p><strong>　九、Linux/Windows</strong> </p>
<p>　　这是当今PCs机<nobr><strong class="kgb" onclick='javascript:window.open("http://pagead2.googlesyndication.com/pagead/iclk?sa=l&ai=B9pIRHRZrR4CiIpDE6wORqaVXuarQMI3Ru_8DwI23AdDZERAJGAkgrYXQDSgUOABQrc7vFWCd2dCBlAWqAQoyMDAwMDM2MTI3sgENbmV3cy5jc2RuLm5ldMgBAdoBK2h0dHA6Ly9uZXdzLmNzZG4ubmV0L24vMjAwNzEyMjAvMTExOTI3Lmh0bWypAscbcxfeNoI-yALF6uMDqAMB6AO3AvUDAAQAAA&num=9&adurl=http://www.hunter2006.com/pcmonitor.htm&client=ca-pub-5186439242807756");GgKwClickStat("操作系统","www.hunter2006.com","afc","2000036127");' onmouseout='isShowGg = false;InTextAds_GgLayer="_u64CD_u4F5C_u7CFB_u7EDF"' onmouseover='isShowAds = false;isShowAds2 = false;isShowGg = true;InTextAds_GgLayer="_u64CD_u4F5C_u7CFB_u7EDF";KeyGate_ads.ShowGgAds(this,"_u64CD_u4F5C_u7CFB_u7EDF",event)' style="border: 0px none ; margin: 0px; padding: 0px; color: #0000ff; font-weight: normal; text-decoration: underline;">操作系统</strong></nobr>的
两大阵容，如果你想在计算机行业里混，就一定要熟悉它们。对于Linux，最好能自己安装，配置，下载它的图形用户界面以及一些应用程序。自己安装
Apache并会编写Web应用程序。要清醒地认识到这个世界除了Windows之外，还有Linux的存在。并且这种局面将会长期存在。反过来，如果你
是一个死忠的Linux开发者，不要再继续对Windows的憎恶，要相互学习，取长补短，看看Windows有什么好的东东可以采纳。记住
Windows仍然是桌面之王。</p>
<p>　　谁也说不准你们公司什么时候会决定从Linux转向Windows，或者从Windows转向Linux.谁也说不准什么时候你会跳槽跑到另外
一个使用不同平台的公司上班——或者即便不跳槽，也有可能在不同平台上开始另外一个杀手级项目——所以最好在每个平台上都积累一些经验，而不要在一棵树上
吊死。</p>
<p><strong>　　十、SQL</strong></p>
<p>　　尽管SQL在当今众多的技术中已不是什么新东西，而且在未来的十年里它的作用很有可能被削弱，甚至整个被淘汰，但它仍然是一种基本技能——别看
它是一种基本技能，至今仍有许多开发人员不懂什么是SQL或对它了解不多。不要指望基于图形用户界面的SQL构造器会帮你的忙，还是自己亲手写SQL查询
吧，确定你掌握了SQL的基本语法。现在理解了SQL，不仅对以后学习XQuery有所裨益，而且可以使你很快找到简化或改进当前开发项目的途径。</p>
<p>　　<strong>尾声：培养对技术的好奇心</strong></p>
<p>　　其实，不管技术的发展趋势如何，每个人最重要的一个技能是好奇心。敢于面对挑战，在你目前或未来的工作中，新语言或新技术可能很重要，也可能不
怎么重要，你所学习的东西并不一定非要针对你的工作。不要怕失败，任何新的技术对初学者来说都是困难的。大多数的失败都可以归咎于本身急功近利，希望速
成。俗话说——千里之行，始于足下，应该脚踏实地，一步一个脚印地往前走。不要让时间来左右你行动，而是要利用时间来关注、研究、测试新的开发技术和工
具。<br />
</p>
<p><br />
</p>
<p>注：以上内容来自网络，本人不承担任何连带责任</p>
<p>转自：赛迪网</p>
<img src ="http://www.blogjava.net/relax/aggbug/169224.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2007-12-21 09:36 <a href="http://www.blogjava.net/relax/archive/2007/12/21/169224.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java开发者的十大戒律 </title><link>http://www.blogjava.net/relax/archive/2007/12/21/169217.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Fri, 21 Dec 2007 01:23:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2007/12/21/169217.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/169217.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2007/12/21/169217.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/169217.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/169217.html</trackback:ping><description><![CDATA[<div><dl><dt>
<p>有许多标准和实践准则可适用于Java开发者，但此处要说的，是每个Java开发者需坚守的基本原则。</p>
</dt></dl></div>
<p>　　<strong>一、为<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">代码</strong>加注释</strong>。虽然每个人都知道这点，但有时却不自觉忘了履行，今天你&#8220;忘了&#8221;加注释了吗?虽然注释对 程序的功能没什么&#8220;贡献&#8221;，但过一段<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">时间</strong>，
比如说两星期之后或者更长，回过头来看看自己的代码，说不定已经记不住它是干什么的了。如果这些代码是你个人的，那还算是走运了，不幸的是，当然了，大多
数时候都是别人的不幸，很多时候大家都是在为公司写代码，写代码的人也许早已经离开了公司，但别忘了一句古话，有来有往嘛，为他人，也为我们自己，请为你
的代码加上注释。 </p>
<p>　　<strong>二、不要让事情复杂化</strong>。<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">程序员</strong>有时候总是对<strong style="border: 0px none ; font-weight: normal; color: #0000ff; text-decoration: underline;">简单</strong>问题想出复杂的<strong style="border: 0px none ; font-weight: normal; color: #0000ff; text-decoration: underline;">解决方案</strong>，
比如说，在只有五个用户的程序中引入EJB、对程序实现了并不需要的框架(framework)，之类的还有属性文件、面向对象解决方案、多线程等等。为
什么要这样做呢?也许我们并不知道是否这样会更好，但这样做也许可以学到一些新东西，或者让自己更感兴趣一些。如果是不知道为什么这样做，建议多请教经验
丰富的程序员，如果是为了个人的目的，麻烦让自己更专业一点。 </p>
<p>　　<strong>三、始终牢记</strong>——&#8220;少即是好(Less is more)并不总是对的&#8221;。代码效率虽然很重要，但在许多解决方案中，编写更少的代码并不能改善这些代码的效率，请看下面这个简单的例子： </p>
<p> </p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(newStatusCode.equals("SD")&nbsp;&amp;&amp;&nbsp;(sellOffDate&nbsp;==&nbsp;null&nbsp;|| <br />
            todayDate.compareTo(sellOffDate)&lt;0&nbsp;||&nbsp;(lastUsedDate&nbsp;!=&nbsp;null&nbsp;&amp;&amp; <br />
            todayDate.compareTo(lastUsedDate)&gt;0))&nbsp;|| <br />
            (newStatusCode.equals("OBS")&nbsp;&amp;&amp;&nbsp;(OBSDate&nbsp;==&nbsp;null&nbsp;|| <br />
            todayDate.compareTo(OBSDate)&lt;0))){ <br />
            newStatusCode&nbsp;=&nbsp;"NYP"; <br />
            }</td>
        </tr>
    </tbody>
</table>
<p>　　能看明白if条件语句是干什么的吗?能想出来是谁写的这段代码吗?如果把它分成两段独立的if语句，是不是更容易理解呢，下面是修改后的代码： </p>
<p> </p>
<table style="border: 1px dotted #cccccc; table-layout: auto;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(newStatusCode.equals("SD")&nbsp;&amp;&amp;&nbsp;(sellOffDate&nbsp;==&nbsp;null&nbsp;|| <br />
            todayDate.compareTo(sellOffDate)&lt;0&nbsp;||&nbsp;(lastUsedDate&nbsp;!=&nbsp;null&nbsp;&amp;&amp; <br />
            todayDate.compareTo(lastUsedDate)&gt;0))){ <br />
            newStatusCode&nbsp;=&nbsp;"NYP"; <br />
            }else <br />
            if(newStatusCode.equals("OBS")&nbsp;&amp;&amp;&nbsp;(OBSDate&nbsp;==&nbsp;null&nbsp;|| <br />
            todayDate.compareTo(OBSDate)&lt;0)) <br />
            { <br />
            newStatusCode&nbsp;=&nbsp;"NYP"; <br />
            }</td>
        </tr>
    </tbody>
</table>
<p>　　是不是读起来容易多了呢，在此只是多加了一个if和两个花括号，但代码的可读性与可理解性就一下子提高了一大截。 </p>
<p>　　<strong>四、请不要硬编码</strong>。开发者经常有意&#8220;忘记&#8221;或忽略掉这点，因为有些时候开发日程逼得实在太紧。其实，多写一行定义静态变量的代码能花多少时间呢? </p>
<p> </p>
<table style="border: 1px dotted #cccccc; table-layout: auto;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3"><strong><font color="#990000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></strong>public&nbsp;class&nbsp;A&nbsp;{ <br />
            public&nbsp;static&nbsp;final&nbsp;String&nbsp;S_CONSTANT_ABC&nbsp;=&nbsp;"ABC"; <br />
            public&nbsp;boolean&nbsp;methodA(String&nbsp;sParam1){ <br />
            if&nbsp;(A.S_CONSTANT_ABC.equalsIgnoreCase(sParam1)){ <br />
            return&nbsp;true; <br />
            } <br />
            return&nbsp;false; <br />
            } <br />
            }</td>
        </tr>
    </tbody>
</table>
<p>　　现在，每次需要将&#8220;ABC&#8221;与其他变量进行比较时，不必记住实际代码，直接引用A.S_CONSTANT_ABC就行了，而且在今后需要进行修改时，也可在一处修改，不会翻遍整个源代码逐个修改了。 </p>
<p>　　<strong>五、不要&#8220;创造&#8221;自己的框架(framework)。</strong>确切来说，有数以千计的各种框架存在，而且大多数是开 源的，这些框架都是优秀的解决方案，可用于日常<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">程序开发</strong>中，
我们只需使用这些框架的最新版本就行了，至少表面上要跟上形势吧。被大家广为接受的最为明显的一个例子就是Struts了，这个开源web框架非常适合用
在基于web的应用程序中。是不是想开发出自己的Struts呢，还是省点力气吧，回头看看第二条——不要让事情复杂化。另外，如果正在开发的程序只有3
个窗口，就不要使用Struts了，对这种程序来说，不需要那么多的&#8220;控制&#8221;。 </p>
<p>　　<strong>六、不要使用println及字符串连接</strong>。通常为了调试方便，开发者喜欢在可能的所有地方都加上 System.out.println，也许还会提醒自己回过头来再来删除，但有些时候，经常会忘了删除或者不愿意删除它们。既然使用 System.out.println是为了<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">测试</strong>，那么测试完之后，为什么还要留着它们呢，因为在删除时，很可能会删除掉真正有用的代码，所以不能低估 System.out.println危害啊，请看下面的代码： </p>
<p> </p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;class&nbsp;BadCode&nbsp;{ <br />
            public&nbsp;static&nbsp;void&nbsp;calculationWithPrint(){ <br />
            double&nbsp;someValue&nbsp;=&nbsp;0D; <br />
            for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++)&nbsp;{ <br />
            System.out.println(someValue&nbsp;=&nbsp;someValue&nbsp;+&nbsp;i); <br />
            } <br />
            } <br />
            public&nbsp;static&nbsp;void&nbsp;calculationWithOutPrint(){ <br />
            double&nbsp;someValue&nbsp;=&nbsp;0D; <br />
            for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++)&nbsp;{ <br />
            someValue&nbsp;=&nbsp;someValue&nbsp;+&nbsp;i; <br />
            } <br />
            } <br />
            public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;[]&nbsp;n)&nbsp;{ <br />
            BadCode.calculationWithPrint(); <br />
            BadCode.calculationWithOutPrint(); <br />
            } <br />
            }</td>
        </tr>
    </tbody>
</table>
<p>　　从测试中可以发现，方法calculationWithOutPrint()执行用了0.001204秒，作为对比，方法calculationWithPrint()执行可是用了10.52秒。 </p>
<p>　　要避免浪费CPU时间，最好的方法是引入像如下的包装方法： </p>
<p> </p>
<table style="border: 1px dotted #cccccc; table-layout: auto;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">
            <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;class&nbsp;BadCode&nbsp;{ <br />
            public&nbsp;static&nbsp;final&nbsp;int&nbsp;DEBUG_MODE&nbsp;=&nbsp;1; <br />
            public&nbsp;static&nbsp;final&nbsp;int&nbsp;PRODUCTION_MODE&nbsp;=&nbsp;2; <br />
            public&nbsp;static&nbsp;void&nbsp;calculationWithPrint(int&nbsp;logMode){ <br />
            double&nbsp;someValue&nbsp;=&nbsp;0D; <br />
            for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;10000;&nbsp;i++)&nbsp;{ <br />
            someValue&nbsp;=&nbsp;someValue&nbsp;+&nbsp;i; <br />
            myPrintMethod(logMode,&nbsp;someValue); <br />
            } <br />
            } <br />
            public&nbsp;static&nbsp;void&nbsp;myPrintMethod(int&nbsp;logMode,&nbsp;double&nbsp;value)&nbsp;{ <br />
            if&nbsp;(logMode&nbsp;&gt;&nbsp;BadCode.DEBUG_MODE)&nbsp;{&nbsp;return;&nbsp;} <br />
            System.out.println(value); <br />
            } <br />
            public&nbsp;static&nbsp;void&nbsp;main(String&nbsp;[]&nbsp;n)&nbsp;{ <br />
            BadCode.calculationWithPrint(BadCode.PRODUCTION_MODE); <br />
            } <br />
            }</p>
            </td>
        </tr>
    </tbody>
</table>
<p>　　另外，字符串连接也是浪费CPU时间的一个大头，请看下面的示例代码： </p>
<p> </p>
<table style="border: 1px dotted #cccccc; table-layout: auto;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public&nbsp;static&nbsp;void&nbsp;concatenateStrings(String&nbsp;startingString)&nbsp;{ <br />
            for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;20;&nbsp;i++)&nbsp;{ <br />
            startingString&nbsp;=&nbsp;startingString&nbsp;+&nbsp;startingString; <br />
            } <br />
            } <br />
            public&nbsp;static&nbsp;void&nbsp;concatenateStringsUsingStringBuffer(String&nbsp;startingString)&nbsp;{ <br />
            StringBuffer&nbsp;sb&nbsp;=&nbsp;new&nbsp;StringBuffer(); <br />
            sb.append(startingString); <br />
            for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;20;&nbsp;i++)&nbsp;{ <br />
            sb.append(sb.toString()); <br />
            } <br />
            }</td>
        </tr>
    </tbody>
</table>
<p>　　在测试中可发现，使用StringBuffer的方法只用了0.01秒执行完毕，而使用连接的方法则用了0.08秒，选择显而易见了。 </p>
<p>　　<strong>七、多关注GUI(用户界面)。</strong>再三强调，GUI对商业客户来说，与程序的功能及效率同等重要，GUI是一 个成功程序的最基本部分，而很多IT经理往往都没注意到GUI的重要性。在现实生活中，许多公司可能为了节省开支，没有雇用那些有着<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">设计</strong>&#8220;用户友好&#8221;界面 丰富经验的网页设计者，此时Java开发者只能依赖他们自身的HTML基本功及在此领域有限的知识，结果，很多开发出来的程序都是&#8220;<strong style="border: 0px none ; font-weight: normal; color: #0000ff; text-decoration: underline;">计算机</strong>友好&#8221;甚于&#8220;用 户友好&#8221;。很少有开发者同时精通<strong style="border: 0px none ; font-weight: normal; color: #0000ff; text-decoration: underline;">软件开发</strong>及GUI设计，如果你在公司&#8220;不幸&#8221;被分配负责程序界面，就应该遵守下面三条原则： </p>
<p>　　1、 不要再发明一次轮子，即不做无用功。现有的程序可能会有类似的界面需求。 </p>
<p>　　2、 先创建一个原型。这是非常重要一步，用户一般想看到他们将使用的东西，而且可以先利用这个原型征求用户的意见，再慢慢修改成用户想要的样子。 </p>
<p>　　3、 学会换位思考。换句话来说，就是从用户的角度来审查程序的需求。举例来讲，一个汇总的窗口可以跨页或者不跨页，作为一个软件开发者，可能会倾向于不跨页，因为这样简单一些。但是，从用户的角度来看，可能不希望看到上百行数据都挤在同一页上。 </p>
<p>　　<strong>八、文档需求不放松</strong>。每个商业需求都必须记录在案，这可能听上去像童话，似乎在现实生活中很难实现。而我们要做的是，不管开发时间多紧迫，不管最终期限多临近，对每个商业需求都必须记录在案。 </p>
<p>　　<strong>九、单元测试、单元测试、单元测试</strong>。关于什么是单元测试的最好方法，在此不便细说，只是强调，单元测试一定要完成，这也是<strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">编程</strong>中最基本的原则。当然了，如果有人帮你做单元测试自然是最好，如果没有，就自己来做吧，当创建一个单元测试计划时，请遵守以下三条最基本的原则： </p>
<p>　　1、 先于编写类代码之前编写单元测试。 </p>
<p>　　2、 记录单元测试中的代码注释。 </p>
<p>　　3、 测试所有执行关键功能的公有方法，这里不是指set和get方法，除非它们是以自己独特方式执行set和get方法。 </p>
<p>　　<strong>十、质量，而不是数量</strong>。有些时候因为产品问题、期限紧迫、或一些预料之外的事情，导致常常不能按时下班，但一般而言，公司不会因为雇员经常加班而对之表扬和奖励，公司只看重高质量的工作。如果遵守了前九条原则，你会发现自己写出的代码bug少且可维护性高，无形中质量提高了一大步。</p>
<p>注：以上内容来自网络，本人不承担任何连带责任</p>
<p>文章转自：<br />
</p>
<br />
<p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1956723</p>
<img src ="http://www.blogjava.net/relax/aggbug/169217.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2007-12-21 09:23 <a href="http://www.blogjava.net/relax/archive/2007/12/21/169217.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单元测试利器 JUnit 4</title><link>http://www.blogjava.net/relax/archive/2007/03/05/101945.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Mon, 05 Mar 2007 08:15:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2007/03/05/101945.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/101945.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2007/03/05/101945.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/101945.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/101945.html</trackback:ping><description><![CDATA[
		<p>本文主要介绍了如何使用 JUnit 4 提供的各种功能开展有效的单元测试，并通过一个实例演示了如何使用 Ant 执行自动化的单元测试。本文假设读者对 Eclipse 下进行 Java 开发有一定的经验，并了解 Java 5 中的注解（annotation）特性。</p>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>
				<a name="N10053">
						<span class="atitle">引言</span>
				</a>
		</p>
		<p>毋庸置疑，程序员要对自己编写的代码负责，您不仅要保证它能通过编译，正常地运行，而且要满足需求和设计预期的效果。单元测试正是验证代码行为是否满足预期的有效手段之一。但不可否认，做测试是件很枯燥无趣的事情，而一遍又一遍的测试则更是让人生畏的工作。幸运的是，单元测试工具 JUnit 使这一切变得简单艺术起来。</p>
		<p>JUnit 是 Java 社区中知名度最高的单元测试工具。它诞生于 1997 年，由 Erich Gamma 和 Kent Beck 共同开发完成。其中 Erich Gamma 是经典著作《设计模式：可复用面向对象软件的基础》一书的作者之一，并在 Eclipse 中有很大的贡献；Kent Beck 则是一位极限编程（XP）方面的专家和先驱。</p>
		<p>麻雀虽小，五脏俱全。JUnit 设计的非常小巧，但是功能却非常强大。Martin Fowler 如此评价 JUnit：在软件开发领域，从来就没有如此少的代码起到了如此重要的作用。它大大简化了开发人员执行单元测试的难度，特别是 JUnit 4 使用 Java 5 中的注解（annotation）使测试变得更加简单。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="major2">
						<span class="atitle">JUnit 4 初体验</span>
				</a>
		</p>
		<p>在开始体验 JUnit 4 之前，我们需要以下软件的支持：</p>
		<ul>
				<li>Eclipse：最为流行的 IDE，它全面集成了 JUnit，并从版本 3.2 开始支持 JUnit 4。当然 JUnit 并不依赖于任何 IDE。您可以从 <a href="http://www.eclipse.org/"><font color="#996699">http://www.eclipse.org/</font></a> 上下载最新的 Eclipse 版本。 
</li>
				<li>Ant：基于 Java 的开源构建工具，您可以在 <a href="http://ant.apache.org/"><font color="#5c81a7">http://ant.apache.org/</font></a> 上得到最新的版本和丰富的文档。Eclipse 中已经集成了 Ant，但是在撰写本文时，Eclipse 使用的 Ant 版本较低（必需 1.7 或者以上版本），不能很好的支持 JUnit 4。 
</li>
				<li>JUnit：它的官方网站是 <a href="http://www.junit.org/"><font color="#5c81a7">http://www.junit.org/</font></a>。您可以从上面获取关于 JUnit 的最新消息。如果您和本文一样在 Eclipse 中使用 JUnit，就不必再下载了。 </li>
		</ul>
		<p>首先为我们的体验新建一个 Java 工程 —— coolJUnit。现在需要做的是，打开项目 coolJUnit 的属性页 -&gt; 选择“Java Build Path”子选项 -&gt; 点选“Add Library…”按钮 -&gt; 在弹出的“Add Library”对话框中选择 JUnit（<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure001"><font color="#5c81a7">图1</font></a>），并在下一页中选择版本 4.1 后点击“Finish”按钮。这样便把 JUnit 引入到当前项目库中了。</p>
		<br />
		<a name="figure001">
				<b>图1 为项目添加 JUnit 库</b>
		</a>
		<br />
		<img alt="图1 为项目添加 JUnit 库" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure001.jpg" />
		<br />
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N1009A">
																				<b>请注意 JDK 的版本</b>
																		</a>
																		<br />
																		<p>JUnit 4.1 是基于 Java 5 的升级版本，它使用了 Tiger 中的很多新特性来简化原有的使用方式。正因为如此，它并不能直接运行在 JDK1.4.x 版本上。如果您需要在 JDK1.4.x 版本使用 JUnit 的话，请使用 3.8.1 版本。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>可以开始编写单元测试了吗？等等……，您打算把单元测试代码放在什么地方呢？把它和被测试代码混在一起，这显然会照成混乱，因为单元测试代码是不会出现在最终产品中的。建议您分别为单元测试代码与被测试代码创建单独的目录，并保证测试代码和被测试代码使用相同的包名。这样既保证了代码的分离，同时还保证了查找的方便。遵照这条原则，我们在项目 coolJUnit 根目录下添加一个新目录 testsrc，并把它加入到项目源代码目录中（加入方式见 <a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure002"><font color="#5c81a7">图2</font></a>）。</p>
		<br />
		<a name="figure002">
				<b>图2 修改项目源代码目录</b>
		</a>
		<br />
		<img alt="图2 修改项目源代码目录" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure002.jpg" />
		<br />
		<p>现在我们得到了一条 JUnit 的最佳实践：单元测试代码和被测试代码使用一样的包，不同的目录。</p>
		<p>一切准备就绪，一起开始体验如何使用 JUnit 进行单元测试吧。下面的例子来自笔者的开发实践：工具类 WordDealUtil 中的静态方法 wordFormat4DB 是专用于处理 Java 对象名称向数据库表名转换的方法（您可以在代码注释中可以得到更多详细的内容）。下面是第一次编码完成后大致情形：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package com.ai92.cooljunit;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 对名称、地址等字符串格式的内容进行格式检查
 * 或者格式化的工具类
 * 
 * @author Ai92
 */
public class WordDealUtil {

	/**
	 * 将Java对象名称（每个单词的头字母大写）按照
	 * 数据库命名的习惯进行格式化
	 * 格式化后的数据为小写字母，并且使用下划线分割命名单词
	 * 
	 * 例如：employeeInfo 经过格式化之后变为 employee_info
	 * 
	 * @param name	Java对象名称
	 */
	public static String wordFormat4DB(String name){
		Pattern p = Pattern.compile("[A-Z]");
		Matcher m = p.matcher(name);
		StringBuffer sb = new StringBuffer();
		
		while(m.find()){
			m.appendReplacement(sb, "_"+m.group());
		}
		return m.appendTail(sb).toString().toLowerCase();
	}
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>它是否能按照预期的效果执行呢？尝试为它编写 JUnit 单元测试代码如下：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package com.ai92.cooljunit;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class TestWordDealUtil {
	//测试wordFormat4DB正常运行的情况
	@Test public void wordFormat4DBNormal(){
		String target = "employeeInfo";
		String result = WordDealUtil.wordFormat4DB(target);
		
		assertEquals("employee_info", result);
	}
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>很普通的一个类嘛！测试类 TestWordDealUtil 之所以使用“Test”开头，完全是为了更好的区分测试类与被测试类。测试方法 wordFormat4DBNormal 调用执行被测试方法 WordDealUtil.wordFormat4DB，以判断运行结果是否达到设计预期的效果。需要注意的是，测试方法 wordFormat4DBNormal 需要按照一定的规范书写：</p>
		<ol>
				<li>测试方法必须使用注解 org.junit.Test 修饰。 
</li>
				<li>测试方法必须使用 public void 修饰，而且不能带有任何参数。 </li>
		</ol>
		<p>测试方法中要处理的字符串为“employeeInfo”，按照设计目的，处理后的结果应该为“employee_info”。assertEquals 是由 JUnit 提供的一系列判断测试结果是否正确的静态断言方法（位于类 org.junit.Assert 中）之一，我们使用它将执行结果 result 和预期值“employee_info”进行比较，来判断测试是否成功。</p>
		<p>看看运行结果如何。在测试类上点击右键，在弹出菜单中选择 Run As JUnit Test。运行结果如<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure003"><font color="#5c81a7">下图</font></a>所示：</p>
		<br />
		<a name="figure003">
				<b>图3 JUnit 运行成功界面</b>
		</a>
		<br />
		<img alt="图3 JUnit 运行成功界面" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure003.jpg" />
		<br />
		<p>绿色的进度条提示我们，测试运行通过了。但现在就宣布代码通过了单元测试还为时过早。记住：您的单元测试代码不是用来证明您是对的，而是为了证明您没有错。因此单元测试的范围要全面，比如对边界值、正常值、错误值得测试；对代码可能出现的问题要全面预测，而这也正是需求分析、详细设计环节中要考虑的。显然，我们的测试才刚刚开始，继续补充一些对特殊情况的测试：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">public class TestWordDealUtil {
	……
	//测试 null 时的处理情况
	@Test public void wordFormat4DBNull(){
		String target = null;
		String result = WordDealUtil.wordFormat4DB(target);
		
		assertNull(result);
	}
	
	//测试空字符串的处理情况
	@Test public void wordFormat4DBEmpty(){
		String target = "";
		String result = WordDealUtil.wordFormat4DB(target);
		
		assertEquals("", result);
	}

	//测试当首字母大写时的情况
	@Test public void wordFormat4DBegin(){
		String target = "EmployeeInfo";
		String result = WordDealUtil.wordFormat4DB(target);
		
		assertEquals("employee_info", result);
	}
	
	//测试当尾字母为大写时的情况
	@Test public void wordFormat4DBEnd(){
		String target = "employeeInfoA";
		String result = WordDealUtil.wordFormat4DB(target);
		
		assertEquals("employee_info_a", result);
	}
	
	//测试多个相连字母大写时的情况
	@Test public void wordFormat4DBTogether(){
		String target = "employeeAInfo";
		String result = WordDealUtil.wordFormat4DB(target);
		
		assertEquals("employee_a_info", result);
	}
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>再次运行测试。很遗憾，JUnit 运行界面提示我们有两个测试情况未通过测试（<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure004"><font color="#5c81a7">图4</font></a>）——当首字母大写时得到的处理结果与预期的有偏差，造成测试失败（failure）；而当测试对 null 的处理结果时，则直接抛出了异常——测试错误（error）。显然，被测试代码中并没有对首字母大写和 null 这两种特殊情况进行处理，修改如下：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">//修改后的方法wordFormat4DB
/**
	 * 将Java对象名称（每个单词的头字母大写）按照
	 * 数据库命名的习惯进行格式化
	 * 格式化后的数据为小写字母，并且使用下划线分割命名单词
	 * 如果参数name为null，则返回null
	 * 
	 * 例如：employeeInfo 经过格式化之后变为 employee_info
	 * 
	 * @param name Java对象名称
	 */
	public static String wordFormat4DB(String name){
		
		if(name == null){
			return null;
		}
		
		Pattern p = Pattern.compile("[A-Z]");
		Matcher m = p.matcher(name);
		StringBuffer sb = new StringBuffer();
		
		while(m.find()){
			if(m.start() != 0)
				m.appendReplacement(sb, ("_"+m.group()).toLowerCase());
		}
		return m.appendTail(sb).toString().toLowerCase();
	}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<a name="figure004">
				<b>图4 JUnit 运行失败界面</b>
		</a>
		<br />
		<img alt="图4 JUnit 运行失败界面" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure004.jpg" />
		<br />
		<p>JUnit 将测试失败的情况分为两种：failure 和 error。Failure 一般由单元测试使用的断言方法判断失败引起，它表示在测试点发现了问题；而 error 则是由代码异常引起，这是测试目的之外的发现，它可能产生于测试代码本身的错误（测试代码也是代码，同样无法保证完全没有缺陷），也可能是被测试代码中的一个隐藏的bug。</p>
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="N1010C">
																				<b>请牢记！</b>
																		</a>
																		<br />
																		<p>请牢记这一条 JUnit 最佳实践：测试任何可能的错误。单元测试不是用来证明您是对的，而是为了证明您没有错。</p>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>啊哈，再次运行测试，绿条又重现眼前。通过对 WordDealUtil.wordFormat4DB 比较全面的单元测试，现在的代码已经比较稳定，可以作为 API 的一部分提供给其它模块使用了。</p>
		<p>不知不觉中我们已经使用 JUnit 漂亮的完成了一次单元测试。可以体会到 JUnit 是多么轻量级，多么简单，根本不需要花心思去研究，这就可以把更多的注意力放在更有意义的事情上——编写完整全面的单元测试。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1011B">
						<span class="atitle">JUnit 深入</span>
				</a>
		</p>
		<p>当然，JUnit 提供的功能决不仅仅如此简单，在接下来的内容中，我们会看到 JUnit 中很多有用的特性，掌握它们对您灵活的编写单元测试代码非常有帮助。</p>
		<p>
				<a name="N10125">
						<span class="smalltitle">
								<strong>
										<font face="Arial">Fixture</font>
								</strong>
						</span>
				</a>
		</p>
		<p>何谓 Fixture？它是指在执行一个或者多个测试方法时需要的一系列公共资源或者数据，例如测试环境，测试数据等等。在编写单元测试的过程中，您会发现在大部分的测试方法在进行真正的测试之前都需要做大量的铺垫——为设计准备 Fixture 而忙碌。这些铺垫过程占据的代码往往比真正测试的代码多得多，而且这个比率随着测试的复杂程度的增加而递增。当多个测试方法都需要做同样的铺垫时，重复代码的“坏味道”便在测试代码中弥漫开来。这股“坏味道”会弄脏您的代码，还会因为疏忽造成错误，应该使用一些手段来根除它。</p>
		<p>JUnit 专门提供了设置公共 Fixture 的方法，同一测试类中的所有测试方法都可以共用它来初始化 Fixture 和注销 Fixture。和编写 JUnit 测试方法一样，公共 Fixture 的设置也很简单，您只需要：</p>
		<ol>
				<li>使用注解 org,junit.Before 修饰用于初始化 Fixture 的方法。 
</li>
				<li>使用注解 org.junit.After 修饰用于注销 Fixture 的方法。 
</li>
				<li>保证这两种方法都使用 public void 修饰，而且不能带有任何参数。 </li>
		</ol>
		<p>遵循上面的三条原则，编写出的代码大体是这个样子：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">//初始化Fixture方法
@Before public void init(){……}

//注销Fixture方法
@After public void destroy(){……}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这样，在每一个测试方法执行之前，JUnit 会保证 init 方法已经提前初始化测试环境，而当此测试方法执行完毕之后，JUnit 又会调用 destroy 方法注销测试环境。注意是每一个测试方法的执行都会触发对公共 Fixture 的设置，也就是说使用注解 Before 或者 After 修饰的公共 Fixture 设置方法是方法级别的（<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure005"><font color="#5c81a7">图5</font></a>）。这样便可以保证各个独立的测试之间互不干扰，以免其它测试代码修改测试环境或者测试数据影响到其它测试代码的准确性。</p>
		<br />
		<a name="figure005">
				<b>图5 方法级别 Fixture 执行示意图</b>
		</a>
		<br />
		<img alt="图5 方法级别 Fixture 执行示意图" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure005.gif" />
		<br />
		<p>可是，这种 Fixture 设置方式还是引来了批评，因为它效率低下，特别是在设置 Fixture 非常耗时的情况下（例如设置数据库链接）。而且对于不会发生变化的测试环境或者测试数据来说，是不会影响到测试方法的执行结果的，也就没有必要针对每一个测试方法重新设置一次 Fixture。因此在 JUnit 4 中引入了类级别的 Fixture 设置方法，编写规范如下：</p>
		<ol>
				<li>使用注解 org,junit.BeforeClass 修饰用于初始化 Fixture 的方法。 
</li>
				<li>使用注解 org.junit.AfterClass 修饰用于注销 Fixture 的方法。 
</li>
				<li>保证这两种方法都使用 public static void 修饰，而且不能带有任何参数。 </li>
		</ol>
		<p>类级别的 Fixture 仅会在测试类中所有测试方法执行之前执行初始化，并在全部测试方法测试完毕之后执行注销方法（<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure006"><font color="#5c81a7">图6</font></a>）。代码范本如下：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">//类级别Fixture初始化方法
@BeforeClass public static void dbInit(){……}
	
//类级别Fixture注销方法
	@AfterClass public static void dbClose(){……}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<a name="figure006">
				<b>图6 类级别 Fixture 执行示意图</b>
		</a>
		<br />
		<img alt="图6 类级别 Fixture 执行示意图" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure006.gif" />
		<br />
		<p>
				<a name="N1017E">
						<span class="smalltitle">
								<strong>
										<font face="Arial">异常以及时间测试</font>
								</strong>
						</span>
				</a>
		</p>
		<p>注解 org.junit.Test 中有两个非常有用的参数：expected 和 timeout。参数 expected 代表测试方法期望抛出指定的异常，如果运行测试并没有抛出这个异常，则 JUnit 会认为这个测试没有通过。这为验证被测试方法在错误的情况下是否会抛出预定的异常提供了便利。举例来说，方法 supportDBChecker 用于检查用户使用的数据库版本是否在系统的支持的范围之内，如果用户使用了不被支持的数据库版本，则会抛出运行时异常 UnsupportedDBVersionException。测试方法 supportDBChecker 在数据库版本不支持时是否会抛出指定异常的单元测试方法大体如下：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">@Test(expected=UnsupportedDBVersionException.class)
	public void unsupportedDBCheck(){
		……
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>注解 org.junit.Test 的另一个参数 timeout，指定被测试方法被允许运行的最长时间应该是多少，如果测试方法运行时间超过了指定的毫秒数，则JUnit认为测试失败。这个参数对于性能测试有一定的帮助。例如，如果解析一份自定义的 XML 文档花费了多于 1 秒的时间，就需要重新考虑 XML 结构的设计，那单元测试方法可以这样来写：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">@Test(timeout=1000)
	public void selfXMLReader(){
		……
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>
				<a name="N10193">
						<span class="smalltitle">
								<strong>
										<font face="Arial">忽略测试方法</font>
								</strong>
						</span>
				</a>
		</p>
		<p>JUnit 提供注解 org.junit.Ignore 用于暂时忽略某个测试方法，因为有时候由于测试环境受限，并不能保证每一个测试方法都能正确运行。例如下面的代码便表示由于没有了数据库链接，提示 JUnit 忽略测试方法 unsupportedDBCheck：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">@ Ignore(“db is down”)
@Test(expected=UnsupportedDBVersionException.class)
	public void unsupportedDBCheck(){
		……
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>但是一定要小心。注解 org.junit.Ignore 只能用于暂时的忽略测试，如果需要永远忽略这些测试，一定要确认被测试代码不再需要这些测试方法，以免忽略必要的测试点。</p>
		<p>
				<a name="N101A4">
						<span class="smalltitle">
								<strong>
										<font face="Arial">测试运行器</font>
								</strong>
						</span>
				</a>
		</p>
		<p>又一个新概念出现了——测试运行器，JUnit 中所有的测试方法都是由它负责执行的。JUnit 为单元测试提供了默认的测试运行器，但 JUnit 并没有限制您必须使用默认的运行器。相反，您不仅可以定制自己的运行器（所有的运行器都继承自 org.junit.runner.Runner），而且还可以为每一个测试类指定使用某个具体的运行器。指定方法也很简单，使用注解 org.junit.runner.RunWith 在测试类上显式的声明要使用的运行器即可：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">@RunWith(CustomTestRunner.class)
public class TestWordDealUtil {
……
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>显而易见，如果测试类没有显式的声明使用哪一个测试运行器，JUnit 会启动默认的测试运行器执行测试类（比如上面提及的单元测试代码）。一般情况下，默认测试运行器可以应对绝大多数的单元测试要求；当使用 JUnit 提供的一些高级特性（例如即将介绍的两个特性）或者针对特殊需求定制 JUnit 测试方式时，显式的声明测试运行器就必不可少了。</p>
		<p>
				<a name="N101B5">
						<span class="smalltitle">
								<strong>
										<font face="Arial">测试套件</font>
								</strong>
						</span>
				</a>
		</p>
		<p>在实际项目中，随着项目进度的开展，单元测试类会越来越多，可是直到现在我们还只会一个一个的单独运行测试类，这在实际项目实践中肯定是不可行的。为了解决这个问题，JUnit 提供了一种批量运行测试类的方法，叫做测试套件。这样，每次需要验证系统功能正确性时，只执行一个或几个测试套件便可以了。测试套件的写法非常简单，您只需要遵循以下规则：</p>
		<ol>
				<li>创建一个空类作为测试套件的入口。 
</li>
				<li>使用注解 org.junit.runner.RunWith 和 org.junit.runners.Suite.SuiteClasses 修饰这个空类。 
</li>
				<li>将 org.junit.runners.Suite 作为参数传入注解 RunWith，以提示 JUnit 为此类使用套件运行器执行。 
</li>
				<li>将需要放入此测试套件的测试类组成数组作为注解 SuiteClasses 的参数。 
</li>
				<li>保证这个空类使用 public 修饰，而且存在公开的不带有任何参数的构造函数。 </li>
		</ol>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package com.ai92.cooljunit;

import org.junit.runner.RunWith;
import org.junit.runners.Suite;
……

/**
 * 批量测试 工具包 中测试类
 * @author Ai92
 */
@RunWith(Suite.class)
@Suite.SuiteClasses({TestWordDealUtil.class})
public class RunAllUtilTestsSuite {
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>上例代码中，我们将前文提到的测试类 TestWordDealUtil 放入了测试套件 RunAllUtilTestsSuite 中，在 Eclipse 中运行测试套件，可以看到测试类 TestWordDealUtil 被调用执行了。测试套件中不仅可以包含基本的测试类，而且可以包含其它的测试套件，这样可以很方便的分层管理不同模块的单元测试代码。但是，您一定要保证测试套件之间没有循环包含关系，否则无尽的循环就会出现在您的面前……。</p>
		<p>
				<a name="N101D8">
						<span class="smalltitle">
								<strong>
										<font face="Arial">参数化测试</font>
								</strong>
						</span>
				</a>
		</p>
		<p>回顾一下我们在小节“<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#major2"><font color="#5c81a7">JUnit 初体验</font></a>”中举的实例。为了保证单元测试的严谨性，我们模拟了不同类型的字符串来测试方法的处理能力，为此我们编写大量的单元测试方法。可是这些测试方法都是大同小异：代码结构都是相同的，不同的仅仅是测试数据和期望值。有没有更好的方法将测试方法中相同的代码结构提取出来，提高代码的重用度，减少复制粘贴代码的烦恼？在以前的 JUnit 版本上，并没有好的解决方法，而现在您可以使用 JUnit 提供的参数化测试方式应对这个问题。</p>
		<p>参数化测试的编写稍微有点麻烦（当然这是相对于 JUnit 中其它特性而言）：</p>
		<ol>
				<li>为准备使用参数化测试的测试类指定特殊的运行器 org.junit.runners.Parameterized。 
</li>
				<li>为测试类声明几个变量，分别用于存放期望值和测试所用数据。 
</li>
				<li>为测试类声明一个使用注解 org.junit.runners.Parameterized.Parameters 修饰的，返回值为 java.util.Collection 的公共静态方法，并在此方法中初始化所有需要测试的参数对。 
</li>
				<li>为测试类声明一个带有参数的公共构造函数，并在其中为第二个环节中声明的几个变量赋值。 
</li>
				<li>编写测试方法，使用定义的变量作为参数进行测试。 </li>
		</ol>
		<p>我们按照这个标准，重新改造一番我们的单元测试代码：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">package com.ai92.cooljunit;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class TestWordDealUtilWithParam {

		private String expected;
	
		private String target;
	
		@Parameters
		public static Collection words(){
	    		return Arrays.asList(new Object[][]{
	          	{"employee_info", "employeeInfo"},		//测试一般的处理情况
	          	{null, null},							//测试 null 时的处理情况
	          	{"", ""},								//测试空字符串时的处理情况
	          	{"employee_info", "EmployeeInfo"},		//测试当首字母大写时的情况
	          	{"employee_info_a", "employeeInfoA"},	//测试当尾字母为大写时的情况
	          	{"employee_a_info", "employeeAInfo"}	//测试多个相连字母大写时的情况
	    		});
		}
	
	 	/**
	 	* 参数化测试必须的构造函数
	 	* @param expected	期望的测试结果，对应参数集中的第一个参数
	 	* @param target	测试数据，对应参数集中的第二个参数
	 	*/
		public TestWordDealUtilWithParam(String expected , String target){
			this.expected = expected;
			this.target = target;
		}
	
	 	/**
	 	* 测试将 Java 对象名称到数据库名称的转换
	 	*/
		@Test public void wordFormat4DB(){
			assertEquals(expected, WordDealUtil.wordFormat4DB(target));
		}
}
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>很明显，代码瘦身了。在静态方法 words 中，我们使用二维数组来构建测试所需要的参数列表，其中每个数组中的元素的放置顺序并没有什么要求，只要和构造函数中的顺序保持一致就可以了。现在如果再增加一种测试情况，只需要在静态方法 words 中添加相应的数组即可，不再需要复制粘贴出一个新的方法出来了。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10205">
						<span class="atitle">JUnit 和 Ant</span>
				</a>
		</p>
		<p>随着项目的进展，项目的规模在不断的膨胀，为了保证项目的质量，有计划的执行全面的单元测试是非常有必要的。但单靠JUnit提供的测试套件很难胜任这项工作，因为项目中单元测试类的个数在不停的增加，测试套件却无法动态的识别新加入的单元测试类，需要手动修改测试套件，这是一个很容易遗忘得步骤，稍有疏忽就会影响全面单元测试的覆盖率。</p>
		<p>当然解决的方法有多种多样，其中将 JUnit 与构建利器 Ant 结合使用可以很简单的解决这个问题。Ant —— 备受赞誉的 Java 构建工具。它凭借出色的易用性、平台无关性以及对项目自动测试和自动部署的支持，成为众多项目构建过程中不可或缺的独立工具，并已经成为事实上的标准。Ant 内置了对 JUnit 的支持，它提供了两个 Task：junit 和 junitreport，分别用于执行 JUnit 单元测试和生成测试结果报告。使用这两个 Task 编写构建脚本，可以很简单的完成每次全面单元测试的任务。 </p>
		<p>不过，在使用 Ant 运行 JUnit 之前，您需要稍作一些配置。打开 Eclipse 首选项界面，选择 Ant -&gt; Runtime 首选项（见<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure007"><font color="#5c81a7">图7</font></a>），将 JUnit 4.1 的 JAR 文件添加到 Classpath Tab 页中的 Global Entries 设置项里。记得检查一下 Ant Home Entries 设置项中的 Ant 版本是否在 1.7.0 之上，如果不是请替换为最新版本的 Ant JAR 文件。</p>
		<br />
		<a name="figure007">
				<b>图7 Ant Runtime 首选项</b>
		</a>
		<br />
		<img alt="图7 Ant Runtime 首选项" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure007.jpg" />
		<br />
		<p>剩下的工作就是要编写 Ant 构建脚本 build.xml。虽然这个过程稍嫌繁琐，但这是一件一劳永逸的事情。现在我们就把前面编写的测试用例都放置到 Ant 构建脚本中执行，为项目 coolJUnit 的构建脚本添加一下内容：</p>
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="code-outline">
										<pre class="displaycode">&lt;?xml version="1.0"?&gt;
&lt;!-- ============================================= 
     auto unittest task    
     ai92                                                                
     ========================================== --&gt;
&lt;project name="auto unittest task" default="junit and report" basedir="."&gt;

		&lt;property name="output folder" value="bin"/&gt;

		&lt;property name="src folder" value="src"/&gt;
	
		&lt;property name="test folder" value="testsrc"/&gt;
	
		&lt;property name="report folder" value="report" /&gt;

		&lt;!-- - - - - - - - - - - - - - - - - - 
          target: test report folder init                      
         - - - - - - - - - - - - - - - - - --&gt;
		&lt;target name="test init"&gt;
			&lt;mkdir dir="${report folder}"/&gt;
		&lt;/target&gt;
	
		&lt;!-- - - - - - - - - - - - - - - - - - 
          target: compile                      
         - - - - - - - - - - - - - - - - - --&gt;
		&lt;target name="compile"&gt;
			&lt;javac srcdir="${src folder}" destdir="${output folder}" /&gt;
			&lt;echo&gt;compilation complete!&lt;/echo&gt;
		&lt;/target&gt;

		&lt;!-- - - - - - - - - - - - - - - - - - 
          target: compile test cases                      
         - - - - - - - - - - - - - - - - - --&gt;
		&lt;target name="test compile" depends="test init"&gt;
			&lt;javac srcdir="${test folder}" destdir="${output folder}" /&gt;
			&lt;echo&gt;test compilation complete!&lt;/echo&gt;
		&lt;/target&gt;
	
		&lt;target name="all compile" depends="compile, test compile"&gt;
		&lt;/target&gt;
	
		&lt;!-- ======================================== 
          target: auto test all test case and output report file                      
      	===================================== --&gt;
		&lt;target name="junit and report" depends="all compile"&gt;
			&lt;junit printsummary="on" fork="true" showoutput="true"&gt;
				&lt;classpath&gt;
					&lt;fileset dir="lib" includes="**/*.jar"/&gt;
					&lt;pathelement path="${output folder}"/&gt;
				&lt;/classpath&gt;
				&lt;formatter type="xml" /&gt;
				&lt;batchtest todir="${report folder}"&gt;
					&lt;fileset dir="${output folder}"&gt;
						&lt;include name="**/Test*.*" /&gt;
					&lt;/fileset&gt;
				&lt;/batchtest&gt;
			&lt;/junit&gt;
			&lt;junitreport todir="${report folder}"&gt;
				&lt;fileset dir="${report folder}"&gt;
					&lt;include name="TEST-*.xml" /&gt;
				&lt;/fileset&gt;
				&lt;report format="frames" todir="${report folder}" /&gt;
			&lt;/junitreport&gt;
		&lt;/target&gt;
&lt;/project&gt;
</pre>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>Target junit report 是 Ant 构建脚本中的核心内容，其它 target 都是为它的执行提供前期服务。Task junit 会寻找输出目录下所有命名以“Test”开头的 class 文件，并执行它们。紧接着 Task junitreport 会将执行结果生成 HTML 格式的测试报告（<a href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#figure008"><font color="#5c81a7">图8</font></a>）放置在“report folder”下。</p>
		<p>为整个项目的单元测试类确定一种命名风格。不仅是出于区分类别的考虑，这为 Ant 批量执行单元测试也非常有帮助，比如前面例子中的测试类都已“Test”打头，而测试套件则以“Suite”结尾等等。</p>
		<br />
		<a name="figure008">
				<b>图8 junitreport 生成的测试报告</b>
		</a>
		<br />
		<img alt="图8 junitreport 生成的测试报告" src="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/figure008.jpg" />
		<br />
		<p>现在执行一次全面的单元测试变得非常简单了，只需要运行一下 Ant 构建脚本，就可以走完所有流程，并能得到一份详尽的测试报告。您可以在 <a href="http://ant.apache.org/manual/index.html"><font color="#5c81a7">Ant 在线手册</font></a> 中获得上面提及的每一个 Ant 内置 task 的使用细节。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10249">
						<span class="atitle">总结</span>
				</a>
		</p>
		<p>随着越来越多的开发人员开始认同并接受极限编程（XP）的思想，单元测试的作用在软件工程中变得越来越重要。本文旨在将最新的单元测试工具 JUnit 4 介绍给您，以及如何结合 IDE Eclipse 和构建工具 Ant 创建自动化单元测试方案。并且还期望您能够通过本文“感染”一些好的单元测试意识，因为 JUnit 本身仅仅是一份工具而已，它的真正优势来自于它的思想和技术。</p>
		<br />
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/index.html?S_TACT=105AGX52&amp;S_CMP=techcsdn#main">
																				<b>
																						<font color="#5c81a7">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<span class="atitle">
						<a name="download">下载</a>
				</span>
		</p>
		<table class="data-table-1" cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<th scope="col">描述</th>
								<th scope="col">名字</th>
								<th scope="col" align="right">大小</th>
								<th scope="col">下载方法</th>
						</tr>
						<tr>
								<th class="tb-row" scope="row">本文示例代码</th>
								<td nowrap="">coolJUnit.zip</td>
								<td nowrap="" align="right">24 KB</td>
								<td nowrap="">
										<a class="fbox" href="http://www.ibm.com/developerworks/cn/java/j-lo-junit4/coolJUnit.zip">
												<b>
														<font color="#5c81a7">HTTP</font>
												</b>
										</a>
								</td>
						</tr>
				</tbody>
		</table>
		<table cellspacing="0" cellpadding="0" border="0">
				<tbody>
						<tr valign="top">
								<td colspan="5">
										<font color="#5c81a7">
												<img height="12" alt="" src="http://www.ibm.com/i/c.gif" width="12" border="0" />
										</font>
								</td>
						</tr>
						<tr>
								<td>
										<font color="#5c81a7">
												<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/fw.gif" width="16" />
										</font>
								</td>
								<td>
										<a class="fbox" href="http://www.ibm.com/developerworks/cn/whichmethod.html">
												<font color="#5c81a7">关于下载方法的信息</font>
										</a>
								</td>
								<td>
										<font color="#5c81a7">
												<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="50" />
										</font>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">参考资料 </span>
				</a>
		</p>
		<b>学习</b>
		<br />
		<ul>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-junit4.html">
								<font color="#5c81a7">JUnit 4 抢先看</font>
						</a>（Elliotte Rusty Harold, developerWorks, 2005 年 10 月）：Elliotte Rusty Harold 为大家揭开了 JUnit 4 新框架的面纱。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-cq08296/">
								<font color="#5c81a7">追求代码质量: JUnit 4 与 TestNG 的对比</font>
						</a>（Andrew Glover, developerWorks, 2006 年 9 月）：Andrew Glover 探讨了这两种框架各自的独特之处，并阐述了 TestNG 独有的三种高级测试特性。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-testng/">
								<font color="#5c81a7">TestNG 使 Java 单元测试轻而易举</font>
						</a>（Filippo Diotalevi, developerWorks, 2005 年 1 月）：TestNG 不仅确实强大、创新、可扩展、灵活，它还展示了 Java Annotations（JDK 5.0 中的重大新特性）的有趣应用。<br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-annotate1/">
								<font color="#5c81a7">Tiger 中的注释，第 1 部分: 向 Java 代码中添加元数据</font>
						</a>（Brett McLaughlin, developerWorks, 2004 年 9 月）：本文解释了元数据如此有用的原因，向您介绍了 Java 语言中的注释，并研究了 Tiger 的内置注释。 <br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-ant/index.html">
								<font color="#5c81a7">利用 Ant 和 JUnit 进行增量开发</font>
						</a>（Malcolm Davis, developerWorks, 2000 年 11 月）：本文通过使用代码样本说明了单元测试的种种好处，特别是使用 Ant 和 JUnit 带来的各种方便。 <br /><br /></li>
				<li>
						<a href="http://www.ibm.com/developerworks/cn/java/j-cq/">
								<i>
										<font color="#5c81a7">追求代码质量系列</font>
								</i>
						</a>（Andrew Glover, developerWorks）：在这个系列中，Andrew Glover 将重点阐述有关保证代码质量的一些有时看上去有点神秘的东西。 <br /><br /></li>
		</ul>
		<br />
		<b>获得产品和技术</b>
		<br />
		<ul>
				<li>
						<a href="http://www.junit.org/">
								<font color="#5c81a7">获得 JUnit 软件和相关信息</font>
						</a>。<br /><br /></li>
				<li>
						<a href="http://ant.apache.org/">
								<font color="#5c81a7">获得 Ant 软件和相关信息</font>
						</a>。<br /><br /></li>
				<li>
						<a href="http://www.eclipse.org/">
								<font color="#996699">获得 Eclipse 软件和相关信息</font>
						</a>。</li>
		</ul>
		<br />
<img src ="http://www.blogjava.net/relax/aggbug/101945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2007-03-05 16:15 <a href="http://www.blogjava.net/relax/archive/2007/03/05/101945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>weblogic中文显示乱码解决办法</title><link>http://www.blogjava.net/relax/archive/2007/03/05/101935.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Mon, 05 Mar 2007 07:53:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2007/03/05/101935.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/101935.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2007/03/05/101935.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/101935.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/101935.html</trackback:ping><description><![CDATA[
		<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">
				<font face="Times New Roman">
				</font>中文显示乱码解决办法：</span>
		<span lang="EN-US" style="FONT-SIZE: 12pt">
				<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?>
				<o:p>
				</o:p>
		</span>
		<p>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; mso-list: l0 level1 lfo2; tab-stops: list 36.0pt" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">1．</span>
				</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt">web.xml</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里面加入</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 17.95pt; TEXT-INDENT: 12pt; TEXT-ALIGN: left; mso-para-margin-left: 1.71gd; mso-char-indent-count: 1.0" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">&lt;context-param&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">        </span>&lt;param-name&gt;weblogic.httpd.inputCharset./*&lt;/param-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 17.95pt; TEXT-INDENT: 36pt; TEXT-ALIGN: left; mso-para-margin-left: 1.71gd; mso-char-indent-count: 3.0" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">   </span>&lt;param-value&gt;GB2312&lt;/param-value&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">  </span>&lt;/context-param&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 36pt; TEXT-INDENT: -18pt; TEXT-ALIGN: left; mso-list: l0 level1 lfo2; tab-stops: list 36.0pt" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; mso-fareast-font-family: 'Times New Roman'">
						<span style="mso-list: Ignore">2．</span>
				</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt">weblogic.xml</span>
				<span style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">里面加入</span>
				<span lang="EN-US" style="FONT-SIZE: 12pt">
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt">
						<span style="mso-spacerun: yes"> </span>
						<o:p>
						</o:p>
				</span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">&lt;jsp-descriptor&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes"> </span>
						<span style="mso-spacerun: yes"> </span>&lt;jsp-param&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">
						</span>
						<span style="mso-spacerun: yes">    </span>&lt;param-name&gt;compileCommand&lt;/param-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 17.95pt; TEXT-INDENT: 24pt; TEXT-ALIGN: left; mso-para-margin-left: 1.71gd; mso-char-indent-count: 2.0" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">       </span>&lt;param-value&gt;javac&lt;/param-value&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">  </span>&lt;/jsp-param&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">  </span>&lt;jsp-param&gt; <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">
						</span>
						<span style="mso-spacerun: yes">    </span>&lt;param-name&gt;compilerSupportsEncoding&lt;/param-name&gt; <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 17.95pt; TEXT-INDENT: 24pt; TEXT-ALIGN: left; mso-para-margin-left: 1.71gd; mso-char-indent-count: 2.0" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">       </span>&lt;param-value&gt;true&lt;/param-value&gt; <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">  </span>&lt;/jsp-param&gt; <o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">  </span>&lt;jsp-param&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">
						</span>
						<span style="mso-spacerun: yes">    </span>&lt;param-name&gt;encoding&lt;/param-name&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-tab-count: 1">
						</span>
						<span style="mso-spacerun: yes">    </span>&lt;param-value&gt;GB2312&lt;/param-value&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">    </span>&lt;/jsp-param&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<span style="mso-spacerun: yes">  </span>&lt;/jsp-descriptor&gt;<o:p></o:p></span>
		</p>
		<p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-ALIGN: left" align="left">
				<span lang="EN-US" style="FONT-SIZE: 12pt; COLOR: lime">
						<o:p> </o:p>
				</span>
		</p>
<img src ="http://www.blogjava.net/relax/aggbug/101935.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2007-03-05 15:53 <a href="http://www.blogjava.net/relax/archive/2007/03/05/101935.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>澄清Java语言接口与继承的本质     选择自 psyl 的 Blog </title><link>http://www.blogjava.net/relax/archive/2006/03/07/34046.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Tue, 07 Mar 2006 05:34:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2006/03/07/34046.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/34046.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2006/03/07/34046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/34046.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/34046.html</trackback:ping><description><![CDATA[<SPAN id=ArticleContent1_ArticleContent1_lblContent>大多数人认为，接口的意义在于顶替多重继承。众所周知Java没有c++那样多重继承的机制，但是却能够实作多个接口。其实这样做是很牵强的，接口和继承是完全不同的东西，接口没有能力代替多重继承，也没有这个义务。接口的作用，一言以蔽之，就是标志类的类别（type&nbsp;of&nbsp;class）。把不同类型的类归于不同的接口，可以更好的管理他们。OO的精髓，我以为，是对对象的抽象，最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言（比如c++、java、c#等），就是因为设计模式所研究的，实际上就是如何合理的去抽象。（cowboy的名言是“抽象就是抽去像的部分”，看似调侃，实乃至理）。<BR><BR>　　设计模式中最基础的是工厂模式（Factory），在我最近的一个很简单的应用中，我想尽量的让我的程序能够在多个数据库间移植，当然，这涉及很多问题，单是如何兼容不同DBMS的SQL就让人头痛。我们不妨先把问题简单化，只考虑如何连接不同的数据库。<BR><BR>　　假设我有很多个类，分别是Mysql.java、SQLServer.java、Oracle.java、DB2.java，他们分别连接不同的数据库，统一返回一个Connection对象，并且都有一个close方法，用于关闭连接。只需要针对你的DBMS，选择不同的类，就可以用了，但是我的用户他会使用什么数据库？我不知道，我希望的是尽量少的修改代码，就能满足他的需要。我可以抽象如下接口：<BR><BR>package&nbsp;org.bromon.test;<BR>public&nbsp;interface&nbsp;DB<BR>{<BR>　　java.sql.Connection&nbsp;openDB(String&nbsp;url,String&nbsp;user,String&nbsp;password);<BR>　　void&nbsp;close();<BR>}&nbsp;<BR><BR>　　这个接口只定义两个方法，没有任何有实际意义的代码，具体的代码由实作这个接口的类来给出，比如Mysql.java：<BR><BR>Package&nbsp;org.bromon.test;<BR>import&nbsp;java.sql.*;<BR>public&nbsp;class&nbsp;Mysql&nbsp;implements&nbsp;DB<BR>{<BR>　　private&nbsp;String&nbsp;url=”jdbc:mysql:localhost:3306/test”;<BR>　　private&nbsp;String&nbsp;user=”root”;<BR>　　private&nbsp;String&nbsp;password=””;<BR>　　private&nbsp;Connection&nbsp;conn;<BR>　　public&nbsp;Connection&nbsp;openDB(url,user,password)<BR>　　{<BR>　　　　//连接数据库的代码<BR>　　}<BR><BR>　　public&nbsp;void&nbsp;close()<BR>　　{<BR>　　　　//关闭数据库<BR>　　}<BR>}&nbsp;<BR><BR>　　类似的当然还有Oracle.java等等，接口DB给这些类归了个类，在应用程序中我们这样定义对象：<BR><BR>　　org.bromon.test.DB&nbsp;myDB;<BR><BR>　　使用myDB来操作数据库，就可以不用管实际上我所使用的是哪个类，这就是所谓的“开-闭”原则。但是问题在于接口是不能实例化的，myDB=new&nbsp;DB()，这样的代码是绝对错误的，我们只能myDB=new&nbsp;Mysql()或者myDB=new&nbsp;Oracle()。麻烦了，我还是需要指定具体实例化的是哪个类，用了接口跟没用一样。所以我们需要一个工厂：<BR><BR>package&nbsp;org.bromon.test;<BR>public&nbsp;class&nbsp;DBFactory<BR>{<BR>　　public&nbsp;static&nbsp;DB&nbsp;Connection&nbsp;getConn()<BR>　　{<BR>　　　　Return(new&nbsp;Mysql());<BR>　　}<BR>}&nbsp;<BR><BR>　　所以实例化的代码变成：myDB=DBFactory.getConn()；<BR><BR>　　这就是23种模式中最基础的普通工厂(Factory)，工厂类负责具体实例化哪个类，而其他的程序逻辑都是针对DB这个接口进行操作，这就是“针对接口编程”。责任都被推卸给工厂类了，当然你也可以继续定义工厂接口，继续把责任上抛，这就演变成抽象工厂(Abstract&nbsp;Factory)。<BR><BR>　　整个过程中接口不负责任何具体操作，其他的程序要连接数据库的话，只需要构造一个DB对象就OK，而不管工厂类如何变化。这就是接口的意义----抽象。<BR><BR>　　继承的概念不用多说，很好理解。为什么要继承呢？因为你想重用代码？这绝对不是理由，继承的意义也在于抽象，而不是代码重用。如果对象A有一个run()方法，对象B也想有这个方法，所以有人就Class&nbsp;B&nbsp;extends&nbsp;A。这是不经大脑的做法。如果在B中实例化一个A，调用A的Run()方法，是不是可以达到同样的目的？如下：<BR><BR>Class&nbsp;B<BR>{<BR>　　A&nbsp;a=new&nbsp;A();<BR>　　a.run();<BR>}&nbsp;<BR><BR>　　这就是利用类的聚合来重用代码，是委派模式的雏形，是GoF一贯倡导的做法。<BR><BR>　　那么继承的意义何在？其实这是历史原因造成的，最开始的OO语言只有继承，没有接口，所以只能以继承来实现抽象，请一定注意，继承的本意在于抽象，而非代码重用（虽然继承也有这个作用），这是很多Java烂书最严重的错误之一，它们所造成的阴影，我至今还没有完全摆脱，坏书害人啊，尤其是入门类的，流毒太大。什么时候应该使用继承？只在抽象类中使用，其他情况下尽量不使用。抽象类也是不能实例化的，它仅仅提供一个模版而已，这就很能说明问题。<BR><BR>　　软件开发的万恶之源，一是重复代码而不是重用代码，二是烂用继承，尤以c++程序员为甚。Java中取缔多重继承，目的就是制止烂用继承，实是非常明智的做法，不过很多人都不理解。Java能够更好的体现设计，这是让我入迷的原因之一. <BR></SPAN><BR><img src ="http://www.blogjava.net/relax/aggbug/34046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2006-03-07 13:34 <a href="http://www.blogjava.net/relax/archive/2006/03/07/34046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>weblogic和mq的集成</title><link>http://www.blogjava.net/relax/archive/2006/03/07/34026.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Tue, 07 Mar 2006 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2006/03/07/34026.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/34026.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2006/03/07/34026.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/34026.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/34026.html</trackback:ping><description><![CDATA[<SPAN class=postdetails><FONT size=2>weblogic:8.1 sp2 <BR>MQ:5.3 <BR><BR>摘要：把weblogic 和MQ集成起来是非常有价值的应用。本文讨论使用weblogic的Foreign JMS Server 配置JNDI,MDB配置，使用MQ提供的 <BR>JMSADMIN配置MQ的jndi。也没有那么详细啦，还是需要读者自己作一番小小的努力的。 <BR><BR>关键词：jms,Weblogic foreign JMS Server,JNDI,JMSAdmin <BR><BR>开始： <BR>1、安装Weblogic 和MQ（废话）。 <BR>2、配置JMSAdmin（就是在 mq安装目录下的 java/bin/目录里没有扩展名的的文件） <BR>uncomment下面两行，同时在你的机器上建相应的目录C:/JNDI-Directory <BR><BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR><BR>INITIAL_CONTEXT_FACTORY=com.<SPAN style="COLOR: #000000">sun</SPAN>.<SPAN style="COLOR: #000000">jndi</SPAN>.<SPAN style="COLOR: #000000">fscontext</SPAN>.<SPAN style="COLOR: #000000">RefFSContextFactory</SPAN> <BR><BR>PROVIDER_URL=file:/C:/JNDI-Directory&nbsp; &nbsp; <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><BR><FONT size=2>以上配置适用于使用文件jndi。 <BR>3、配置mq的jndi <BR>下面使用jmsadmin配置mq的jndi。 <BR>下面是使用jmsadmin的一些命令的例子。 <BR>其实你可以去ibm的网站上面下载图形界面的东东，就不用记这些命令啦。 <BR>这个东东叫：JMSADMINGUI <BR><BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR><BR>def qcf<SPAN style="COLOR: #000000">(</SPAN>ivtQCF<SPAN style="COLOR: #000000">)</SPAN> <BR>def q<SPAN style="COLOR: #000000">(</SPAN>ivtQ<SPAN style="COLOR: #000000">)</SPAN> qu<SPAN style="COLOR: #000000">(</SPAN>SYSTEM.<SPAN style="COLOR: #000000">DEFAULT</SPAN>.<SPAN style="COLOR: #000000">LOCAL</SPAN>.<SPAN style="COLOR: #000000">QUEUE</SPAN><SPAN style="COLOR: #000000">)</SPAN> <BR>def tcf<SPAN style="COLOR: #000000">(</SPAN>ivtTCF<SPAN style="COLOR: #000000">)</SPAN> <BR>def t<SPAN style="COLOR: #000000">(</SPAN>ivtT<SPAN style="COLOR: #000000">)</SPAN> topic<SPAN style="COLOR: #000000">(</SPAN>MQJMS/PSIVT/Information<SPAN style="COLOR: #000000">)</SPAN> <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><BR><BR><FONT size=2>或者你可以执行IVTSETUP脚本来完成一个可以使用的JNDI配置。 <BR><BR>4、配置Weblogic的Foreign JMSServer以下属性进行配置： <BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR>JNDI Initial <SPAN style="COLOR: #aaaadd" ?>Context</SPAN> Factory-&gt;com.<SPAN style="COLOR: #000000">sun</SPAN>.<SPAN style="COLOR: #000000">jndi</SPAN>.<SPAN style="COLOR: #000000">fscontext</SPAN>.<SPAN style="COLOR: #000000">RefFSContextFactory</SPAN> <BR>JNDI <SPAN style="COLOR: #aaaadd" ?>Connection</SPAN> URL-&gt;file:/C:/JNDI-Directory&nbsp; &nbsp; &nbsp; <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>5、配置Foreign JMS Connection Factories <BR><BR>代码: <BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR>Local JNDI <SPAN style="COLOR: #aaaadd" ?>Name</SPAN>:mqqcf<SPAN style="COLOR: #000000">(</SPAN>在weblogic 中使用的QueueConnectionFactory的JNDI的名字<SPAN style="COLOR: #000000">)</SPAN> <BR><SPAN style="COLOR: #aaaadd" ?>Remote</SPAN> JNDI <SPAN style="COLOR: #aaaadd" ?>Name</SPAN>:ivtQCF<SPAN style="COLOR: #000000">(</SPAN>已经在通过jmsadmin配置º玫Äjndi的名字<SPAN style="COLOR: #000000">)</SPAN> <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>6、配置foreign JMS destination <BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR><BR>Local JNDI <SPAN style="COLOR: #aaaadd" ?>Name</SPAN>: MQQUEUE <BR><SPAN style="COLOR: #aaaadd" ?>Remote</SPAN> JNDI <SPAN style="COLOR: #aaaadd" ?>Name</SPAN>: ivtQ <BR>&nbsp; &nbsp; &nbsp; &nbsp; <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>同上。 <BR>7、MDB配置 <BR><BR><BR><BR></FONT></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR><BR>&lt;?xml version="<SPAN style="COLOR: #000000" ?>1</SPAN>.<SPAN style="COLOR: #000000" ?>0</SPAN>"?&gt; <BR>&lt;!DOCTYPE ejb-jar <SPAN style="FONT-WEIGHT: bold; COLOR: #990066" ?>PUBLIC</SPAN> "-<SPAN style="COLOR: #6666ff">//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"&gt; </SPAN><BR>&lt;!-- This ejb-jar.<SPAN style="COLOR: #000000">xml</SPAN> file defines a message-driven bean called "SimpleMDB". <SPAN style="COLOR: #000000">It</SPAN> uses container-managed transactions, because "transaction-type" is "<SPAN style="COLOR: #aaaadd" ?>Container</SPAN>" and "trans-attribute" is "Required". --&gt; <BR>&lt;ejb-jar&gt; <BR>&nbsp; &nbsp;&lt;enterprise-beans&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;message-driven&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;ejb-name&gt;ReceiveMessageMDB&lt;/ejb-name&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;ejb-<SPAN style="FONT-WEIGHT: bold; COLOR: #990066" ?>class</SPAN>&gt;com.<SPAN style="COLOR: #000000">rm</SPAN>.<SPAN style="COLOR: #000000">mdb</SPAN>.<SPAN style="COLOR: #000000">ReceiveMessageBean</SPAN>&lt;/ejb-<SPAN style="FONT-WEIGHT: bold; COLOR: #990066" ?>class</SPAN>&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;transaction-type&gt;<SPAN style="COLOR: #aaaadd" ?>Container</SPAN>&lt;/transaction-type&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;message-driven-destination&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;!-- In WebLogic Server <SPAN style="COLOR: #000000" ?>6</SPAN>.<SPAN style="COLOR: #000000" ?>0</SPAN>, this next parameter is named "jms-destination-type" --&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;destination-type&gt;javax.<SPAN style="COLOR: #000000">jms</SPAN>.<SPAN style="COLOR: #000000">Queue</SPAN>&lt;/destination-type&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/message-driven-destination&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;/message-driven&gt; <BR>&nbsp; &nbsp;&lt;/enterprise-beans&gt; <BR>&nbsp; &nbsp;&lt;assembly-descriptor&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;container-transaction&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;method&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;ejb-name&gt;ReceiveMessageMDB&lt;/ejb-name&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;method-name&gt;*&lt;/method-name&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;/method&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&lt;trans-attribute&gt;NotSupported&lt;/trans-attribute&gt; <BR>&nbsp; &nbsp; &nbsp; &lt;/container-transaction&gt; <BR>&nbsp; &nbsp;&lt;/assembly-descriptor&gt; <BR>&lt;/ejb-jar&gt;&nbsp; &nbsp; &nbsp; &nbsp; <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR></SPAN>
<TABLE cellSpacing=1 cellPadding=3 width="90%" align=center border=0>
<TBODY>
<TR>
<TD><SPAN class=genmed><B><FONT size=2>java代码:&nbsp;</FONT></B></SPAN></TD></TR>
<TR>
<TD class=code>
<DIV style="FONT-FAMILY: 'Courier New', Courier, monospace"><BR><BR>&lt;?xml version="<SPAN style="COLOR: #000000" ?>1</SPAN>.<SPAN style="COLOR: #000000" ?>0</SPAN>" encoding="UTF-<SPAN style="COLOR: #000000" ?>8</SPAN>"?&gt; <BR>&lt;!DOCTYPE weblogic-ejb-jar <SPAN style="FONT-WEIGHT: bold; COLOR: #990066" ?>PUBLIC</SPAN> <SPAN style="COLOR: #0000ff">'-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN'</SPAN> <SPAN style="COLOR: #0000ff">'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'</SPAN>&gt; <BR>&lt;weblogic-ejb-jar&gt; <BR>&lt;weblogic-enterprise-bean&gt; <BR>&lt;ejb-name&gt;ReceiveMessageMDB&lt;/ejb-name&gt; <BR>&lt;message-driven-descriptor&gt; <BR>&lt;pool&gt; <BR>&lt;max-beans-in-free-pool&gt;<SPAN style="COLOR: #000000" ?>8</SPAN>&lt;/max-beans-in-free-pool&gt; <BR>&lt;initial-beans-in-free-pool&gt;<SPAN style="COLOR: #000000" ?>1</SPAN>&lt;/initial-beans-in-free-pool&gt; <BR>&lt;/pool&gt; <BR>&lt;destination-jndi-name&gt;MQQUEUE&lt;/destination-jndi-name&gt; <BR>&lt;initial-context-factory&gt; weblogic.<SPAN style="COLOR: #000000">jndi</SPAN>.<SPAN style="COLOR: #000000">WLInitialContextFactory</SPAN> &lt;/initial-context-factory&gt; <BR>&lt;provider-url&gt;t3:<SPAN style="COLOR: #6666ff">//localhost:7001&lt;/provider-url&gt; </SPAN><BR>&lt;connection-factory-jndi-name&gt;MQQCF&lt;/connection-factory-jndi-name&gt; <BR>&lt;/message-driven-descriptor&gt; <BR>&lt;/weblogic-enterprise-bean&gt; <BR>&lt;/weblogic-ejb-jar&gt; <BR>&nbsp; &nbsp; &nbsp; &nbsp; <BR></DIV><BR></TD></TR></TBODY></TABLE><SPAN class=postbody><BR><BR><FONT size=2>注意： <BR>如果 ejb-jar.xml中的&lt;trans-attribute&gt;NotSupported&lt;/trans-attribute&gt; <BR>为required则需要使用XAQueueConnectionFactory.</FONT></SPAN> <img src ="http://www.blogjava.net/relax/aggbug/34026.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2006-03-07 11:51 <a href="http://www.blogjava.net/relax/archive/2006/03/07/34026.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>EJB 2.0：“本地”接口和“远程”接口</title><link>http://www.blogjava.net/relax/archive/2005/12/02/22267.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Fri, 02 Dec 2005 09:03:00 GMT</pubDate><guid>http://www.blogjava.net/relax/archive/2005/12/02/22267.html</guid><wfw:comment>http://www.blogjava.net/relax/comments/22267.html</wfw:comment><comments>http://www.blogjava.net/relax/archive/2005/12/02/22267.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/relax/comments/commentRss/22267.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/relax/services/trackbacks/22267.html</trackback:ping><description><![CDATA[<STRONG>个新的接口可以使你更有效地访问EJB。学习如何运用它们，以及何时运用它们。 <BR xmlns:fo="http://www.w3.org/1999/XSL/Format"></STRONG><SPAN class=AboutAuthor xmlns:fo="http://www.w3.org/1999/XSL/Format">by Rudy Dahbura</SPAN> 
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>当前的EJB 2.0规范有新的接口功能，这在原先的EJB 1.1中是没有的。学习运用这些新的功能，它们可以使你更容易地、更有效地访问EJB。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>缺点是什么呢？你将牺牲位置的独立性，但有时侯，这种代价是值得的。了解何时、如何运用新的功能对编写设计良好的EJB应用程序是至关重要的。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>EJB 1.1规范给EJB客户端提供了一个remote interface和一个remote home interface与EJB实例交互，得到位置的透明度。以类似的形式，EJB 2.0规范现在给EJB客户端提供了一个local interface和一个local home interface来与共享同一个JVM的EJB实例交互。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>EJB remote interface（javax.ejb.EJBObject）和remote home interface（javax.ejb.EJBHome）在本质上是Java RMI接口。远程客户端运用接口和与Java RMI-IIOP兼容的参数与EJBs通讯。参数和方法的结果值在同一个容器中传递，或者跨网络传递到远程容器。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>这种编程模式给EJB客户端提供了一种访问EJB组件的方法，就好像这些组件是本地的一样。然后，容器就可以透明地处理网络通讯和执行其它功能。这种方法很适合粗粒度的（coarse-grained）方法调用，其中客户端和EJBs之间的客户端通讯保持到最小限度。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>相反，EJB local interface（javax.ejb.EJBLocalObject）和local home interface（javax.ejb.EJBLocalHome）不是Java RMI接口，它们是EJB 2.0的新功能。本地客户端——如其它EJBs，运用相同JVM中传递的参数直接与EJBs通讯。这种技术消除了网络潜在的问题、参数复制的问题以及需要与Java RMI-IIOP兼容的问题。也意味着，EJB客户端可以运用一个更轻量级的编程模式来访问服务。该方法很适合细粒度的（fine-grained）方法调用，因为作为EJB实例的位于同一个JVM中的EJB客户端可以用本地接口来避免不必要的费用。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>引进本地客户端产生的另一个显著的变化就是类型的转换。所有的EJB实例在运用前必须转换到它们恰当的接口类型，所以，有时侯，在运用远程客户端时，要保证Java RMI-IIOP的兼容性，你必须在转换EJB实例前运用java.rmi.PortableRemoteObject.narrow()来缩小（narrow）它。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>但本地客户端可以直接把EJB实例转换成local home interface类型，如下面的代码片段： 
<TABLE bgColor=#ffffaa>
<TBODY>
<TR>
<TD><FONT color=#0000cc><PRE>InitialContext initCtx = new 
InitialContext();
   ExampleLocalHome exampleLocalHome = 
(ExampleLocalHome)initCtx.lookup("java:comp/
env/ejb/Example");</PRE></FONT></TD></TR></TBODY></TABLE></FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>从local home创建了EJB实例： 
<TABLE bgColor=#ffffaa>
<TBODY>
<TR>
<TD><FONT color=#0000cc><PRE>ExampleLocal exampleLocal = 
exampleLocalHome.create();</PRE></FONT></TD></TR></TBODY></TABLE></FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>也许EJB 2.0的最有趣、最容易被忽视的一个方面就是session和entity beans可以同时运用远程和本地接口，这就给了你很大的灵活性。运用两种接口给了潜在的bean客户端最大程度的自由，不管它们是不是在一起的。</FONT></P><BR xmlns:fo="http://www.w3.org/1999/XSL/Format"><?xml version="1.0" encoding="utf-16"?><BR xmlns:fo="http://www.w3.org/1999/XSL/Format"><SPAN class=AboutAuthor xmlns:fo="http://www.w3.org/1999/XSL/Format"></SPAN>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>&lt;session&gt;和&lt;entity&gt;元素描述了session和entity bean的部署属性。EJB 1.1和EJB 2.0规范定义了两个元素，&lt;home&gt;和&lt;remote&gt;。（以前的规范需要两个元素，但它们在2.0版中是可选的）。它们分别包含EJB remote home interface和remote interface的完全资格类名。 </FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>类似地，EJB 2.0规范定义了两个附加的元素，&lt;local-home&gt;和&lt;local&gt;。正如你预料的，它们包含EJB local home interface和local interface的完全资格类名。下面的代码显示了如何运用这些新元素： 
<TABLE bgColor=#ffffaa>
<TBODY>
<TR>
<TD><FONT color=#0000cc><PRE>&lt;ejb-jar&gt;
   &lt;enterprise-beans&gt;
      &lt;session&gt;
         &lt;ejb-name&gt;...&lt;/ejb-name&gt;
         &lt;local-home&gt;...&lt;/local-home&gt;
         &lt;local&gt;...&lt;/local&gt;
         &lt;ejb-link&gt;...&lt;/ejb-link&gt;
         ...
      &lt;/session&gt;
   &lt;/enterprise-beans&gt;
   &lt;assembly-descriptor&gt;
...
   &lt;/assembly-descriptor&gt;
&lt;/ejb-jar&gt;
</PRE></FONT></TD></TR></TBODY></TABLE></FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black><B><FONT color=#333399>聪明地访问本地客户端的一个实例</FONT></B><BR>本地EJB客户端的概念在如<A href="">列表1</A>所示的例子中得到了很好地阐明，其中显示了一个无状态session bean，它的local interface和它的local home interface。注意，接口不扩展java.rmi.Remote。 </FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>无状态session bean的XML部署描述如下面的代码所示，它也重点强调了&lt;local&gt;和&lt;local-home&gt;元素的运用： 
<TABLE bgColor=#ffffaa>
<TBODY>
<TR>
<TD><FONT color=#0000cc><PRE>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE ejb-jar PUBLIC
   '-//Sun Microsystems, Inc.//DTD Enterprise 
JavaBeans 2.0//EN'
   'http://java.sun.com/dtd/ejb-jar_2_0.dtd'&gt;
&lt;ejb-jar&gt;
   &lt;enterprise-beans&gt;
      &lt;session&gt;
         &lt;ejb-name&gt;Example&lt;/ejb-name&gt;
         &lt;local-
home&gt;com.acmecorp.ejb.ExampleLocalHome&lt;/
local-home&gt;
         &lt;local&gt;com.acmecorp.ejb.ExampleLocal&lt;/local&gt;
         &lt;ejb-
class&gt;com.acmecorp.ejb.ExampleBean&lt;/
ejb-class&gt;
         &lt;session-
type&gt;Stateless&lt;/session-type&gt;
         &lt;transaction-
type&gt;Container&lt;/transaction-type&gt;
      &lt;/session&gt;
   &lt;/enterprise-beans&gt;
   &lt;assembly-descriptor&gt;
      &lt;method-permission&gt;
         &lt;unchecked/&gt;
         &lt;method&gt;
            &lt;ejb-name&gt;Example&lt;/ejb-name&gt;
            &lt;method-name&gt;*&lt;/method-name&gt;
         &lt;/method&gt;
      &lt;/method-permission&gt;
      &lt;container-transaction&gt;
         &lt;method&gt;
            &lt;ejb-name&gt;Example&lt;/ejb-name&gt;
            &lt;method-name&gt;*&lt;/method-name&gt;
         &lt;/method&gt;
         &lt;trans-
attribute&gt;NotSupported&lt;/trans-attribute&gt;
      &lt;/container-transaction&gt;
   &lt;/assembly-descriptor&gt;
&lt;/ejb-jar&gt;
</PRE></FONT></TD></TR></TBODY></TABLE></FONT></P><BR xmlns:fo="http://www.w3.org/1999/XSL/Format"><?xml version="1.0" encoding="utf-16"?><BR xmlns:fo="http://www.w3.org/1999/XSL/Format"><SPAN class=AboutAuthor xmlns:fo="http://www.w3.org/1999/XSL/Format"></SPAN>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>然后，一个本地的客户端创建并访问一个已经创建的enterprise bean的实例。下面的代码也显示了如何转换一个bean的实例，而不用先缩小它： 
<TABLE bgColor=#ffffaa>
<TBODY>
<TR>
<TD><FONT color=#0000cc><PRE>&lt;%@ page errorPage="/error.jsp" 
import="javax.naming.*, 
com.acmecorp.ejb.*" 
%&gt;
&lt;%

   InitialContext initCtx = new InitialContext();
   ExampleLocalHome exampleLocalHome = 
(ExampleLocalHome)initCtx.lookup("java:comp/env/
ejb/Example");
   ExampleLocal exampleLocal = 
exampleLocalHome.create();

%&gt;
&lt;html&gt;
&lt;head&gt;
   &lt;title&gt;Default&lt;/title&gt;
   &lt;link rel="STYLESHEET" type="text/css" 
href="styles/default.css"&gt;
&lt;/head&gt;
&lt;body&gt;
   &lt;pre class="code"&gt;&lt;%= 
exampleLocal.getMessage() %&gt;&lt;/pre&gt;
&lt;/body&gt;
&lt;/html&gt;
</PRE></FONT></TD></TR></TBODY></TABLE></FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>在这个例子中，本地客户端是一个JSP页面，因此是一个Web组件。（在有些情况中，当Web组件位于相同的JVM中时，它们访问EJB 2.0本地组件接口。）</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>最后是Web组件的部署描述： 
<TABLE bgColor=#ffffaa>
<TBODY>
<TR>
<TD><FONT color=#0000cc><PRE>&lt;web-app&gt;
   &lt;!-- EJB Reference information --&gt;
   &lt;ejb-local-ref&gt;
      &lt;ejb-ref-name&gt;ejb/Example&lt;
/ejb-ref-name&gt;
      &lt;ejb-ref-type&gt;Session&lt;
/ejb-ref-type&gt;
      &lt;local-home&gt;com.acmecorp.ejb.ExampleLocalHome&lt;
/local-home&gt;
      &lt;local&gt;com.acmecorp.ejb.ExampleLocal&lt;
/local&gt;
      &lt;ejb-link&gt;Example&lt;/ejb-link&gt;
   &lt;/ejb-local-ref&gt;
&lt;/web-app&gt;
</PRE></FONT></TD></TR></TBODY></TABLE></FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>注意用&lt;ejb-local-ref&gt;元素来声明本地EJB引用。通过&lt;ejb-link&gt;元素得到一个明显的与EJB的链接。它的值必须等于EJB XML描述符中的&lt;ejb-name&gt;元素。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black><B><FONT color=#333399>未来会有更大的灵活性？</FONT></B><BR>目前还是公开草案的EJB 2.1规范为访问无状态session beans定义了一个Web services客户端。远程客户端将以一种位置独立的方式与无状态session beans通讯，这种通讯主要运用SOAP 1.1通过HTTP进行基于XML的调用。因为XML、SOAP和HTTP是独立于语言的，所以客户端不需要是Java对象，可以是运行在不同平台上的其它类型的对象。</FONT></P>
<P xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=black>到那时，EJB 2.0的新功能就会更受Java开发人员的欢迎了，使他们能够创建代码，更有效地运用本地和远程接口。通过运用这些功能，并对你的设计能力进行正确的评估，你就可以创建应用程序，使它们最大限度地运用EJBs。</FONT></P><BR xmlns:fo="http://www.w3.org/1999/XSL/Format"><FONT color=#666666 xmlns:fo="http://www.w3.org/1999/XSL/Format"><I>关于作者:</I></FONT><BR xmlns:fo="http://www.w3.org/1999/XSL/Format">Rudy Dahbura是位住在洛杉矶的软件顾问。他在洛杉矶的Sierra Systems Group工作，他运用分布式对象技术已经有五年了。他的联系方式是<A href="" target=_blank xmlns:fo="http://www.w3.org/1999/XSL/Format">rdahbura@sierrasystems.com</A>。<BR xmlns:fo="http://www.w3.org/1999/XSL/Format"><img src ="http://www.blogjava.net/relax/aggbug/22267.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/relax/" target="_blank">轻松</a> 2005-12-02 17:03 <a href="http://www.blogjava.net/relax/archive/2005/12/02/22267.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一段利用管道的多线程程序</title><link>http://www.blogjava.net/relax/archive/2005/12/02/22184.html</link><dc:creator>轻松</dc:creator><author>轻松</author><pubDate>Fri, 02 Dec 2005 01:05:00 GMT</pubDate><guid>http://www.blogjava.net/re