??xml version="1.0" encoding="utf-8" standalone="yes"?>
以字Wa的ASCIIZQ?int i = 'a'; String iBin = Integer.toBinaryString(i);//二进?String iHex = Integer.toHexString(i);//十六q制 String iOct = Integer.toOctalString(i);//八进?String iWoKao = Integer.toString(i,3);//三进制或M你想要的35q制以下的进?DEC
[集]java中进行二q制Q八q制Q十六进Ӟ十进刉q行怺转换 十进制{成十六进Ӟ Integer.toHexString(int i) 十进制{成八q制 Integer.toOctalString(int i) 十进制{成二q制 Integer.toBinaryString(int i) 十六q制转成十进?Integer.valueOf("FFFF",16).toString() 八进制{成十q制 Integer.valueOf("876",8).toString() 二进制{十进?Integer.valueOf("0101",2).toString()
有什么方法可以直接将2,8,16q制直接转换?0q制的吗? java.lang.Integerc?parseInt(String s, int radix) 使用W二个参数指定的基数Q将字符串参数解析ؓ有符L整数?examples from jdk: parseInt("0", 10) returns 0 parseInt("473", 10) returns 473 parseInt("-0", 10) returns 0 parseInt("-FF", 16) returns -255 parseInt("1100110", 2) returns 102 parseInt("2147483647", 10) returns 2147483647 parseInt("-2147483648", 10) returns -2147483648 parseInt("2147483648", 10) throws a NumberFormatException parseInt("99", 8) throws a NumberFormatException parseInt("Kona", 10) throws a NumberFormatException parseInt("Kona", 27) returns 411787
q制转换如何写(二,八,十六Q不用算?Integer.toBinaryString Integer.toOctalString Integer.toHexString
例一Q?/p>
public class Test{ public static void main(String args[]){
int i=100; String binStr=Integer.toBinaryString(i); String otcStr=Integer.toOctalString(i); String hexStr=Integer.toHexString(i); System.out.println(binStr);
例二Q?/p>
public class TestStringFormat { public static void main(String[] args) { if (args.length == 0) { System.out.println("usage: java TestStringFormat <a number>"); System.exit(0); }
Integer factor = Integer.valueOf(args[0]);
String s;
s = String.format("%d", factor); System.out.println(s); s = String.format("%x", factor); System.out.println(s); s = String.format("%o", factor); System.out.println(s); } }
各种数字cd转换成字W串型:
String s = String.valueOf( value); // 其中 value ZQ意一U数字类型?
字符串型转换成各U数字类型:
String s = "169"; byte b = Byte.parseByte( s ); short t = Short.parseShort( s ); int i = Integer.parseInt( s ); long l = Long.parseLong( s ); Float f = Float.parseFloat( s ); Double d = Double.parseDouble( s );
数字cd与数字类对象之间的{换:
byte b = 169; Byte bo = new Byte( b ); b = bo.byteValue();
short t = 169; Short to = new Short( t ); t = to.shortValue();
int i = 169; b = bo.byteValue();
short t = 169; Short to = new Short( t ); t = to.shortValue();
int i = 169; Integer io = new Integer( i ); i = io.intValue();
long l = 169; Long lo = new Long( l ); l = lo.longValue();
float f = 169f; Float fo = new Float( f ); f = fo.floatValue();
double d = 169f; Double dObj = new Double( d ); d = dObj.doubleValue();
一、Ant使用中的OutOfMemoryError解决Q?/font>
C的Ant的安装目录,在bin子目录中扑ֈant.batQ用文字编辑器打开Q修?runAnt处的允许命oQ添加如下参敎ͼ
:runAnt
"%_JAVACMD%" -Xms128m -Xmx512m -classpath ……
如果你安装了JikeQ用Jike~译器,则需要修?runAntWithJikes处的q行命oQ同上?/font>
二、tomcat中的内存溢出优化
安装版的Q?/font>
讄的java选项卡有啦?/p>
非安装版的:
打开~辑catalina.batQ在文g开头处增加如下参数Q?/font>
set JAVA_OPTS=-Xms128m -Xmx512m
转自:http://blog.csdn.net/zzr173/archive/2006/12/11/1438691.aspx
一、XML
在十U技术中Q最重要的一U技术我惛_该非XML莫属。这里不仅仅指XML规范本nQ还包括一pd有关的基于XML的语aQ主要有XHTMLQ? XSLTQXSLQDTDsQXML Schema(XSD)QXPathQXQuery和SOAP.如果你现在还对XML一无所知,那么赶快狂补吧。XML是包含类gHTML标签的一个文 本文Ӟ在这个文件中定义了一个树型结构来描述它所保存?nobr>数据?/p>
XML最大的优点是你既可以在q个文本文g中存储结构化数据Q也可以在其中存储非l构化数据——也是_它能包含和描q?_糙?文档数据Q就象它描述"规则?表格数据一栗?/p>
XHTML是目前编写HTML的首选方?因ؓXHTML本n是格式良好的XMLQ与通常畸Ş的HTML文档相比Q?XHTML格式文档更容易处理?/p>
XSLT和XSL是对XML文档q行转换的语a。它们可以将XML文档转换成各U格式,比如另一个文本文件、PDF文g、HTML文g、逗号分割的文Ӟ或者{换成其它的XML文档?/p>
DTDs 和XML Schema用来描述XML文g所包含的数据内容的cdQ你不用编写定制的代码p对XML文档的内容进?有效?查,使内容强行遵守给出的规则?/p>
XPath ?XQuery是查询语aQ用它们可以从XML文档中吸取单个的数据Ҏ者数据项列表。XQuery的功能特别强大,因ؓ它对XPath查询q行了扩展。实际上QXQuery和XML的关pd像SQL之于关系数据库一栗?/p>
SOAP是Web services间进行通讯的标准协议。你不必知道SOAP协议的所有细节,但是你应该熟悉其常用规则及其工作原理Q这样你才能使用它?/p>
二、Web Services
Web
XML工作l的John Bosak曾说q:"XML使得Java有事可做"Q那么,我们也可以说QWeb服务使得所有语a都有事可做。Web服务让运行在大型Z的COBOL应用E序与运行在手持讑֤上的应用E序怺沟?让Java应用与。NET
三、面向对象编E?/strong>
许多E序员仍然认为OOP乃技术的象牙之塔Q但是细l想一下过dq里在面向对象领域里占据q统d位的开发语a之后Q你׃会这么认ZQ? OOP理念从Smalltalk开始,然后蔓g到C++和Pascal(Delphi)Q到Java成ؓ真正的主,几年之后QVB.NET ? C#的出现可以说是OOP发展Cd造极的地步。虽然用这些语a不必了解OOP的概念,但如果你~Z一些OOP的基本知识和ҎQ我想你很难在逐渐? 软的׃市场中找到工作?/p>
四、JavaQ?C++Q?C#Q?VB.NET
如果你热衷于技术,q且热爱~程Q那么我想你应该L玩{q些高语言Q我说的玩{q不一定要你成U编E高手。而是能看懂用q些语言~写? 代码卛_。如果你q有_֊用它们编码那更好了。其实这U机会甚。但是看代码的机会很多,学习~程的最有效的一U方式就是看源代码——浩如烟L源代? 中很多都不是用你所钟爱的开发语a~写的?/p>
在过ȝ几年里,各个语言功能的发展基本上都差不多。现在你完全可以用VB.NET来写Windows服务、Web应用或者命令行E序。即使你 只用其中的一U语a写程序。我认ؓ也完全有必要学习另外一U语aQ自己能阅d理解它们现有的例子代码,q且能将一U语a~写的代码{换成你首选的~程 语言代码。这里列出的四种语言可谓是一个强大的开发语a工具,如果你掌握了它们Q毫无疑问你一定是一个众ZԒ慕的高手。这里我要声明一下:那就是我q没 有要忽略和排除其它的高语言Q如QFORTRAN、COBOL、APL、ADA、Perl和Lisp{等Q根据你所从事的领域不同,应该选择适合的语a 和工兗?/p>
五、JavaScript
Java 和JavaScript两者的名字管很类|但它们之间ƈ没有什么关pRؓ什么一U脚本语a会如此重要,以至于将它列入十U关键技术之一?仔细想一? q道了Q目前所有主的览器都使用JavaScript.如果你要~写Web应用E序Q那么JavaScript不可或缺。此外, JavaScriptq能作ؓ一U?nobr>服务器端? 脚本语言Q如它嵌入在ASP、ASP.NET中,或者嵌入XSLT来扩展功能。目前JavaScript在Mozilla/Netscape中是Ȁzd 于XUL界面的首选语aQ它zZActionScriptQ成为Flash MX应用的编E语a。还有就是JavaScript极有可能成ؓ未来新设备的脚本语言以及L应用的宏语言?/p>
相比之下QVBScript虽然在微软的产品中得到很好的支持Q但从长q来看,没有q象表明它会有美好前途。微软自己都向于用 JavaScript(或者用由JavaScriptz的JScript)来编写其客户端脚本代码。因此,如果你要选择脚本语言Q非 JavaScript莫属?/p>
六、Regular Expressions
从所周知Q关pL据库的查询用SQLQ搜索XML文档用XPath 和XQueryQ而正则表辑ּ则用来搜索纯文本。例如,你可以用一个命令来查找或删除HTML格式文g中的注释内容。大安用过"IndexOf"? "InStr"以及"Like"q些内徏在JavaScript或VB中的文本搜烦函数Q这些函数虽然很Ҏ使用Q但是它们的功能却无法与正则表达式同? 而语——现在每一U主的开发语a都提供对正则表达式的存取。尽有为正则表辑ּ本n的读写艰涩难懂,但毕竟它的功能强大,使用它的领域也越来越多?/p>
七、Design Patterns
像OOP通过创徏和分cd象来化编E一P设计模式普通的对象交互分类成指定的模型Q这是一个从一般到具体的过E。OOP的成分用得多Q设计模式就昑־有用武之地。所以你必须理解它们Q跟上其M理论的发展?/p>
八、Flash MX
当你需要比HTML和CSS所能提供的更多的客L囑Ş和编E能力时QFlash是最佳选择。在Flash中编E比用Java应用或者。NET代码来得快得多,也容易得多?/p>
在最新版本中(MX)QFlash不仅可以d和进行动L包,它还是个高度的可~程应用环境。具备强大的与SOAP Web服务沟通的能力Q可以调用运行在q端服务器上的ColdFusion、Java或。NET代码。可以说Flash几乎无处不在Q包括手持设备、置? 盒、甚x新的qx电脑Q你到处都可以见到它的n影,所以用它实际上可以扩展和延你的应用E序使用领域?/p>
九、Linux/Windows
q是当今PCs?nobr>操作pȝ? 两大阵容Q如果你惛_计算业里P׃定要熟悉它们。对于LinuxQ最好能自己安装Q配|,下蝲它的囑Ş用户界面以及一些应用程序。自己安? Apacheq会~写Web应用E序。要清醒地认识到q个世界除了Windows之外Q还有Linux的存在。ƈ且这U局面将会长期存在。反q来Q如果你 是一个死忠的Linux开发者,不要再l对Windows的憎Ӟ要相互学习,取长补短Q看看Windows有什么好的东东可以采U뀂记? Windows仍然是桌面之王?/p>
谁也说不准你们公总么时候会军_从Linux转向WindowsQ或者从Windows转向Linux.谁也说不准什么时候你会蟩槽跑到另? 一个用不同^台的公司上班——或者即便不xQ也有可能在不同q_上开始另外一个杀手目——所以最好在每个q_上都U篏一些经验,而不要在一|? 吊死?/p>
十、SQL
管SQL在当今众多的技术中已不是什么新东西Q而且在未来的十年里它的作用很有可能被削弱Q甚x个被淘汰Q但它仍然是一U基本技能——别? 它是一U基本技能,至今仍有许多开发h员不懂什么是SQL或对它了解不多。不要指望基于图形用L面的SQL构造器会帮你的忙,q是自己亲手写SQL查询 吧,定你掌握了SQL的基本语法。现在理解了SQLQ不仅对以后学习XQuery有所裨益Q而且可以使你很快扑ֈ化或改进当前开发项目的途径?/p>
֣Q培d技术的好奇?/strong>
其实Q不技术的发展势如何Q每个h最重要的一个技能是好奇心。敢于面Ҏ战,在你目前或未来的工作中,新语a或新技术可能很重要Q也可能? 怎么重要Q你所学习的东西ƈ不一定非要针对你的工作。不要怕失败,M新的技术对初学者来说都是困隄。大多数的失败都可以归咎于本w急功q利Q希望? 成。俗话说——千里之行,始于下Q应该脚t实圎ͼ一步一个脚印地往前走。不要让旉来左右你行动Q而是要利用时间来x、研I、测试新的开发技术和? 兗?br />
注:以上内容来自|络Q本Z承担Mq带责Q
转自Q赛q网
有许多标准和实践准则可适用于Java开发者,但此处要说的Q是每个Java开发者需坚守的基本原则?/p>
一、ؓ代码加注?/strong>。虽然每个h都知道这点,但有时却不自觉忘了行,今天?#8220;忘了”加注释了?虽然注释?E序的功能没什?#8220;贡献”Q但q一D?strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">旉Q? 比如说两星期之后或者更长,回过头来看看自己的代码,说不定已l记不住它是q什么的了。如果这些代码是你个人的Q那q算是走q了Q不q的是,当然了,大多 数时候都是别人的不幸Q很多时候大安是在为公司写代码Q写代码的h也许早已l离开了公司,但别忘了一句古话,有来有往嘛,Z人,也ؓ我们自己Q请Z 的代码加上注释?
二、不要让事情复杂?/strong>?strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">E序?/strong>有时候L?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;">解决ҎQ? 比如_在只有五个用LE序中引入EJB、对E序实现了ƈ不需要的框架(framework)Q之cȝq有属性文件、面向对象解x案、多U程{等。ؓ 什么要q样做呢?也许我们q不知道是否q样会更好,但这样做也许可以学到一些新东西Q或者让自己更感兴趣一些。如果是不知道ؓ什么这样做Q徏议多hl验 丰富的程序员Q如果是Z个h的目的,ȝ让自己更专业一炏V?
三、始l牢?/strong>—?#8220;即是好(Less is more)q不L对的”。代码效率虽然很重要Q但在许多解x案中Q编写更的代码q不能改善这些代码的效率Q请看下面这个简单的例子Q?
if(newStatusCode.equals("SD") && (sellOffDate == null || todayDate.compareTo(sellOffDate)<0 || (lastUsedDate != null && todayDate.compareTo(lastUsedDate)>0)) || (newStatusCode.equals("OBS") && (OBSDate == null || todayDate.compareTo(OBSDate)<0))){ newStatusCode = "NYP"; } |
能看明白if条g语句是干什么的?能想出来是谁写的q段代码?如果把它分成两段独立的if语句Q是不是更容易理解呢Q下面是修改后的代码Q?
if(newStatusCode.equals("SD") && (sellOffDate == null || todayDate.compareTo(sellOffDate)<0 || (lastUsedDate != null && todayDate.compareTo(lastUsedDate)>0))){ newStatusCode = "NYP"; }else if(newStatusCode.equals("OBS") && (OBSDate == null || todayDate.compareTo(OBSDate)<0)) { newStatusCode = "NYP"; } |
是不是读hҎ多了呢,在此只是多加了一个if和两个花括号Q但代码的可L与可理解性就一下子提高了一大截?
四、请不要编?/strong>。开发者经常有?#8220;忘记”或忽略掉q点Q因为有些时候开发日E逼得实在太紧。其实,多写一行定义静态变量的代码能花多少旉?
public class A { public static final String S_CONSTANT_ABC = "ABC"; public boolean methodA(String sParam1){ if (A.S_CONSTANT_ABC.equalsIgnoreCase(sParam1)){ return true; } return false; } } |
现在Q每ơ需要将“ABC”与其他变量进行比较时Q不必记住实际代码,直接引用A.S_CONSTANT_ABCp了,而且在今后需要进行修ҎQ也可在一处修改,不会遍整个源代码逐个修改了?
五、不?#8220;创?#8221;自己的框?framework)?/strong>切来说Q有C千计的各U框架存在,而且大多数是开 源的Q这些框枉是优U的解x案,可用于日?strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">E序开?/strong>中, 我们只需使用q些框架的最新版本就行了Q至表面上要跟上Ş势吧。被大家qؓ接受的最为明昄一个例子就是Struts了,q个开源web框架非常适合? 在基于web的应用程序中。是不是惛_发出自己的Struts呢,q是省点力气吧,回头看看W二条——不要让事情复杂化。另外,如果正在开发的E序只有3 个窗口,׃要用Struts了,对这U程序来_不需要那么多?#8220;控制”?
六、不要用println及字W串q接。通常Z调试方便Q开发者喜Ƣ在可能的所有地斚w加上 System.out.printlnQ也许还会提醒自己回q头来再来删除,但有些时候,l常会忘了删除或者不愿意删除它们。既然?System.out.println是ؓ?strong style="border: 0px none ; margin: 0px; padding: 0px; font-weight: normal; color: #0000ff; text-decoration: underline;">试Q那么测试完之后Qؓ什么还要留着它们呢,因ؓ在删除时Q很可能会删除掉真正有用的代码,所以不能低?System.out.println危害啊,L下面的代码:
public class BadCode { public static void calculationWithPrint(){ double someValue = 0D; for (int i = 0; i < 10000; i++) { System.out.println(someValue = someValue + i); } } public static void calculationWithOutPrint(){ double someValue = 0D; for (int i = 0; i < 10000; i++) { someValue = someValue + i; } } public static void main(String [] n) { BadCode.calculationWithPrint(); BadCode.calculationWithOutPrint(); } } |
从测试中可以发现Q方法calculationWithOutPrint()执行用了0.001204U,作ؓҎQ方法calculationWithPrint()执行可是用了10.52U?
要避免浪费CPU旉Q最好的Ҏ是引入像如下的包装方法:
public class BadCode { |
另外Q字W串q接也是费CPU旉的一个大_L下面的示例代码:
public static void concatenateStrings(String startingString) { for (int i = 0; i < 20; i++) { startingString = startingString + startingString; } } public static void concatenateStringsUsingStringBuffer(String startingString) { StringBuffer sb = new StringBuffer(); sb.append(startingString); for (int i = 0; i < 20; i++) { sb.append(sb.toString()); } } |
在测试中可发玎ͼ使用StringBuffer的方法只用了0.01U执行完毕,而用连接的Ҏ则用?.08U,选择显而易见了?
七、多xGUI(用户界面)?/strong>再三QGUI对商业客h_与程序的功能及效率同{重要,GUI是一 个成功程序的最基本部分Q而很多ITl理往往都没注意到GUI的重要性。在现实生活中,许多公司可能Z节省开支,没有雇用那些有着设计“用户友好”界面 丰富l验的网设计者,此时Java开发者只能依赖他们自w的HTML基本功及在此领域有限的知识,l果Q很多开发出来的E序都是“计算?/strong>友好”甚于“?户友?#8221;。很有开发者同时精?strong style="border: 0px none ; font-weight: normal; color: #0000ff; text-decoration: underline;">软g开?/strong>及GUI设计Q如果你在公?#8220;不幸”被分配负责程序界面,应该遵守下面三条原则:
1?不要再发明一ơ轮子,即不做无用功。现有的E序可能会有cM的界面需求?
2?先创Z个原型。这是非帔R要一步,用户一般想看到他们用的东西Q而且可以先利用这个原型征求用L意见Q再慢慢修改成用h要的样子?
3?学会换位思考。换句话来说Q就是从用户的角度来审查E序的需求。D例来Ԍ一个汇ȝH口可以跨页或者不跨页Q作Z个Y件开发者,可能会們于不跨页Q因L单一些。但是,从用L角度来看Q可能不希望看到上百行数据都挤在同一上?
八、文档需求不放松。每个商业需求都必须记录在案Q这可能听上d童话Q似乎在现实生活中很隑֮现。而我们要做的是,不管开发时间多紧迫Q不最l期限多临近Q对每个商业需求都必须记录在案?
九、单元测试、单元测试、单元测?/strong>。关于什么是单元试的最好方法,在此不便l说Q只是强调,单元试一定要完成Q这也是~程中最基本的原则。当然了Q如果有人帮你做单元试自然是最好,如果没有Q就自己来做吧,当创Z个单元测试计划时Q请遵守以下三条最基本的原则:
1?先于~写cM码之前编写单元测试?
2?记录单元试中的代码注释?
3?试所有执行关键功能的公有ҎQ这里不是指set和getҎQ除非它们是以自qҎ式执行set和getҎ?
十、质量,而不是数?/strong>。有些时候因Z品问题、期限紧q、或一些预料之外的事情Q导致常怸能按时下班,但一般而言Q公怸会因为雇员经常加班而对之表扬和奖励Q公司只看重高质量的工作。如果遵守了前九条原则,你会发现自己写出的代码bug且可维护性高Q无形中质量提高了一大步?/p>
注:以上内容来自|络Q本Z承担Mq带责Q 文章转自Q?br />
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1956723
]]>
毋庸|疑Q程序员要对自己~写的代码负责,您不仅要保证它能通过~译Q正常地q行Q而且要满需求和设计预期的效果。单元测试正是验证代码行为是否满预期的有效手段之一。但不可否认Q做试是g很枯燥无的事情Q而一遍又一遍的试则更是让人生畏的工作。幸q的是,单元试工具 JUnit 使这一切变得简单艺术v来?/p>
JUnit ?Java C中知名度最高的单元试工具。它诞生?1997 q_?Erich Gamma ?Kent Beck 共同开发完成。其?Erich Gamma 是经典著作《设计模式:可复用面向对象Y件的基础》一书的作者之一Qƈ?Eclipse 中有很大的A献;Kent Beck 则是一位极限编E(XPQ方面的专家和先驱?/p>
麻雀虽小Q五脏俱全。JUnit 设计的非常小巧,但是功能却非常强大。Martin Fowler 如此评h JUnitQ在软g开发领域,从来没有如此少的代码vC如此重要的作用。它大大化了开发h员执行单元测试的隑ֺQ特别是 JUnit 4 使用 Java 5 中的注解QannotationQɋ试变得更加单?/p>
![]() ![]() |
![]()
|
在开始体?JUnit 4 之前Q我们需要以下Y件的支持Q?/p>
首先为我们的体验新徏一?Java 工程 —?coolJUnit。现在需要做的是Q打开目 coolJUnit 的属性页 -> 选择“Java Build Path”子选项 -> 炚w“Add Library…”按?-> 在弹出的“Add Library”对话框中选择 JUnitQ?a >?Q,q在下一中选择版本 4.1 后点几ZFinish”按钮。这样便?JUnit 引入到当前项目库中了?/p>
? 为项目添?JUnit ?/b>
![]() |
|
可以开始编写单元测试了吗?{等……,您打把单元试代码攑֜什么地方呢Q把它和被测试代码在一Pq显然会照成混ؕQ因为单元测试代码是不会出现在最l品中的。徏议您分别为单元测试代码与被测试代码创建单独的目录Qƈ保证试代码和被试代码使用相同的包名。这h保证了代码的分离Q同时还保证了查扄方便。遵照这条原则,我们在项?coolJUnit 根目录下d一个新目录 testsrcQƈ把它加入到项目源代码目录中(加入方式??Q?/p>
? 修改目源代码目?/b>
现在我们得到了一?JUnit 的最佛_践:单元试代码和被试代码使用一L包,不同的目录?/p>
一切准备就l,一起开始体验如何?JUnit q行单元试吧。下面的例子来自W者的开发实践:工具c?WordDealUtil 中的静态方?wordFormat4DB 是专用于处理 Java 对象名称向数据库表名转换的方法(您可以在代码注释中可以得到更多详l的内容Q。下面是W一ơ编码完成后大致情ŞQ?/p>
package com.ai92.cooljunit; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * 对名U、地址{字W串格式的内容进行格式检? * 或者格式化的工L * * @author Ai92 */ public class WordDealUtil { /** * Java对象名称Q每个单词的头字母大写)按照 * 数据库命名的习惯q行格式? * 格式化后的数据ؓ写字母Qƈ且用下划线分割命名单词 * * 例如QemployeeInfo l过格式化之后变?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(); } } |
它是否能按照预期的效果执行呢Q尝试ؓ它编?JUnit 单元试代码如下Q?/p>
package com.ai92.cooljunit; import static org.junit.Assert.assertEquals; import org.junit.Test; public class TestWordDealUtil { //试wordFormat4DB正常q行的情? @Test public void wordFormat4DBNormal(){ String target = "employeeInfo"; String result = WordDealUtil.wordFormat4DB(target); assertEquals("employee_info", result); } } |
很普通的一个类嘛!试c?TestWordDealUtil 之所以用“Test”开_完全是ؓ了更好的区分试cM被测试类。测试方?wordFormat4DBNormal 调用执行被测试方?WordDealUtil.wordFormat4DBQ以判断q行l果是否辑ֈ设计预期的效果。需要注意的是,试Ҏ wordFormat4DBNormal 需要按照一定的规范书写Q?/p>
试Ҏ中要处理的字W串为“employeeInfo”,按照设计目的Q处理后的结果应该ؓ“employee_info”。assertEquals 是由 JUnit 提供的一pd判断试l果是否正确的静态断aҎQ位于类 org.junit.Assert 中)之一Q我们用它执行结?result 和预期值“employee_info”进行比较,来判断测试是否成功?/p>
看看q行l果如何。在试cM点击右键Q在弹出菜单中选择 Run As JUnit Test。运行结果如下图所C:
l色的进度条提示我们Q测试运行通过了。但现在宣布代码通过了单元测试还为时q早。记住:您的单元试代码不是用来证明您是对的Q而是Z证明您没有错。因此单元测试的范围要全面,比如对边界倹{正常倹{错误值得试Q对代码可能出现的问题要全面预测Q而这也正是需求分析、详l设计环节中要考虑的。显Ӟ我们的测试才刚刚开始,l箋补充一些对Ҏ情况的测试:
public class TestWordDealUtil { …? //试 null 时的处理情况 @Test public void wordFormat4DBNull(){ String target = null; String result = WordDealUtil.wordFormat4DB(target); assertNull(result); } //试I字W串的处理情? @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); } } |
再次q行试。很遗憾QJUnit q行界面提示我们有两个测试情冉|通过试Q?a >?Q——当首字母大写时得到的处理结果与预期的有偏差Q造成试p|QfailureQ;而当试?null 的处理结果时Q则直接抛出了异常——测试错误(errorQ。显Ӟ被测试代码中q没有对首字母大写和 null q两U特D情况进行处理,修改如下Q?/p>
//修改后的ҎwordFormat4DB /** * Java对象名称Q每个单词的头字母大写)按照 * 数据库命名的习惯q行格式? * 格式化后的数据ؓ写字母Qƈ且用下划线分割命名单词 * 如果参数name为nullQ则q回null * * 例如QemployeeInfo l过格式化之后变?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(); } |
JUnit 测试失败的情况分ؓ两种Qfailure ?error。Failure 一般由单元试使用的断aҎ判断p|引vQ它表示在测试点发现了问题;?error 则是׃码异常引Pq是试目的之外的发玎ͼ它可能生于试代码本n的错误(试代码也是代码Q同h法保证完全没有缺PQ也可能是被试代码中的一个隐藏的bug?/p>
![]() |
|
啊哈Q再ơ运行测试,l条又重现眼前。通过?WordDealUtil.wordFormat4DB 比较全面的单元测试,现在的代码已l比较稳定,可以作ؓ API 的一部分提供l其它模块用了?/p>
不知不觉中我们已l?JUnit 漂亮的完成了一ơ单元测试。可以体会到 JUnit 是多么轻量Q多么简单,Ҏ不需要花心思去研究Q这可以把更多的注意力攑֜更有意义的事情上——编写完整全面的单元试?/p>
![]() ![]() |
![]()
|
当然QJUnit 提供的功能决不仅仅如此简单,在接下来的内容中Q我们会看到 JUnit 中很多有用的Ҏ,掌握它们Ҏ灉|的编写单元测试代码非常有帮助?/p>
何谓 FixtureQ它是指在执行一个或者多个测试方法时需要的一pd公共资源或者数据,例如试环境Q测试数据等{。在~写单元试的过E中Q您会发现在大部分的试Ҏ在进行真正的试之前都需要做大量的铺垫——ؓ设计准备 Fixture 而忙。这些铺垫过E占据的代码往往比真正测试的代码多得多,而且q个比率随着试的复杂程度的增加而递增。当多个试Ҏ都需要做同样的铺垫时Q重复代码的“坏味道”便在测试代码中弥O开来。这股“坏味道”会弄脏您的代码Q还会因为疏忽造成错误Q应该用一些手D|栚w它?/p>
JUnit 专门提供了设|公?Fixture 的方法,同一试cM的所有测试方法都可以q它来初始?Fixture 和注销 Fixture。和~写 JUnit 试Ҏ一P公共 Fixture 的设|也很简单,您只需要:
遵@上面的三条原则,~写出的代码大体是这个样子:
//初始化FixtureҎ @Before public void init(){……} //注销FixtureҎ @After public void destroy(){……} |
q样Q在每一个测试方法执行之前,JUnit 会保?init Ҏ已经提前初始化测试环境,而当此测试方法执行完毕之后,JUnit 又会调用 destroy Ҏ注销试环境。注意是每一个测试方法的执行都会触发对公?Fixture 的设|,也就是说使用注解 Before 或?After 修饰的公?Fixture 讄Ҏ是方法别的Q?a >?Q。这样便可以保证各个独立的测试之间互不干扎ͼ以免其它试代码修改试环境或者测试数据媄响到其它试代码的准性?/p>
? ҎU别 Fixture 执行C意?/b>
可是Q这U?Fixture 讄方式q是引来了批评,因ؓ它效率低下,特别是在讄 Fixture 非常耗时的情况下Q例如设|数据库链接Q。而且对于不会发生变化的测试环境或者测试数据来_是不会媄响到试Ҏ的执行结果的Q也没有必要针Ҏ一个测试方法重新设|一?Fixture。因此在 JUnit 4 中引入了cȝ别的 Fixture 讄ҎQ编写规范如下:
cȝ别的 Fixture 仅会在测试类中所有测试方法执行之前执行初始化Qƈ在全部测试方法测试完毕之后执行注销ҎQ?a >?Q。代码范本如下:
//cȝ别Fixture初始化方? @BeforeClass public static void dbInit(){……} //cȝ别Fixture注销Ҏ @AfterClass public static void dbClose(){……} |
注解 org.junit.Test 中有两个非常有用的参敎ͼexpected ?timeout。参?expected 代表试Ҏ期望抛出指定的异常,如果q行试q没有抛个异常,?JUnit 会认个测试没有通过。这为验证被试Ҏ在错误的情况下是否会抛出预定的异常提供了便利。D例来_Ҏ supportDBChecker 用于查用户用的数据库版本是否在pȝ的支持的范围之内Q如果用户用了不被支持的数据库版本Q则会抛行时异常 UnsupportedDBVersionException。测试方?supportDBChecker 在数据库版本不支持时是否会抛出指定异常的单元试Ҏ大体如下Q?/p>
@Test(expected=UnsupportedDBVersionException.class) public void unsupportedDBCheck(){ …? } |
注解 org.junit.Test 的另一个参?timeoutQ指定被试Ҏ被允许运行的最长时间应该是多少Q如果测试方法运行时间超q了指定的毫U数Q则JUnit认ؓ试p|。这个参数对于性能试有一定的帮助。例如,如果解析一份自定义?XML 文档p了多?1 U的旉Q就需要重新考虑 XML l构的设计,那单元测试方法可以这h写:
@Test(timeout=1000) public void selfXMLReader(){ …? } |
JUnit 提供注解 org.junit.Ignore 用于暂时忽略某个试ҎQ因为有时候由于测试环境受限,q不能保证每一个测试方法都能正运行。例如下面的代码便表C由于没有了数据库链接,提示 JUnit 忽略试Ҏ unsupportedDBCheckQ?/p>
@ Ignore(“db is down? @Test(expected=UnsupportedDBVersionException.class) public void unsupportedDBCheck(){ …? } |
但是一定要心。注?org.junit.Ignore 只能用于暂时的忽略测试,如果需要永q忽略这些测试,一定要认被测试代码不再需要这些测试方法,以免忽略必要的测试点?/p>
又一个新概念出现了——测试运行器QJUnit 中所有的试Ҏ都是由它负责执行的。JUnit 为单元测试提供了默认的测试运行器Q但 JUnit q没有限制您必须使用默认的运行器。相反,您不仅可以定制自qq行器(所有的q行器都l承?org.junit.runner.RunnerQ,而且q可以ؓ每一个测试类指定使用某个具体的运行器。指定方法也很简单,使用注解 org.junit.runner.RunWith 在测试类上显式的声明要用的q行器即可:
@RunWith(CustomTestRunner.class) public class TestWordDealUtil { …? } |
显而易见,如果试cL有显式的声明使用哪一个测试运行器QJUnit 会启动默认的试q行器执行测试类Q比如上面提及的单元试代码Q。一般情况下Q默认测试运行器可以应对l大多数的单元测试要求;当?JUnit 提供的一些高U特性(例如卛_介绍的两个特性)或者针对特D需求定?JUnit 试方式Ӟ昑ּ的声明测试运行器必不可了?/p>
在实际项目中Q随着目q度的开展,单元试cM来多Q可是直到现在我们还只会一个一个的单独q行试c,q在实际目实践中肯定是不可行的。ؓ了解册个问题,JUnit 提供了一U批量运行测试类的方法,叫做试套g。这P每次需要验证系l功能正性时Q只执行一个或几个试套g便可以了。测试套件的写法非常单,您只需要遵循以下规则:
package com.ai92.cooljunit; import org.junit.runner.RunWith; import org.junit.runners.Suite; …? /** * 扚w试 工具?中测试类 * @author Ai92 */ @RunWith(Suite.class) @Suite.SuiteClasses({TestWordDealUtil.class}) public class RunAllUtilTestsSuite { } |
上例代码中,我们前文提到的试c?TestWordDealUtil 攑օ了测试套?RunAllUtilTestsSuite 中,?Eclipse 中运行测试套Ӟ可以看到试c?TestWordDealUtil 被调用执行了。测试套件中不仅可以包含基本的测试类Q而且可以包含其它的测试套Ӟq样可以很方便的分层理不同模块的单元测试代码。但是,您一定要保证试套g之间没有循环包含关系Q否则无的循环׃出现在您的面前……?/p>
回顾一下我们在节?a >JUnit 初体?/font>”中丄实例。ؓ了保证单元测试的严}性,我们模拟了不同类型的字符串来试Ҏ的处理能力,为此我们~写大量的单元测试方法。可是这些测试方法都是大同小异:代码l构都是相同的,不同的仅仅是试数据和期望倹{有没有更好的方法将试Ҏ中相同的代码l构提取出来Q提高代码的重用度,减少复制_脓代码的烦|在以前的 JUnit 版本上,q没有好的解x法,而现在您可以使用 JUnit 提供的参数化试方式应对q个问题?/p>
参数化测试的~写E微有点ȝQ当然这是相对于 JUnit 中其它特性而言Q: 我们按照q个标准Q重新改造一番我们的单元试代码Q?/p>
很明显,代码瘦n了。在静态方?words 中,我们使用二维数组来构建测试所需要的参数列表Q其中每个数l中的元素的攄序q没有什么要求,只要和构造函C的顺序保持一致就可以了。现在如果再增加一U测试情况,只需要在静态方?words 中添加相应的数组卛_Q不再需要复制粘贴出一个新的方法出来了?/p>
随着目的进展,目的规模在不断的膨胀Qؓ了保证项目的质量Q有计划的执行全面的单元试是非常有必要的。但单靠JUnit提供的测试套件很难胜任这工作,因ؓ目中单元测试类的个数在不停的增加,试套g却无法动态的识别新加入的单元试c,需要手动修Ҏ试套Ӟq是一个很Ҏ遗忘得步骤,E有疏忽׃影响全面单元试的覆盖率?/p>
当然解决的方法有多种多样Q其中将 JUnit 与构建利?Ant l合使用可以很简单的解决q个问题。Ant —?备受赞誉?Java 构徏工具。它凭借出色的易用性、^台无x以及对目自动试和自动部|的支持Q成Z多项目构E中不可或缺的独立工Pq已l成Z实上的标准。Ant 内置了对 JUnit 的支持,它提供了两个 TaskQjunit ?junitreportQ分别用于执?JUnit 单元试和生成测试结果报告。用这两个 Task ~写构徏脚本Q可以很单的完成每次全面单元试的Q务? 不过Q在使用 Ant q行 JUnit 之前Q您需要稍作一些配|。打开 Eclipse 首选项界面Q选择 Ant -> Runtime 首选项Q见?Q,?JUnit 4.1 ?JAR 文gd?Classpath Tab 中?Global Entries 讄w。记得检查一?Ant Home Entries 讄中?Ant 版本是否?1.7.0 之上Q如果不是请替换为最新版本的 Ant JAR 文g?/p>
剩下的工作就是要~写 Ant 构徏脚本 build.xml。虽然这个过E稍嫌繁琐,但这是一件一x逸的事情。现在我们就把前面编写的试用例都放|到 Ant 构徏脚本中执行,为项?coolJUnit 的构本添加一下内容: Target junit report ?Ant 构徏脚本中的核心内容Q其?target 都是为它的执行提供前期服务。Task junit 会寻找输出目录下所有命名以“Test”开头的 class 文gQƈ执行它们。紧接着 Task junitreport 会将执行l果生成 HTML 格式的测试报告(?Q放|在“report folder”下?/p>
为整个项目的单元试cȝ定一U命名风根{不仅是Z区分cd的考虑Q这?Ant 扚w执行单元试也非常有帮助Q比如前面例子中的测试类都已“Test”打_而测试套件则以“Suite”结{?/p>
现在执行一ơ全面的单元试变得非常单了Q只需要运行一?Ant 构徏脚本Q就可以走完所有流E,q能得到一份详的试报告。您可以?Ant 在线手册 中获得上面提及的每一?Ant 内置 task 的用细节?/p>
随着来多的开发h员开始认同ƈ接受极限~程QXPQ的思想Q单元测试的作用在Y件工E中变得来重要。本文旨在将最新的单元试工具 JUnit 4 介绍l您Q以及如何结?IDE Eclipse 和构建工?Ant 创徏自动化单元测试方案。ƈ且还期望您能够通过本文“感染”一些好的单元测试意识,因ؓ JUnit 本n仅仅是一份工兯已Q它的真正优势来自于它的思想和技术?/p>
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 时的处理情况
{"", ""}, //试I字W串时的处理情况
{"employee_info", "EmployeeInfo"}, //试当首字母大写时的情况
{"employee_info_a", "employeeInfoA"}, //试当尾字母为大写时的情?
{"employee_a_info", "employeeAInfo"} //试多个相连字母大写时的情况
});
}
/**
* 参数化测试必ȝ构造函?
* @param expected 期望的测试结果,对应参数集中的第一个参?
* @param target 试数据Q对应参数集中的W二个参?
*/
public TestWordDealUtilWithParam(String expected , String target){
this.expected = expected;
this.target = target;
}
/**
* 试?Java 对象名称到数据库名称的{?
*/
@Test public void wordFormat4DB(){
assertEquals(expected, WordDealUtil.wordFormat4DB(target));
}
}
回页?/font>
? Ant Runtime 首选项
<?xml version="1.0"?>
<!-- =============================================
auto unittest task
ai92
========================================== -->
<project name="auto unittest task" default="junit and report" basedir=".">
<property name="output folder" value="bin"/>
<property name="src folder" value="src"/>
<property name="test folder" value="testsrc"/>
<property name="report folder" value="report" />
<!-- - - - - - - - - - - - - - - - - -
target: test report folder init
- - - - - - - - - - - - - - - - - -->
<target name="test init">
<mkdir dir="${report folder}"/>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compile
- - - - - - - - - - - - - - - - - -->
<target name="compile">
<javac srcdir="${src folder}" destdir="${output folder}" />
<echo>compilation complete!</echo>
</target>
<!-- - - - - - - - - - - - - - - - - -
target: compile test cases
- - - - - - - - - - - - - - - - - -->
<target name="test compile" depends="test init">
<javac srcdir="${test folder}" destdir="${output folder}" />
<echo>test compilation complete!</echo>
</target>
<target name="all compile" depends="compile, test compile">
</target>
<!-- ========================================
target: auto test all test case and output report file
===================================== -->
<target name="junit and report" depends="all compile">
<junit printsummary="on" fork="true" showoutput="true">
<classpath>
<fileset dir="lib" includes="**/*.jar"/>
<pathelement path="${output folder}"/>
</classpath>
<formatter type="xml" />
<batchtest todir="${report folder}">
<fileset dir="${output folder}">
<include name="**/Test*.*" />
</fileset>
</batchtest>
</junit>
<junitreport todir="${report folder}">
<fileset dir="${report folder}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${report folder}" />
</junitreport>
</target>
</project>
? junitreport 生成的测试报?/b>
回页?/font>
回页?/font>
描述
名字
大小
下蝲Ҏ
本文CZ代码
coolJUnit.zip
24 KB
HTTP
关于下蝲Ҏ的信?/font>
学习
获得产品和技?/b>
]]>
1Q?/span>
?/span>
web.xml
里面加入
<context-param>
<param-name>weblogic.httpd.inputCharset./*</param-name>
<param-value>GB2312</param-value>
</context-param>
2Q?/span>
?/span>
weblogic.xml
里面加入
<jsp-descriptor>
<jsp-param>
<param-name>compileCommand</param-name>
<param-value>javac</param-value>
</jsp-param>
<jsp-param>
<param-name>compilerSupportsEncoding</param-name>
<param-value>true</param-value>
</jsp-param>
<jsp-param>
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</jsp-param>
</jsp-descriptor>
java代码: |
INITIAL_CONTEXT_FACTORY=com.sun.jndi.fscontext.RefFSContextFactory PROVIDER_URL=file:/C:/JNDI-Directory |
java代码: |
def qcf(ivtQCF) def q(ivtQ) qu(SYSTEM.DEFAULT.LOCAL.QUEUE) def tcf(ivtTCF) def t(ivtT) topic(MQJMS/PSIVT/Information) |
java代码: |
JNDI Initial Context Factory->com.sun.jndi.fscontext.RefFSContextFactory JNDI Connection URL->file:/C:/JNDI-Directory |
java代码: |
Local JNDI Name:mqqcf(在weblogic 中用的QueueConnectionFactory的JNDI的名?SPAN style="COLOR: #000000">) Remote JNDI Name:ivtQCF(已经在通过jmsadmin配置º玫Äjndi的名?SPAN style="COLOR: #000000">) |
java代码: |
Local JNDI Name: MQQUEUE Remote JNDI Name: ivtQ |
java代码: |
<?xml version="1.0"?> <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd"> <!-- This ejb-jar.xml file defines a message-driven bean called "SimpleMDB". It uses container-managed transactions, because "transaction-type" is "Container" and "trans-attribute" is "Required". --> <ejb-jar> <enterprise-beans> <message-driven> <ejb-name>ReceiveMessageMDB</ejb-name> <ejb-class>com.rm.mdb.ReceiveMessageBean</ejb-class> <transaction-type>Container</transaction-type> <message-driven-destination> <!-- In WebLogic Server 6.0, this next parameter is named "jms-destination-type" --> <destination-type>javax.jms.Queue</destination-type> </message-driven-destination> </message-driven> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>ReceiveMessageMDB</ejb-name> <method-name>*</method-name> </method> <trans-attribute>NotSupported</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> |
java代码: |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE weblogic-ejb-jar PUBLIC '-//BEA Systems, Inc.//DTD WebLogic 8.1.0 EJB//EN' 'http://www.bea.com/servers/wls810/dtd/weblogic-ejb-jar.dtd'> <weblogic-ejb-jar> <weblogic-enterprise-bean> <ejb-name>ReceiveMessageMDB</ejb-name> <message-driven-descriptor> <pool> <max-beans-in-free-pool>8</max-beans-in-free-pool> <initial-beans-in-free-pool>1</initial-beans-in-free-pool> </pool> <destination-jndi-name>MQQUEUE</destination-jndi-name> <initial-context-factory> weblogic.jndi.WLInitialContextFactory </initial-context-factory> <provider-url>t3://localhost:7001</provider-url> <connection-factory-jndi-name>MQQCF</connection-factory-jndi-name> </message-driven-descriptor> </weblogic-enterprise-bean> </weblogic-ejb-jar> |
当前的EJB 2.0规范有新的接口功能,q在原先的EJB 1.1中是没有的。学习运用这些新的功能,它们可以使你更容易地、更有效地访问EJB?/FONT>
~点是什么呢Q你牺牲位|的独立性,但有时侯Q这U代h值得的。了解何时、如何运用新的功能对~写设计良好的EJB应用E序是至关重要的?/FONT>
EJB 1.1规范lEJB客户端提供了一个remote interface和一个remote home interface与EJB实例交互Q得C|的透明度。以cM的Ş式,EJB 2.0规范现在lEJB客户端提供了一个local interface和一个local home interface来与׃n同一个JVM的EJB实例交互?/FONT>
EJB remote interfaceQjavax.ejb.EJBObjectQ和remote home interfaceQjavax.ejb.EJBHomeQ在本质上是Java RMI接口。远E客Lq用接口和与Java RMI-IIOP兼容的参CEJBs通讯。参数和Ҏ的结果值在同一个容器中传递,或者跨|络传递到q程容器?/FONT>
q种~程模式lEJB客户端提供了一U访问EJBlg的方法,好像这些组件是本地的一栗然后,容器可以透明地处理网l通讯和执行其它功能。这U方法很适合_粒度的Qcoarse-grainedQ方法调用,其中客户端和EJBs之间的客L通讯保持到最限度?/FONT>
相反QEJB local interfaceQjavax.ejb.EJBLocalObjectQ和local home interfaceQjavax.ejb.EJBLocalHomeQ不是Java RMI接口Q它们是EJB 2.0的新功能。本地客L——如其它EJBsQ运用相同JVM中传递的参数直接与EJBs通讯。这U技术消除了|络潜在的问题、参数复制的问题以及需要与Java RMI-IIOP兼容的问题。也意味着QEJB客户端可以运用一个更轻量U的~程模式来访问服务。该Ҏ很适合l粒度的Qfine-grainedQ方法调用,因ؓ作ؓEJB实例的位于同一个JVM中的EJB客户端可以用本地接口来避免不必要的费用?/FONT>
引进本地客户端生的另一个显著的变化是cd的{换。所有的EJB实例在运用前必须转换到它们恰当的接口cdQ所以,有时侯,在运用远E客LӞ要保证Java RMI-IIOP的兼Ҏ,你必d转换EJB实例前运用java.rmi.PortableRemoteObject.narrow()来羃(narrowQ它?/FONT>
但本地客L可以直接把EJB实例转换成local home interfacecdQ如下面的代码片D:
InitialContext initCtx = new
InitialContext();
ExampleLocalHome exampleLocalHome =
(ExampleLocalHome)initCtx.lookup("java:comp/
env/ejb/Example");
从local home创徏了EJB实例Q?
ExampleLocal exampleLocal =
exampleLocalHome.create();
也许EJB 2.0的最有趣、最Ҏ被忽视的一个方面就是session和entity beans可以同时q用q程和本地接口,q就l了你很大的灉|性。运用两U接口给了潜在的bean客户端最大程度的自由Q不它们是不是在一L?/FONT>
<session>?lt;entity>元素描述了session和entity bean的部|属性。EJB 1.1和EJB 2.0规范定义了两个元素,<home>?lt;remote>。(以前的规范需要两个元素,但它们在2.0版中是可选的Q。它们分别包含EJB remote home interface和remote interface的完全资格类名?
cM圎ͼEJB 2.0规范定义了两个附加的元素Q?lt;local-home>?lt;local>。正如你预料的,它们包含EJB local home interface和local interface的完全资格类名。下面的代码昄了如何运用这些新元素Q?
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>...</ejb-name>
<local-home>...</local-home>
<local>...</local>
<ejb-link>...</ejb-link>
...
</session>
</enterprise-beans>
<assembly-descriptor>
...
</assembly-descriptor>
</ejb-jar>
聪明地访问本地客L的一个实?/FONT>
本地EJB客户端的概念在如列表1所C的例子中得C很好地阐明,其中昄了一个无状态session beanQ它的local interface和它的local home interface。注意,接口不扩展java.rmi.Remote?
无状态session bean的XML部v描述如下面的代码所C,它也重点?lt;local>?lt;local-home>元素的运用:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise
JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
<enterprise-beans>
<session>
<ejb-name>Example</ejb-name>
<local-
home>com.acmecorp.ejb.ExampleLocalHome</
local-home>
<local>com.acmecorp.ejb.ExampleLocal</local>
<ejb-
class>com.acmecorp.ejb.ExampleBean</
ejb-class>
<session-
type>Stateless</session-type>
<transaction-
type>Container</transaction-type>
</session>
</enterprise-beans>
<assembly-descriptor>
<method-permission>
<unchecked/>
<method>
<ejb-name>Example</ejb-name>
<method-name>*</method-name>
</method>
</method-permission>
<container-transaction>
<method>
<ejb-name>Example</ejb-name>
<method-name>*</method-name>
</method>
<trans-
attribute>NotSupported</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
然后Q一个本地的客户端创建ƈ讉K一个已l创建的enterprise bean的实例。下面的代码也显CZ如何转换一个bean的实例,而不用先~小它:
<%@ page errorPage="/error.jsp"
import="javax.naming.*,
com.acmecorp.ejb.*"
%>
<%
InitialContext initCtx = new InitialContext();
ExampleLocalHome exampleLocalHome =
(ExampleLocalHome)initCtx.lookup("java:comp/env/
ejb/Example");
ExampleLocal exampleLocal =
exampleLocalHome.create();
%>
<html>
<head>
<title>Default</title>
<link rel="STYLESHEET" type="text/css"
href="styles/default.css">
</head>
<body>
<pre class="code"><%=
exampleLocal.getMessage() %></pre>
</body>
</html>
在这个例子中Q本地客L是一个JSP面Q因此是一个Weblg。(在有些情况中Q当Weblg位于相同的JVM中时Q它们访问EJB 2.0本地lg接口。)
最后是Weblg的部|描qͼ
<web-app>
<!-- EJB Reference information -->
<ejb-local-ref>
<ejb-ref-name>ejb/Example<
/ejb-ref-name>
<ejb-ref-type>Session<
/ejb-ref-type>
<local-home>com.acmecorp.ejb.ExampleLocalHome<
/local-home>
<local>com.acmecorp.ejb.ExampleLocal<
/local>
<ejb-link>Example</ejb-link>
</ejb-local-ref>
</web-app>
注意?lt;ejb-local-ref>元素来声明本地EJB引用。通过<ejb-link>元素得到一个明昄与EJB的链接。它的值必ȝ于EJB XML描述W中?lt;ejb-name>元素?/FONT>
未来会有更大的灵zL?
目前q是公开草案的EJB 2.1规范问无状态session beans定义了一个Web services客户端。远E客L以一U位|独立的方式与无状态session beans通讯Q这U通讯主要q用SOAP 1.1通过HTTPq行ZXML的调用。因为XML、SOAP和HTTP是独立于语言的,所以客L不需要是Java对象Q可以是q行在不同^C的其它类型的对象?/FONT>
到那ӞEJB 2.0的新功能׃更受Java开发h员的Ƣ迎了,使他们能够创Z码,更有效地q用本地和远E接口。通过q用q些功能Qƈ对你的设计能力进行正的评估Q你可以创建应用程序,使它们最大限度地q用EJBs?/FONT>
public class PipeIODemo1{
public static void main(String[] args) throws IOException{
//创徏一个管道输出流对象
PipedWriter out=new PipedWriter();
//创徏一个管道输入流对象
PipedReader in=new PipedReader();
//把管道输入流对象和管道输出流对象联接h
in.connect(out);
//以上2个语句等效于
//PipedReader in=new PipedReader(out);
OutThread objOut=new OutThread(out);
InThread objIn=new InThread(in);
objOut.start();
objIn.start();
try{
objOut.join();
objIn.join();
}catch (InterruptedException e){}
System.out.println();
System.out.println("Run Completed!!");
}
}
//定义一个写U程c?BR>class OutThread extends Thread{
private Writer out;
public OutThread(Writer out){
this.out=out;
}
public void run(){
try{
try{
for(char c='A'; c<='Z'; c++)
out.write(c);
}finally{
out.close();
}
}catch(IOException e){
getThreadGroup().uncaughtException(this, e);
}
}
}
class InThread extends Thread{
private Reader in;
public InThread(Reader in){
this.in=in;
}
public void run(){
int ch;
try{
try{
while ((ch=in.read())!=-1)
System.out.print((char)ch);
}finally{
in.close();
}
}catch(IOException e){
getThreadGroup().uncaughtException(this, e);
}
}
}
许多语言Q包括Perl、PHP、Python、JavaScript和JScriptQ都支持用正则表辑ּ处理文本Q一些文本编辑器用正则表辑ּ实现高“搜?替换”功能。那么Java又怎样呢?本文写作Ӟ一个包含了用正则表辑ּq行文本处理的Java规范需求(Specification RequestQ已l得到认可,你可以期待在JDK的下一版本中看到它? |
然而,如果现在需要用正则表辑ּQ又该怎么办呢Q你可以从Apache.org下蝲源代码开攄Jakarta-ORO库。本文接下来的内容先要地介绍正则表达式的入门知识Q然后以Jakarta-ORO APIZ介绍如何使用正则表达式? |
一、正则表辑ּ基础知识 |
我们先从单的开始。假设你要搜索一个包含字W“cat”的字符Ԍ搜烦用的正则表达式就是“cat”。如果搜索对大小写不敏感Q单词“catalog”、“Catherine”、“sophisticated”都可以匚w。也是_ |
![]() |
1.1 句点W号 |
假设你在玩英文拼字游戏,惌扑և三个字母的单词,而且q些单词必须以“t”字母开_以“n”字母结束。另外,假设有一本英文字典,你可以用正则表达式搜索它的全部内宏V要构造出q个正则表达式,你可以用一个通配W——句点符号?”。这P完整的表辑ּ是“t.n”,它匹配“tan”、“ten”、“tin”和“ton”,q匹配“t#n”、“tpn”甚至“t n”,q有其他许多无意义的l合。这是因为句点符号匹配所有字W,包括I格、Tab字符甚至换行W: |
![]() |
1.2 ҎL?/B> |
Z解决句点W号匚w范围q于q泛q一问题Q你可以在方括号Q“[]”)里面指定看来有意义的字符。此Ӟ只有Ҏ号里面指定的字符才参与匹配。也是_正则表达式“t[aeio]n”只匚w“tan”、“Ten”、“tin”和“ton”。但“Toon”不匚wQ因为在Ҏ号之内你只能匚w单个字符Q? |
![]() |
1.3 “或”符?/B> |
如果除了上面匚w的所有单词之外,你还惌匚w“toon”,那么Q你可以使用“|”操作符。“|”操作符的基本意义就是“或”运。要匚w“toon”,使用“t(a|e|i|o|oo)n”正则表辑ּ。这里不能用方扩号Q因为方括号只允许匹配单个字W;q里必须使用圆括号?)”。圆括号q可以用来分l,具体请参见后面介l? |
![]() |
1.4 表示匚wơ数的符?/B> |
表一昄了表C匹配次数的W号Q这些符L来确定紧靠该W号左边的符号出现的ơ数Q? |
|
假设我们要在文本文g中搜索美国的C会安全L。这个号码的格式?99-99-9999。用来匹配它的正则表辑ּ如图一所C。在正则表达式中Q连字符Q?”)有着Ҏ的意义,它表CZ个范_比如??。因此,匚wC会安全L中的q字W号Ӟ它的前面要加上一个{义字W“\”? |
|
图一Q匹配所?23-12-1234形式的社会安全号?/P> |
假设q行搜烦的时候,你希望连字符号可以出玎ͼ也可以不出现——即Q?99-99-9999?99999999都属于正的格式。这Ӟ你可以在q字W号后面加上“?”数量限定符P如图二所C: |
|
图二Q匹配所?23-12-1234?23121234形式的社会安全号?/P> |
下面我们再来看另外一个例子。美国汽车牌照的一U格式是四个数字加上二个字母。它的正则表辑ּ前面是数字部分“[0-9]{4}”,再加上字母部分“[A-Z]{2}”。图三显CZ完整的正则表辑ּ? |
|
图三Q匹配典型的国汽R牌照LQ如8836KV |
1.5 “否”符? |
“^”符L为“否”符受如果用在方括号内,“^”表CZ惌匚w的字W。例如,囑֛的正则表辑ּ匚w所有单词,但以“X”字母开头的单词除外? |
|
囑֛Q匹配所有单词,但“X”开头的除外 |
1.6 圆括号和I白W号 |
假设要从格式为“June 26, 1951”的生日日期中提取出月䆾部分Q用来匹配该日期的正则表辑ּ可以如图五所C: |
|
图五Q匹配所有Moth DD,YYYY格式的日?/P> |
新出现的“\s”符hI白W号Q匹配所有的I白字符Q包括Tab字符。如果字W串正确匚wQ接下来如何提取出月份部分呢Q只需在月份周围加上一个圆括号创徏一个组Q然后用ORO APIQ本文后面详l讨论)提取出它的倹{修改后的正则表辑ּ如图六所C: |
|
囑օQ匹配所有Month DD,YYYY格式的日期,定义月䆾gؓW一个组 |
1.7 其它W号 |
为简便v见,你可以用一些ؓ常见正则表达式创建的快捷W号。如表二所C: |
表二Q常用符? |
|
例如Q在前面C会安全L的例子中Q所有出现“[0-9]”的地方我们都可以用“\d”。修改后的正则表辑ּ如图七所C: |
|
图七Q匹配所?23-12-1234格式的社会安全号?/P> |
二、Jakarta-ORO?/FONT> |
有许多源代码开攄正则表达式库可供JavaE序员用,而且它们中的许多支持Perl 5兼容的正则表辑ּ语法。我在这里选用的是Jakarta-ORO正则表达式库Q它是最全面的正则表辑ּAPI之一Q而且它与Perl 5正则表达式完全兼宏V另外,它也是优化得最好的API之一? |
Jakarta-ORO库以前叫做OROMatcherQDaniel Savarese大方地把它赠送给了Jakarta Project。你可以按照本文最后参考资源的说明下蝲它? |
我首先将要介l用Jakarta-ORO库时你必d建和讉K的对象,然后介绍如何使用Jakarta-ORO API? |
?PatternCompiler对象 |
首先Q创Z个Perl5Compilercȝ实例Qƈ把它赋值给PatternCompiler接口对象。Perl5Compiler是PatternCompiler接口的一个实玎ͼ允许你把正则表达式编译成用来匚w的Pattern对象? |
![]() |
?Pattern对象 |
要把正则表达式编译成Pattern对象Q调用compiler对象的compile()ҎQƈ在调用参C指定正则表达式。例如,你可以按照下面这U方式编译正则表辑ּ“t[aeio]n”: |
![]() |
默认情况下,~译器创Z个大写敏感的模式(patternQ。因此,上面代码~译得到的模式只匚w“tin”、“tan”?“ten”和“ton”,但不匚w“Tin”和“taN”。要创徏一个大写不敏感的模式Q你应该在调用编译器的时候指定一个额外的参数Q? |
![]() |
创徏好Pattern对象之后Q你可以通过PatternMatchercȝ该Pattern对象q行模式匚w? |
?PatternMatcher对象 |
PatternMatcher对象ҎPattern对象和字W串q行匚w查。你要实例化一个Perl5Matchercdƈ把结果赋值给PatternMatcher接口。Perl5MatchercLPatternMatcher接口的一个实玎ͼ它根据Perl 5正则表达式语法进行模式匹配: |
![]() |
使用PatternMatcher对象Q你可以用多个方法进行匹配操作,q些Ҏ的第一个参数都是需要根据正则表辑ּq行匚w的字W串Q? |
· boolean matches(String input, Pattern pattern)Q当输入字符串和正则表达式要_匚w时用。换句话_正则表达式必d整地描述输入字符丌Ӏ? |
· boolean matchesPrefix(String input, Pattern pattern)Q当正则表达式匹配输入字W串起始部分时用? |
· boolean contains(String input, Pattern pattern)Q当正则表达式要匚w输入字符串的一部分时用(卻I它必L一个子Ԍ? |
另外Q在上面三个Ҏ调用中,你还可以用PatternMatcherInput对象作ؓ参数替代String对象Q这Ӟ你可以从字符串中最后一ơ匹配的位置开始l进行匹配。当字符串可能有多个子串匚wl定的正则表辑ּӞ用PatternMatcherInput对象作ؓ参数很有用了。用PatternMatcherInput对象作ؓ参数替代StringӞ上述三个Ҏ的语法如下: |
· boolean matches(PatternMatcherInput input, Pattern pattern) |
· boolean matchesPrefix(PatternMatcherInput input, Pattern pattern) |
· boolean contains(PatternMatcherInput input, Pattern pattern) |
三、应用实?/FONT> |
下面我们来看看Jakarta-ORO库的一些应用实例? |
3.1 日志文g处理 |
dQ分析一个Web服务器日志文Ӟ定每一个用戯在网站上的时间。在典型的BEA WebLogic日志文g中,日志记录的格式如下: |
![]() |
分析q个日志记录Q可以发玎ͼ要从q个日志文g提取的内Ҏ两项QIP地址和页面访问时间。你可以用分l符P圆括P从日志记录提取出IP地址和时间标记? |
首先我们来看看IP地址。IP地址?个字节构成,每一个字节的值在0?55之间Q各个字节通过一个句点分隔。因此,IP地址中的每一个字节有臛_一个、最多三个数字。图八显CZ为IP地址~写的正则表辑ּQ? |
|
囑օQ匹配IP地址 |
IP地址中的句点字符必须q行转义处理Q前面加上“\”)Q因为IP地址中的句点h它本来的含义Q而不是采用正则表辑ּ语法中的Ҏ含义。句点在正则表达式中的特D含义本文前面已l介l? |
日志记录的时间部分由一Ҏ括号包围。你可以按照如下思\提取出方括号里面的所有内容:首先搜烦起始Ҏ号字W(“[”)Q提取出所有不过l束Ҏ号字W(“]”)的内容,向前L直至扑ֈl束Ҏ号字W。图九显CZq部分的正则表达式? |
|
图九Q匹配至一个字W,直至扑ֈ“]?/P> |
现在Q把上述两个正则表达式加上分l符P圆括P后合q成单个表达式,q样可以从日志记录提取出IP地址和时间。注意,Z匚w? -”(但不提取它)Q正则表辑ּ中间加入了“\s-\s-\s”。完整的正则表达式如囑֍所C? |
|
囑֍Q匹配IP地址和时间标?/P> |
现在正则表达式已l编写完毕,接下来可以编写用正则表辑ּ库的Java代码了? |
Z用Jakarta-ORO库,首先创徏正则表达式字W串和待分析的日志记录字W串Q? |
![]() |
q里使用的正则表辑ּ与图十的正则表达式差不多完全相同Q但有一点例外:在Java中,你必d每一个向前的斜杠Q“\”)q行转义处理。图十不是Java的表CŞ式,所以我们要在每个“\”前面加上一个“\”以免出现编译错误。遗憄是,转义处理q程很容易出现错误,所以应该小心}慎。你可以首先输入未经转义处理的正则表辑ּQ然后从左到右依ơ把每一个“\”替换成“\\”。如果要复检Q你可以试着把它输出到屏q上? |
初始化字W串之后Q实例化PatternCompiler对象Q用PatternCompiler~译正则表达式创Z个Pattern对象Q? |
![]() |
现在Q创建PatternMatcher对象Q调用PatternMatcher接口的contain()Ҏ查匹配情况: |
![]() |
接下来,利用PatternMatcher接口q回的MatchResult对象Q输出匹配的l。由于logEntry字符串包含匹配的内容Q你可以看到cd下面的输出: |
![]() |
3.2 HTML处理实例一 |
下面一个Q务是分析HTML面内FONT标记的所有属性。HTML面内典型的FONT标记如下所C: |
![]() |
E序按照如下Ş式,输出每一个FONT标记的属性: |
![]() |
在这U情况下Q我你用两个正则表辑ּ。第一个如囑֍一所C,它从字体标记提取出?face="Arial, Serif" size="+2" color="red"”? |
|
囑֍一Q匹配FONT标记的所有属?/P> |
W二个正则表辑ּ如图十二所C,它把各个属性分割成名字-值对? |
|
囑֍二:匚w单个属性,q把它分割成名字-值对 |
分割l果为: |
![]() |
现在我们来看看完成这个Q务的Java代码。首先创Z个正则表辑ּ字符Ԍ用Perl5Compiler把它们编译成Pattern对象。编译正则表辑ּ的时候,指定Perl5Compiler.CASE_INSENSITIVE_MASK选项Q得匹配操作不区分大小写? |
接下来,创徏一个执行匹配操作的Perl5Matcher对象? |
![]() |
假设有一个Stringcd的变量htmlQ它代表了HTML文g中的一行内宏V如果html字符串包含FONT标记Q匹配器返回true。此Ӟ你可以用匚w器对象返回的MatchResult对象获得W一个组Q它包含了FONT的所有属性: |
![]() |
接下来创Z个PatternMatcherInput对象。这个对象允怽从最后一ơ匹配的位置开始l进行匹配操作,因此Q它很适合于提取FONT标记内属性的名字-值对。创建PatternMatcherInput对象Q以参数形式传入待匹配的字符丌Ӏ然后,用匹配器实例提取出每一个FONT的属性。这通过指定PatternMatcherInput对象Q而不是字W串对象Qؓ参数Q反复地调用PatternMatcher对象的contains()Ҏ完成。PatternMatcherInput对象之中的每一ơP代将把它内部的指针向前移动,下一ơ检将从前一ơ匹配位|的后面开始? |
本例的输出结果如下: |
![]() |
3.3 HTML处理实例?/B> |
下面我们来看看另一个处理HTML的例子。这一ơ,我们假定Web服务器从widgets.acme.comUd了newserver.acme.com。现在你要修改一些页面中的链接: |
![]() |
执行q个搜烦的正则表辑ּ如图十三所C: |
|
囑֍三:匚w修改前的链接 |
如果能够匚wq个正则表达式,你可以用下面的内Ҏ换图十三的链接: |
![]() |
注意#字符的后面加上了$1。Perl正则表达式语法用$1?2{表C已l匹配且提取出来的组。图十三的表辑ּ把所有作Z个组匚w和提取出来的内容附加到链接的后面? |
现在Q返回Java。就象前面我们所做的那样Q你必须创徏试字符Ԍ创徏把正则表辑ּ~译到Pattern对象所必需的对象,以及创徏一个PatternMatcher对象Q?IMG src="file:///C:/Documents%20and%20Settings/Administrator/Local%20Settings/Temp/CyberArticle/120_files/01_7_31_4_v[1].jpg" border=0> |
接下来,用com.oroinc.text.regex包Utilcȝsubstitute()静态方法进行替换,输出l果字符Ԍ |
![]() |
Util.substitute()Ҏ的语法如下: |
![]() |
q个调用的前两个参数是以前创建的PatternMatcher和Pattern对象。第三个参数是一个Substiution对象Q它军_了替换操作如何进行。本例用的是Perl5Substitution对象Q它能够q行Perl5风格的替换。第四个参数是想要进行替换操作的字符Ԍ最后一个参数允许指定是否替换模式的所有匹配子ԌUtil.SUBSTITUTE_ALLQ,或只替换指定的次数? |
# 所有Log信息输出到标准输?System.out)和在下面指定的一个文?BR># WARN是默认的loggingU别 log4j.rootCategory = WARN, STDOUT, FILE # 应用E序的loggingU别是DEBUG log4j.logger.com.discursive = DEBUG # 配置标准输出Appender log4j.appender.STDOUT = org.apache.log4j.ConsoleAppender log4j.appender.STDOUT.layout = org.apache.log4j.PatternLayout log4j.appender.STDOUT.layout.ConversionPattern = %5p (%F:%L) %m%n # 配置输出文gAppender log4j.appender.FILE = org.apache.log4j.RollingFileAppender log4j.appender.FILE.File = output.log log4j.appender.FILE.MaxFileSize = 2000KB log4j.appender.FILE.MaxBackupIndex = 5 log4j.appender.FILE.layout = org.apache.log4j.PatternLayout log4j.appender.FILE.layout.ConversionPattern = %d %-5p %c - %m%n |
PropertyConfigurator.configure(getClass() .getResource("/resources/log4j.properties")); Logger logger = Logger.getLogger("com.discursive.SomeApp"); logger.info("This is a info message"); logger.error("This is a error message"); |
speed=23.332 names=Bob,Gautam,Jarret,Stefan correct=false |
Configuration config = new PropertiesConfiguration(getClass() .getResource("/resources/config.properties")); float speed = config.getFloat("speed"); List names = config.getList("names"); boolean correct = config.getBoolean("correct"); |
Configuration config = new XMLConfiguration("resources/config.xml"); List criterias = config.getList("start-criteria.criteria"); String criteria = config.getString("start-criteria.criteria(0)"); String type = config.getString("start-criteria.criteria(0)Q@typeQ?);//自己替换Q] int horsepower = config.getInt("horsepower"); |
<?xml version="1.0" encoding="ISO-8859-1" ?> <configuration> <properties fileName="user.properties" /> <properties fileName="local.properties" /> <properties fileName="global.properties" /> </configuration> |
threads.max=50 threads.min=2 timeout=15.52 interactive=true color=red speed=50 name=Default User |
# Overrides Global Props threads.max=30 speed=55 |
# Overrides Local Props threads.min=1 color=black speed=5000 name=Sean |
ConfigurationFactory factory = new ConfigurationFactory(); factory.setConfigurationURL(CfgTest3.class.getResource("/resources/configuration.xml")); Configuration config = factory.getConfiguration(); // print out properties System.out.println("Timeout: " + config.getFloat("timeout")); System.out.println("Max Threads: " + config.getString("threads.max")); System.out.println("Name: " + config.getString("name")); System.out.println("Speed: " + config.getInt("speed")); |
<?xml version="1.0" encoding="GB2312" ?> <!-- 一个项?可包含很多Q务组(target) --> <project default="main" basedir="."> <!-- 目中的一个Q务组,可包含很多Q?task:javac,java...) --> <target name="main"> <!--~译--> <javac srcdir="src\main\hello\ant" destdir="build\classes"/> <!--q行--> <java classname="hello.ant.HelloAnt"> <classpath> <pathelement path="build\classes"/> </classpath> </java> </target> </project> |
@echo off echo ======================================================== echo 请先讄 Environment echo . echo JAVA_HOME: %JAVA_HOME% echo ====================================================== %java_home%\bin\java -classpath ..\lib\hello-ant.jar hello.ant.HelloAnt pause |
class MD5_Test{
public final static String MD5(String s){
char hexDigits[] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
'e', 'f'};
try {
byte[] strTemp = s.getBytes();
MessageDigest mdTemp = MessageDigest.getInstance("MD5");
mdTemp.update(strTemp);
byte[] md = mdTemp.digest();
int j = md.length;
char str[] = new char[j * 2];
int k = 0;
for (int i = 0; i < j; i++) {
byte byte0 = md[i];
str[k++] = hexDigits[byte0 >>> 4 & 0xf];
str[k++] = hexDigits[byte0 & 0xf];
}
return new String(str);
}
catch (Exception e){
return null;
}
}
public static void main(String[] args){
//MD5_Test aa = new MD5_Test();
System.out.print(MD5_Test.MD5("XX"));
}
Class.forName("oracle.jdbc.driver.OracleDriver").newInstance(); String url="jdbc:oracle:thin:@localhost:1521:orcl"; //orcl为数据库的SID String user="test"; String password="test"; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("com.ibm.db2.jdbc.app.DB2Driver ").newInstance(); String url="jdbc:db2://localhost:5000/sample"; //sampleZ的数据库? String user="admin"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance(); String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=mydb"; //mydb为数据库 String user="sa"; String password=""; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("com.sybase.jdbc.SybDriver").newInstance(); String url =" jdbc:sybase:Tds:localhost:5007/myDB";//myDBZ的数据库? Properties sysProps = System.getProperties(); SysProps.put("user","userid"); SysProps.put("password","user_password"); Connection conn= DriverManager.getConnection(url, SysProps); |
Class.forName("com.informix.jdbc.IfxDriver").newInstance(); String url = "jdbc:informix-sqli://123.45.67.89:1533/myDB:INFORMIXSERVER=myserver; user=testuser;password=testpassword"; //myDB为数据库? Connection conn= DriverManager.getConnection(url); |
Class.forName("org.gjt.mm.mysql.Driver").newInstance(); String url ="jdbc:mysql://localhost/myDB?user=soft&password=soft1234&useUnicode=true&characterEncoding=8859_1" //myDB为数据库? Connection conn= DriverManager.getConnection(url); |
Class.forName("org.postgresql.Driver").newInstance(); String url ="jdbc:postgresql://localhost/myDB" //myDB为数据库? String user="myuser"; String password="mypassword"; Connection conn= DriverManager.getConnection(url,user,password); |
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver") ; String url="jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ="+application.getRealPath("/Data/ReportDemo.mdb"); Connection conn = DriverManager.getConnection(url,"",""); Statement stmtNew=conn.createStatement() ; |
try{ Class.forName(com.mysql.jdbc.Driver); System.out.println(Success loading Mysql Driver!); }catch(Exception e) { System.out.println(Error loading Mysql Driver!); e.printStackTrace(); } |
jdbcQmysqlQ?/localhost/databasename[?pa=va][Qpa=va] |
PreparedStatement pstmt3D null; try { ((OraclePreparedStatement)pstmt).setExecuteBatch(30); ... pstmt.executeUpdate(); } |