﻿<?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-limq</title><link>http://www.blogjava.net/limq/</link><description>rainman</description><language>zh-cn</language><lastBuildDate>Wed, 09 Jul 2008 09:47:41 GMT</lastBuildDate><pubDate>Wed, 09 Jul 2008 09:47:41 GMT</pubDate><ttl>60</ttl><item><title>转载- 网页弹出对话框</title><link>http://www.blogjava.net/limq/archive/2008/01/27/178009.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Sun, 27 Jan 2008 05:28:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2008/01/27/178009.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/178009.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2008/01/27/178009.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/178009.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/178009.html</trackback:ping><description><![CDATA[如何利用网页弹出各种形式的窗口，我想大家大多都是知道些的，但那种多种多样的弹出式窗口是怎么搞出来的，我们今天就来学习一下：
<p align="left">　　<strong>1.弹启一个全屏窗口</strong></p>
<p align="left">&lt;html&gt;<br />
&lt;body onload="window.open('http://www.pconline.com.cn','example01','fullscreen');"&gt;;<br />
&lt;b&gt;www.e3i5.com&lt;/b&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p align="left">　　<strong>2.弹启一个被F11化后的窗口</strong></p>
<p align="left">&lt;html&gt;<br />
&lt;body onload="window.open(''http://www.pconline.com.cn','example02','channelmode');"&gt;;<br />
&lt;b&gt;www.e3i5.com&lt;/b&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p align="left">　　<strong>3.弹启一个带有收藏链接工具栏的窗口</strong></p>
<p align="left">&lt;html&gt;<br />
&lt;body onload="window.open('http://www.pconline.com.cn','example03','width=400,height=300,directories');"&gt;<br />
&lt;b&gt;www.e3i5.com&lt;/b&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p align="left">　　<strong>4.网页对话框</strong></p>
<p align="left">&lt;html&gt;<br />
&lt;SCRIPT LANGUAGE="javascript"&gt;<br />
&lt;!--<br />
showModalDialog('http://www.pconline.com.cn','example04','dialogWidth:400px;dialogHeight:300px;<br />
dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes')<br />
//--&gt;<br />
&lt;/SCRIPT&gt;<br />
&lt;b&gt;www.e3i5.com&lt;/b&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p align="left">&lt;html&gt;<br />
&lt;SCRIPT LANGUAGE="javascript"&gt;<br />
&lt;!--<br />
showModelessDialog('http://www.pconline.com.cn','example05','dialogWidth:400px;dialogHeight:300px;<br />
dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes')<br />
//--&gt;<br />
&lt;/SCRIPT&gt;<br />
&lt;b&gt;http://www.pconline.com.cn&lt;/b&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p align="left">　　showModalDialog()或是showModelessDialog() 来调用网页对话框，至于showModalDialog()与showModelessDialog()的区别，在于showModalDialog()打开的窗口（简称模式窗口），置在父窗口上，必须关闭才能访问父窗口(建议尽量少用，以免招人反感)；showModelessDialog()（简称无模式窗口），打开后不必关闭也可访问父窗口打开的窗口。 </p>
<p align="left">dialogHeight: iHeight 设置对话框窗口的高度。 <br />
dialogWidth: iWidth 设置对话框窗口的宽度。 　　<br />
dialogLeft: iXPos 设置对话框窗口相对于桌面左上角的left位置。 <br />
dialogTop: iYPos 设置对话框窗口相对于桌面左上角的top位置。 <br />
center: {yes | no | 1 | 0 } 指定是否将对话框在桌面上居中，默认值是&#8220;yes&#8221;。<br />
help: {yes | no | 1 | 0 } 指定对话框窗口中是否显示上下文敏感的帮助图标。默认值是&#8220;yes&#8221;。 　　<br />
resizable: {yes | no | 1 | 0 } 指定是否对话框窗口大小可变。默认值是&#8220;no&#8221;。 <br />
status: {yes | no | 1 | 0 } 指定对话框窗口是否显示状态栏。对于非模式对话框窗口，默认值是&#8220;yes&#8221;；对于模式对话框窗口，默认值是 &#8220;no&#8221;。</p>
<img src ="http://www.blogjava.net/limq/aggbug/178009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2008-01-27 13:28 <a href="http://www.blogjava.net/limq/archive/2008/01/27/178009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j使用进阶</title><link>http://www.blogjava.net/limq/archive/2006/04/10/40341.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Mon, 10 Apr 2006 15:11:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2006/04/10/40341.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/40341.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2006/04/10/40341.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/40341.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/40341.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" align="right" border="0">
				<tbody>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" align="left" border="0">
												<tbody>
														<tr>
																<td>
																		<!-- 这儿显示Google的广告 -->
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>二　动态配置log4j<br />1 配置外部配置文件来配置的基本步骤<br />1.1　一个运用配置文件的实例<br />Log4j之所以能成功的原因之一是它的灵活性。但如果只是简单的调用BasicConfigurator.configure()来进行配置工作，那么所有的配置都是在函数中写死的，以后修改配置就要修改原代码，这就不能体现出log4j的灵活性了，所以基本上不会通过BasicConfigurator.configure()来进行配置工作的。<br />为了增加软件的灵活性，最常用的做法就是使用配置文件，如web.xml之于J2EE，struts-config.xml之于struts一样，log4j也提供了让我们把配置信息从程序转移到配置文件中的方法。Log4j提供了两种方式的配置文件：XML文件和Java的property配置文件。通过把配置信息转移到外部文件中，当我们要修改配置信息时，就可以直接修改配置文件而不用去修改代码了，下面，我们就来完成一个通过配置文件来实现log4j的实例。<br />例2-a：<br />package TestLog4j;<br />import org.apache.log4j.Logger;<br />import org.apache.log4j.BasicConfigurator;<br />import org.apache.log4j.PropertyConfigurator;<br />import org.apache.log4j.Priority; public class TestLog4j <br />{<br />static Logger logger = Logger.getLogger(TestLog4j.class.getName());<br />public TestLog4j(){}<br /><br />public static void main(String[] args)<br />{<br />//通过BasicConfigurator类来初始化<br />//BasicConfigurator.configure();<br />//（1）通过配置文件来初始化<br />PropertyConfigurator.configure("F:\\nepalon\\log4j.properties");<br /><br />logger.debug("Start of the main() in TestLog4j");　//代码（2）<br />logger.info("Just testing a log message with priority set to INFO");<br />logger.warn("Just testing a log message with priority set to WARN");<br />logger.error("Just testing a log message with priority set to ERROR");<br />logger.fatal("Just testing a log message with priority set to FATAL");<br />logger.log(Priority.WARN, "Testing a log message use a alternate form");<br />logger.debug(TestLog4j.class.getName());　//代码（2）<br />}<br />}<br />在这个例子中，我们用PropertyConfigurator.configure("F:\\nepalon\\log4j.properties")代替BasicConfigurator.configure()进行配置。PropertyConfigurator.configure()函数的参数可以是一个properties文件所在路径的String对象，可以是一个properties文件所在路径的URL对象，也可以是一个properties对象。通过PropertyConfigurator.configure()可以通过指定的properties文件来配置信息。如果要用XML文件进行信息配置，可以在代码中调用DOMConfigurator()函数来进行配置工作。在这里，我们只以properties文件来完成例子。接着，我们来看一下log4j.properties文件中都有些什么东西：<br />例2-b：<br />log4j.rootLogger = DEBUG, A1<br />log4j.appender.A1 = org.apache.log4j.ConsoleAppender<br />log4j.appender.A1.layout = org.apache.log4j.PatternLayout<br />log4j.appender.A1.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n<br />运行这个实例，运行结果为<br />0 [main] DEBUG TestLog4j.TestLog4j - Start of the main() in TestLog4j<br />20 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO<br />20 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN<br />20 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR<br />20 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL<br />180 [main] WARN TestLog4j.TestLog4j - Testing a log message use a alternate form<br />180 [main] DEBUG TestLog4j.TestLog4j - TestLog4j.TestLog4j<br />下面，我们分析一下这个配置文件。<br />1) 由于每一个Logger对旬都有一个级别，文件的第一行就是定义了一个Logger及其级别。在这里定义了一个根记录器（root logger），这涉及到记录器的层次问题，在些暂时不深入讨论，在后面的章节再进行讨论。<br />2) 第二行定义了一个名为A1的输出流，这个流就是控制台，所以通过Logger对象打印的信息会在控制台输出。<br />3) 第三行定义了打印信息的布局。在这里我们用PatternLayout作为此记录器的布局，PatternLayout允许你以灵活的格式来打印信息。<br />4) 第四行指定的打印信息的具体格式，从结果可知，这个实例的打印格式为：当前打印语句所使用的时间 [日志所在的线程] 打印的级别 当前日志所在的类的全名 日志信息。<br />现在我们来修改一下这个记录器的级别，把第一行的DEBUG改为INFO，再运行程序，结果将变为：<br />0 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO<br />10 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN<br />10 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR<br />10 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL<br />10 [main] WARN TestLog4j.TestLog4j - Testing a log message use a alternate form<br />由于这个Logger的级别变为INFO，而代码（2）是调用debug()函数来输出日志信息时只能当记录器级别为DEBUG时才输出信息，所以代码（2）将不输出信息。<br />1.2　实例原理<br />1.2.1　初始化配置信息<br />如果要通过JAVA的properties文件来配置信息，那么在代码中就要通过PropertyConfigurator.configure()函数从properties文件中加载配置信息，这个函数有三种参数形式：一个properties文件所在路径的String对象，可以是一个properties文件所在路径的URL对象，也可以是一个properties对象。如果要用XML文件来配置信息，则可用类型的<br />DOMConfigurator()函数来从一个XML文件中加载配置信息。<br />1.2.2　输出端Appender<br />在上面的例子中，我们都是简单的把日志信息输出到控制台中。其实在log4j中还可以把日志信息输出到其它的输出端，对于同一个日志信息，我们还可以让它同时输出到多个输出端中，如同时在控制台和文件中进行打印。一个输出端就是一个appender。要在配置文件中定义一个appender有三步：<br />1) 在定义一个记录器的同时定义出该记录器的输出端appender。在例2的配置文件的第一句log4j.rootLogger = DEBUG, A1中，我们定义了一个根记录器，它的级别为DEBUG，它有一个appender名为A1。定义根记录器的格式为log4j.rootLogger = [ level ], appendName1, appendName2, ...appendNameN。同一个记录器可有多个输出端。<br />2) 定义appender的输出目的地。定义一个appender的输出目的地的格式为log4j.appender.appenderName = fully.qualified.name.of.appender.class。log4j提供了以下几种常用的输出目的地：<br />? org.apache.log4j.ConsoleAppender，将日志信息输出到控制台<br />? org.apache.log4j.FileAppender，将日志信息输出到一个文件<br />? org.apache.log4j.DailyRollingFileAppender，将日志信息输出到一个，并且每天输出到一个新的日志文件<br />? org.apache.log4j.RollingFileAppender，将日志信息输出到一个文件，通过指定文件的的尺寸，当文件大小到达指定尺寸的时候会自动把文件改名，如名为example.log的文件会改名为example.log.1，同时产生一个新的example.log文件。如果新的文件再次达到指定尺寸，又会自动把文件改名为example.log.2，同时产生一个example.log文件。依此类推，直到example.log. MaxBackupIndex，MaxBackupIndex的值可在配置文件中定义。<br />? org.apache.log4j.WriterAppender，将日志信息以流格式发送到任意指定的地方。<br />? org.apache.log4j.jdbc.JDBCAppender，通过JDBC把日志信息输出到数据库中。<br />在例2中，log4j.appender.A1 = org.apache.log4j.ConsoleAppender定义了名为A1的appender的输出目的地为控制台，所以日志信息将输出到控制台。<br />3) 定义与所选的输出目的地相关的参数，定义格式为：<br />log4j.appender.appenderName.optionName1 = value1<br />......<br />log4j.appender.appenderName.optionNameN = valueN<br />其中一个最常用的参数layout将在下面介绍。<br />1.2.3　输出格式（布局）layout<br />通过appender可以控制输出的目的地，而如果要控制输出的格式，就可通过log4j的layout组件来实现。通过配置文件定义一个appender的输出格式，也通常需要两个步骤：<br />1) 定义appender的布局模式。定义一个appender的布局模式的格式为log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class。Log4j提供的布局模式有以下几种：<br />? org.apache.log4j.HTMLLayout，以HTML表格形式布局<br />? org.apache.log4j.PatternLayout，可以灵活地指定布局模式<br />? org.apache.log4j.SimpleLayout，包含日志信息的级别和信息字符串<br />在例2　中log4j.appender.A1.layout = org.apache.log4j.PatternLayout定义了名为A1的appender的布局模式为PatternLayout。<br />2) 定义与所选的布局模式相关的设置信息，定义格式为：<br />log4j.appender.appenderName.layout.optionName1 = value1<br />......<br />log4j.appender.appenderName.layout.optionNameN = valueN<br />选择了不同的布局模式可能会有不同的设置信息。实例2所选的布局模式PatternLayout的一个PatternLayout为ConversionPattern ，通过定义这个PatternLayout的值，我们可以指定输出信息的输出格式。在例2的配置文件中的定义如下log4j.appender.A1.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n。在下面，我们将介绍布局模式PatternLayout的参数ConversionPattern的各个值代表的含义。<br />1.2.4　ConversionPattern参数的格式含义<br />格式名 含义<br />%c 输出日志信息所属的类的全名<br />%d 输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy-MM-dd HH:mm:ss }，输出类似：2002-10-18- 22：10：28<br />%f 输出日志信息所属的类的类名<br />%l 输出日志事件的发生位置，即输出日志信息的语句处于它所在的类的第几行<br />%m 输出代码中指定的信息，如log(message)中的message<br />%n 输出一个回车换行符，Windows平台为"\r\n"，Unix平台为"\n"<br />%p 输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL。如果是调用debug()输出的，则为DEBUG，依此类推<br />%r 输出自应用启动到输出该日志信息所耗费的毫秒数<br />%t 输出产生该日志事件的线程名<br />1.3　定义多个输出目的地的实例<br />从上面的实例原理中我们已经知道，同一个日志信息可以同时输出到多个输出目的地，在这个例子中，我们将实现一个把日志信息同时输出到控制器、一个文件中的实例和数据库中。这个实例的Java代码我们沿用例2中的代码，我们只需修改配置文件即可。这也体现了log4j的灵活性。<br />例3-a：<br />create table log4j(<br />logID int primary key identity,<br />message varchar(1024),<br />priority varchar(10),<br />milliseconds int,<br />category varchar(256),<br />thread varchar(100),<br />NDC varchar(256),<br />createDate datetime,<br />location varchar(256),<br />caller varchar(100),<br />method varchar(100),<br />filename varchar(100),<br />line int<br />)<br />例3-b：<br />#1 定义了两个输出端<br />log4j.rootLogger = INFO, A1, A2,A3<br /><br />#2 定义A1输出到控制器<br />log4j.appender.A1 = org.apache.log4j.ConsoleAppender<br />#3 定义A1的布局模式为PatternLayout<br />log4j.appender.A1.layout = org.apache.log4j.PatternLayout<br />#4 定义A1的输出格式<br />log4j.appender.A1.layout.ConversionPattern = %-4r [%t] %-5p %c - %m%n<br /><br />#5 定义A2输出到文件<br />log4j.appender.A2 = org.apache.log4j.RollingFileAppender<br />#6 定义A2要输出到哪一个文件<br />log4j.appender.A2.File = F:\\nepalon\\classes\\example3.log<br />#7 定义A2的输出文件的最大长度<br />log4j.appender.A2.MaxFileSize = 1KB<br />#8 定义A2的备份文件数<br />log4j.appender.A2.MaxBackupIndex = 3<br />#9 定义A2的布局模式为PatternLayout<br />log4j.appender.A2.layout = org.apache.log4j.PatternLayout<br />#10 定义A2的输出格式<br />log4j.appender.A2.layout.ConversionPattern = %d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n<br /><br />#11区 定义A3输出到数据库<br />log4j.appender.A3 = org.apache.log4j.jdbc.JDBCAppender<br />log4j.appender.A3.BufferSize = 40<br />log4j.appender.A3.Driver = com.microsoft.jdbc.sqlserver.SQLServerDriver<br />log4j.appender.A3.URL = jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=nepalon<br />log4j.appender.A3.User = sa<br />log4j.appender.A3.Password = <br />log4j.appender.A3.layout = org.apache.log4j.PatternLayout<br />log4j.appender.A3.layout.ConversionPattern = INSERT INTO log4j (createDate, thread, priority, category, message) values(getdate(), '%t', '%-5p', '%c', '%m')<br />配置文件中的6、7、8行显示了输出端为RollingFileAppender的特有参数及其运用的方法。11区显示了输出端为JDBCAppender的特有参数及其运用方法。在这着重讲解一下6、7、8行的作用。6行指定日志信息输出到哪个文件，7行指定日志文件的最大长度，最后要详细介绍8行。第8行的参数是设置备份文件的个数的参数，在这里我们设置为3，表示最多有3个备份文件，具体作用为：<br />1) 当example3.log文件的大小超过K时，就把文件改名为example3.log.1，同时生成一个新的example3.log文件<br />2) 当example3.log文件的大小再次超过1K，又把文件改名为example3.log.1。但由于此时example3.log.1已存在，则先把example3.log.1更名为example3.log.2，再把example3.log文件改名为example3.log.1<br />3) 同理，当example3.log文件的大小再次超过1K，先把example3.log.2文件更名为example3.log.3，把example3.log.1文件更名为example3.log.2，再把example3.log文件改名为example3.log.1<br />4) 当example3.log文件的大小再次超过1K，先把example3.log.2文件更名为example3.log.3，旧的example3.log.3文件将被覆盖；把example3.log.1文件更名为example3.log.2，旧的example3.log.2文件被覆盖；最后把example3.log文件改名为example3.log.1并覆盖掉旧的example3.log.1文件。<br />运行结果将分为两部分<br />在控制器中：<br />0 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO<br />11 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN<br />21 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR 21 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL<br />21 [main] WARN TestLog4j.TestLog4j - Testing a log message use a alternate form<br />在文件example3.log中：<br />2003-12-18 04:23:02:INFO main TestLog4j.TestLog4j - Just testing a log message with priority set to INFO<br />2003-12-18 04:23:02:WARN main TestLog4j.TestLog4j - Just testing a log message with priority set to WARN<br />2003-12-18 04:23:02:ERROR main TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR<br />2003-12-18 04:23:02:FATAL main TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL<br />2003-12-18 04:23:02:WARN main TestLog4j.TestLog4j - Testing a log message use a alternate form<br />1.4　配置log4j的总结<br />这个教程到这里，关于配置log4j的配置文件的基本原理已经讲完了，而且通过例3我们已经可以完成基本的日志工作了。现在，我们就做一个总结。配置一个配置文件的基本步骤如下：<br />1) 定义一个Logger。在定义Logger时指定该Logger的级别级其输出目的地。定义Logger的格式为<br />log4j.rootLogger = [ level ], appendName1, appendName2, ...appendNameN。<br />2) 定义appender的输出目的地。定义一个appender的输出目的地的格式为<br />log4j.appender.appenderName = fully.qualified.name.of.appender.class。<br />log4j提供的输出端有ConsoleAppender、FileAppender 、DailyRollingFileAppender、RollingFileAppender和WriterAppender。<br />3) 定义appender的除布局模式外的其它相关参数，如例3中第6、7、8定义了A2的相关参数。定义格式为<br />log4j.appender.appenderName.optionName1 = value1<br />......<br />log4j.appender.appenderName.optionNameN = valueN<br />如果除了布局模式外不需要定义别的参数，可跳过这一步（如例3中的A1）。<br />4) 定义appender的布局模式。定义一个appender的布局模式的格式为<br />log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class。<br />布局模式其实也是步骤3）中的一个部分，只是布局模式参数是每一个appender必须定义的参数。Log4j提供的布局模式有HTMLLayout、PatternLayout和SimpleLayout。<br />5) 定义与所选的布局模式相关的设置信息，定义格式为<br />og4j.appender.appenderName.layout.optionName1 = value1<br />......<br />log4j.appender.appenderName.layout.optionNameN = valueN<br />2　记录器的层次Logger hierarchy<br />2.1　何为记录器的层次hierarchy<br />首先，我们先看一下何为层次，以我们最熟悉的继承为例，下面是一张类图<br /><br />在这个继承体系中，类B是类C的父类，类A是类C的祖先类，类D是类C的子类。这些类之间就构成一种层次关系。在这些具有层次关系的类中，子类都可继承它的父类的特征，如类B的对象能调用类A中的非private实例变量和函数；而类C由于继承自类B，所以类B的对象可以同时调用类A和类B中的非private实例变量和函数。<br />在log4j中，处于不同层次中的Logger也具有象类这样的继承关系。<br />2.2　记录器的层次<br />如果一个应用中包含了上千个类，那么也几乎需要上千个Logger实例。如何对这上千个Logger实例进行方便地配置，就是一个很重要的问题。Log4J采用了一种树状的继承层次巧妙地解决了这个问题。在Log4J中Logger是具有层次关系的。它有一个共同的根，位于最上层，其它Logger遵循类似包的层次。下面我们将进行介绍。<br />2.2.1　根记录器root logger<br />就象一个Java中的Object类一样，log4j中的logger层次中有一个称之为根记录器的记录器，其它所有的记录器都继承自这个根记录器。根记录器有两个特征：<br />1) 根记录器总是存在。就像Java中的Object类一样，因为用log4j输出日志信息是通过记录器来实现的，所以只要你应用了log4j，根记录器就肯定存在的。<br />2) 根记录器没有名称，所以不能通过名称来取得根记录器。但在Logger类中提供了getRootLogger()的方法来取得根记录器。<br />2.2.2　记录器的层次<br />Logger遵循类似包的层次。如<br />static Logger rootLog = Logger.getRootLogger();<br />static Logger log1 = Logger.getLogger("test4j");<br />static Logger log2 = Logger.getLogger("test4j.test4j2");<br />static Logger log3 = Logger.getLogger("test4j.test4j2.test4j2");<br />那么rootLog是log2的祖先子记录器，log1是log2的父子记录器，log3是log2的子记录器。记录器象Java中的类继承一样，子记录器可以继承父记录器的设置信息，也可以可以覆写相应的信息。<br />首先先看一下记录器层次中的继承有什么用处。假设程序中的每个包都具有一些基本的日志信息，而包中的不同包可能会有些额外的日志信息要输出，这种情况就可以象处理Java中的类一样，运用Logger中的层次关系来达到目的。假设有个名为A的包，我包下的所有类都要把日志信息输出到控制台中；A.B包除了输出到控制台外还要输出到文件中；A.C包除了输出到控制台中还要输出到HTML文档中。这样我们就可以通过定义一个父记录器A，它负责把日志信息输出到控制台中；定义一个A的子记录器A.B，它负责把日志信息输出到文件中；定义一个A的子记录器A.C，它负责把日志信息输出到HTML文档中。<br />记录器遵循的是类似包的层次，这样做为我们带来了大大的方便。Logger类中的getLogger()方法可以取得Logger对象，这个方法有三种参数形式String、Class和URL，其实不论是用哪一种，最终都是通过记录器的名字来取得记录器对象的。如果要取得一个名为A.B的记录器对象，我们可以Logger.getLogger("A.B")。但从上面的例子中，我们都是通过Logger.getLogger(TestLog4j.class.getName())这种方法来取得记录器对象。这是为什么呢？现在我们假设A.B的包下有一个类BClass，那么我们调用BClass.class.getName()得到的是这个类的全名A.B.BClass。所以当调用Logger.getLogger(BClass.class.getName())时，最理想的情况是返回名为A.B.BClass的记录器对象。但是如果不存在名为A.B.BClass的记录器时它会怎样呢？其实通过Logger类的getLogger方法取得记录器时存在下面两种情况：<br />1) 如果存在与所要找的名字完全相同的记录器，则返回相应的记录器对象。<br />当调用Logger.getLogger(BClass.class.getName())时，如果定义了名为A.B.BClass的记录器，它就返回该记录器的对象。<br />2) 但如果找不到，它会尝试返回在记录器层次中与所要找的记录器最接近的记录器对象。<br />当调用Logger.getLogger(BClass.class.getName())时，如果没有定义了名为A.B.BClass的记录器，那会尝试返回名为A.B的记录器的对象；如果又没有定义名为A.B的记录器，它会尝试返回名为A的记录器的对象；如果也没定义名为A的记录器，它就会返回根记录器的对象，而根记录器是必须存在的，所以你总能得到一个记录器对象。<br />好了，现在我们回到前面的问题，我们为什么总要通过Logger.getLogger(BClass.class.getName())这种以类全名作为参数来取得记录器对象呢？其实这是为了管理方便。因为我们在定义设计Logger时也遵循类似包的规则，使设计器的名称与程序中的类包对应。如上面的假设中我们的程序中有A包，A包下有B包和C包，B包下又有类BClass，那么我们就可使设计器的名为A、A.B、A.C、A.B.BClass，以此类推。那么当我们通过类命名来取得设计器对象时，总能取到与所要的设计器最接近的设计器对象。<br />2.3　如何应用记录器的层次<br />2.3.1　如果定义及获取不同层次的记录器<br />任何一个记录器的使用都有两个步骤：<br />1) 在配置文件中定义相应的记录器。<br />在配置文件中定义记录器的格式有两种<br />? 定义根记录器的格式为<br />log4j.rootLogger = [ level ], appendName1, appendName2, ...appendNameN<br />? 定义一个非根记录器的格式为<br />log4j.logger.loggerName1 = [ level ], appendName1,...appendNameN<br />......<br />log4j.logger.loggerNameM = [ level ], appendName1, ...appendNameN<br />我们可以定义任意个非根记录器。<br />2) 在代码中调用Logger类的取得记录器方法取得相应的记录器对象。<br />要取得根记录器对象可通过Logger.getRootLogger()函数，要取得非根记录器可通过Logger.getLogger()函数。<br />理论知道就讲到这里，纸上得来终觉浅，下面，我们来小小演练一下。<br />例4-a：<br />package TestLog4j;<br />import org.apache.log4j.Logger;<br />import org.apache.log4j.PropertyConfigurator;<br />import org.apache.log4j.Priority;<br />import TestLog4j.TestLog4j2.TestLog4j2;<br /><br />public class TestLog4j <br />{<br />static Logger logger = Logger.getLogger(TestLog4j.class.getName());　//（2）<br />public TestLog4j(){}<br /><br />public static void main(String[] args)<br />{<br />//同时输出到控制台和一个文件的实例并实现了Logger的继承<br />PropertyConfigurator.configure("F:\\nepalon\\log4j2.properties");<br /><br />logger.debug("Start of the main() in TestLog4j");<br />logger.info("Just testing a log message with priority set to INFO");<br />logger.warn("Just testing a log message with priority set to WARN");<br />logger.error("Just testing a log message with priority set to ERROR");<br />logger.fatal("Just testing a log message with priority set to FATAL");<br />logger.log(Priority.WARN, "Testing a log message use a alternate form");<br />logger.debug(TestLog4j.class.getName());<br />TestLog4j2 testLog4j2 = new TestLog4j2();　//（1）<br />testLog4j2.testLog();<br />}<br />}<br />在类TestLog4j中我们调用了另一个类TestLog4j2，下面看一下类TestLog4j2的代码。<br />例4-b：<br />package TestLog4j.TestLog4j2;<br />import org.apache.log4j.Logger;<br />import org.apache.log4j.PropertyConfigurator;<br />import org.apache.log4j.Priority;<br /><br />public class TestLog4j2 <br />{<br />static Logger logger = Logger.getLogger(TestLog4j2.class.getName());　//（1）<br />public TestLog4j2(){}<br /><br />public void testLog()<br />{<br />//同时输出到控制台和一个文件的实例<br />PropertyConfigurator.configure("F:\\nepalon\\log4j2.properties");<br />logger.debug("2Start of the main()");<br />logger.info("2Just testing a log message with priority set to INFO");<br />logger.warn("2Just testing a log message with priority set to WARN");<br />logger.error("2Just testing a log message with priority set to ERROR");<br />logger.fatal("2Just testing a log message with priority set to FATAL");<br />logger.log(Priority.DEBUG, "Testing a log message use a alternate form");<br />logger.debug("2End of the main()");<br />}<br />}<br />最后我们来看一下配置文件。<br />例4-c：<br />log4j2.properties文件内容<br />＃1区<br />#### Use two appenders, one to log to console, another to log to a file<br />log4j.rootLogger = debug, stdout<br /><br />#2区<br />#Print only messages of priority WARN or higher for your category<br />log4j.logger.TestLog4j= , R<br />log4j.logger.TestLog4j.TestLog4j2=WARN<br /><br />#3区<br />#### First appender writes to console<br />log4j.appender.stdout=org.apache.log4j.ConsoleAppender<br />log4j.appender.stdout.layout=org.apache.log4j.PatternLayout<br /><br /># Pattern to output the caller's file name and line number.<br />log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n<br /><br />#4区<br />#### Second appender writes to a file<br />log4j.appender.R=org.apache.log4j.RollingFileAppender<br />log4j.appender.R.File=F:\\nepalon\\classes\\TestLog4j\\example.log<br /><br /># Control the maximum log file size<br />log4j.appender.R.MaxFileSize=100KB<br /># Archive log files (one backup file here)<br />log4j.appender.R.MaxBackupIndex=1<br /><br />log4j.appender.R.layout=org.apache.log4j.PatternLayout<br />log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n<br />先看一下运行结果。<br />在控制台中的结果为：<br />DEBUG [main] (?:?) - Start of the main() in TestLog4j<br />INFO [main] (?:?) - Just testing a log message with priority set to INFO<br />WARN [main] (?:?) - Just testing a log message with priority set to WARN<br />ERROR [main] (?:?) - Just testing a log message with priority set to ERROR<br />FATAL [main] (?:?) - Just testing a log message with priority set to FATAL<br />WARN [main] (?:?) - Testing a log message use a alternate form<br />DEBUG [main] (?:?) - TestLog4j.TestLog4j<br />WARN [main] (?:?) - 2Just testing a log message with priority set to WARN<br />ERROR [main] (?:?) - 2Just testing a log message with priority set to ERROR<br />FATAL [main] (?:?) - 2Just testing a log message with priority set to FATAL<br />输出文件的结果为：<br />2003-12-19 04:19:44:DEBUG main TestLog4j.TestLog4j - Start of the main() in TestLog4j<br />2003-12-19 04:19:44:INFO main TestLog4j.TestLog4j - Just testing a log message with priority set to INFO<br />2003-12-19 04:19:44:WARN main TestLog4j.TestLog4j - Just testing a log message with priority set to WARN<br />2003-12-19 04:19:44:ERROR main TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR<br />2003-12-19 04:19:44:FATAL main TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL<br />2003-12-19 04:19:44:WARN main TestLog4j.TestLog4j - Testing a log message use a alternate form<br />2003-12-19 04:19:44:DEBUG main TestLog4j.TestLog4j - TestLog4j.TestLog4j<br />2003-12-19 04:19:44:WARN main TestLog4j.TestLog4j2.TestLog4j2 - 2Just testing a log message with priority set to WARN<br />2003-12-19 04:19:44:ERROR main TestLog4j.TestLog4j2.TestLog4j2 - 2Just testing a log message with priority set to ERROR<br />2003-12-19 04:19:44:FATAL main TestLog4j.TestLog4j2.TestLog4j2 - 2Just testing a log message with priority set to FATAL<br /><br />首先，先来看一下配置文件都有些什么东西。<br />1) 在1区中定义了一个根记录器。这个根记录器具有DEBUG级别并有一个名称为stdout的输出端appender。<br />2) 2区中的内容是这一节的重点，也是应用到记录器层次的地方，但其实也只有两句，充分体现了log4j的简单性。在这里，我们定义了两个名称分别为TestLog4j和TestLog4j.TestLog4j2设计器。<br />? 在定义TestLog4j记录器时没有指定级别，所以它的级别继承自它的父记录器，即要记录器，所以它的级别也为DEBUG。在定义TestLog4j记录器时又定义了一个名称为R的输出端，所以它的输出端有两个，一个从根记录器继承而来的名为stdout的输出端，另一个为在此定义的名为R的输出端。在此需要注意的是，在定义记录器时必须先定义记录器的级别，然后才是记录器的输出端。如果只想定义输出端而不定义级别，则虽然级别可以为空，但逗号分隔符不能省略。如定义TestLog4j记录器的做法。<br />? 在定义TestLog4j.TestLog4j2记录器时又指定了它的级别，由于一个记录器的级别只能有一个，所以新指定的级别将覆写掉它的父记录器的级别（这就象Java中的多态）。我们没有定义TestLog4j.TestLog4j2记录器的输出端，所以它的输出端将从它的父记录器中继承而来。它的父记录器为estLog4j记录器，所以它和estLog4j记录器一样具有两个名称分别为stdout和R的输出端。<br />3) 剩下的3区和4区分别设置了两个输出端的参数值。<br />接下来，回到我们的代码，看一下是如何取得记录器，在取记录器时又发生了什么。<br />1) 例4-a中的代码（2）中，语句Logger.getLogger()中的参数TestLog4j.class.getName()的值为TestLog4j. TestLog4j，所以此语句的结果是取得一个名为TestLog4j. TestLog4j的记录器的对象。但在配置文件中并没有定义这样的记录器，所以最终将返回与所需的名称TestLog4j. TestLog4j最接近的记录器对象，即名为TestLog4j的记录器的对象。<br />2) 例4-b中的代码（1）的原理与例4-a中的代码（2）相似，期望取得的是名为TestLog4j.TestLog4j2. TestLog4j2的记录器对象，但最终返回的是TestLog4j.TestLog4j2记录器的对象。<br />三　log4j与J2EE的结合<br />到目前为止，这篇文章讲的都是如何在application中应用log4j，而Java现在的应用主流是J2EE和J2ME。现在，我们来看一下要如何在J2EE开发中应用log4j。其实在Web application中应用log4j也很简单，与在application中应用log4j不同之处就是要在所有应用log4j的代码之前对log4j进行初始化。所以，我们在web application中就要把log4j的初始化工作独立出来，把它放在Servlet中。下面，我们看一个例子。<br />例5-a：<br />进行初始化的Servlet：<br />import org.apache.log4j.PropertyConfigurator;<br />import javax.servlet.http.HttpServlet;<br />import javax.servlet.http.HttpServletRequest;<br />import javax.servlet.http.HttpServletResponse;<br /><br />/**<br />* log4j.jar的初始化类，参考web.xml<br />*/<br />public class Log4jInit extends HttpServlet <br />{<br />public void init() <br />{<br />//通过web.xml来动态取得配置文件<br />String prefix = getServletContext().getRealPath("/");<br />String file = getInitParameter("log4j-init-file");<br /><br />// 如果没有给出相应的配置文件，则不进行初始化<br />if(file != null) <br />{<br />PropertyConfigurator.configure(prefix+file);　//（1）<br />}<br />}<br /><br />public void doGet(HttpServletRequest req, HttpServletResponse res) <br />{} <br />}<br />下面来看一下这个Servlet在web.xml中的定义。<br />例5-b：<br />&lt;servlet&gt;<br />&lt;servlet-name&gt;log4j-init&lt;/servlet-name&gt;<br />&lt;servlet-class&gt;TestLog4j.Log4jInit&lt;/servlet-class&gt;<br />&lt;init-param&gt;<br />&lt;param-name&gt;log4j-init-file&lt;/param-name&gt;<br />&lt;param-value&gt;sort.properties&lt;/param-value&gt;<br />&lt;/init-param&gt;<br />&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;<br />&lt;/servlet&gt;<br />因为log4j的初始化要在所有的log4j调用之前完成，所以在web.xml文件中，我们一定要把对应的Servlet定义的load-on-startup应设为1，以便在Web容器启动时即装入该Servlet。<br />完成了这两个步骤这后，我们就可以象在application开发中一样在web application任何地方应用log4j了。下面是在javabean中的应用的一个例子。<br />例5-c：<br />import org.apache.log4j.Logger;<br /><br />public class InfoForm <br />{<br />static Logger logger = Logger.getLogger(InfoForm.class);<br /><br />protected String title;<br />protected String content;<br /><br />public InfoForm() {}<br /><br />public void setTitle(Object value) <br />{<br />logger.debug("nepalon:title = " + title);<br />title = value;<br />}<br /><br />public String getTitle() <br />{<br />logger.debug("nepalon:title = " + title);<br />return title;<br />}<br /><br />public void setContent(String value) <br />{<br />content = value;<br />logger.debug("nepalon: content() = " + content);<br />}<br /><br />public String getContent() <br />{<br />logger.debug("nepalon: content = \n" + content);<br />return content;<br />}<br />} <img src ="http://www.blogjava.net/limq/aggbug/40341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2006-04-10 23:11 <a href="http://www.blogjava.net/limq/archive/2006/04/10/40341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【Eclipse资料】]常用的Eclipse 3.0插件（转）</title><link>http://www.blogjava.net/limq/archive/2006/04/10/40329.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Mon, 10 Apr 2006 13:43:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2006/04/10/40329.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/40329.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2006/04/10/40329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/40329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/40329.html</trackback:ping><description><![CDATA[1.MyEclipse  J2EE开发插件，支持SERVLET/JSP/EJB/数据库操纵等<br /><a href="http://www.myeclipseide.com/"><font color="#4a664d"><u>www.myeclipseide.com</u></font></a><div><font color="#4a664d"></font> </div><div>2.Properties Editor  编辑java的属性文件，并可以自动存盘为Unicode格式<br /><a href="http://propedit.sourceforge.jp/index_en.html"><font color="#4a664d"><u>http://propedit.sourceforge.jp/index_en.html</u></font></a></div><div><font color="#4a664d"></font> </div><div>3.Colorer Take  为上百种类型的文件按语法着色<br /><a href="http://colorer.sourceforge.net/"><font color="#4a664d"><u>http://colorer.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>4.XMLBuddy 编辑xml文件<br /><a href="http://www.xmlbuddy.com/"><font color="#4a664d"><u>www.xmlbuddy.com</u></font></a></div><div><font color="#4a664d"></font> </div><div>5.Code Folding  加入多种代码折叠功能（比eclipse自带的更多）<br /><a href="http://www.coffee-bytes.com/servlet/PlatformSupport"><font color="#4a664d"><u>http://www.coffee-bytes.com/servlet/PlatformSupport</u></font></a></div><div><font color="#4a664d"></font> </div><div>6.Easy Explorer  从eclipse中访问选定文件、目录所在的文件夹<br /><a href="http://easystruts.sourceforge.net/"><font color="#4a664d"><u>http://easystruts.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>7.Fat Jar 打包插件，可以方便的完成各种打包任务，可以包含外部的包等<br /><a href="http://fjep.sourceforge.net/"><font color="#4a664d"><u>http://fjep.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>8.RegEx Test 测试正则表达式<br /><a href="http://brosinski.com/stephan/archives/000028.php"><font color="#4a664d"><u>http://brosinski.com/stephan/archives/000028.php</u></font></a></div><div><font color="#4a664d"></font> </div><div>9.JasperAssistant 报表插件（强，要钱的）<br /><a href="http://www.jasperassistant.com/"><font color="#4a664d"><u>http://www.jasperassistant.com/</u></font></a></div><div><font color="#4a664d"></font> </div><div>10.Jigloo GUI Builder ＪＡＶＡ的ＧＵＩ编辑插件<br /><a href="http://cloudgarden.com/jigloo/"><font color="#4a664d"><u>http://cloudgarden.com/jigloo/</u></font></a></div><div><font color="#4a664d"></font> </div><div>11.Profiler 性能跟踪、测量工具，能跟踪、测量ＢＳ程序<br /><a href="http://sourceforge.net/projects/eclipsecolorer/"><font color="#4a664d"><u>http://sourceforge.net/projects/eclipsecolorer/</u></font></a></div><div><font color="#4a664d"></font> </div><div>12.AdvanQas 提供对if/else等条件语句的提示和快捷帮助（自动更改结构等）<br /><a href="http://eclipsecolorer.sourceforge.net/advanqas/index.html"><font color="#4a664d"><u>http://eclipsecolorer.sourceforge.net/advanqas/index.html</u></font></a></div><div><font color="#4a664d"></font> </div><div>13.Log4E     Log4j插件，提供各种和Log4j相关的任务，如为方法、类添加一个logger等<br /><a href="http://log4e.jayefem.de/index.php/Main_Page"><font color="#4a664d"><u>http://log4e.jayefem.de/index.php/Main_Page</u></font></a></div><div><font color="#4a664d"></font> </div><div>14.VSSPlugin VSS插件<br /><a href="http://sourceforge.net/projects/vssplugin"><font color="#4a664d"><u>http://sourceforge.net/projects/vssplugin</u></font></a></div><div><font color="#4a664d"></font> </div><div>15.Implementors   提供跳转到一个方法的实现类，而不是接中的功能（实用!）<br /><a href="http://eclipse-tools.sourceforge.net/implementors/"><font color="#4a664d"><u>http://eclipse-tools.sourceforge.net/implementors/</u></font></a></div><div><font color="#4a664d"></font> </div><div>16.Call Hierarchy 显示一个方法的调用层次（被哪些方法调，调了哪些方法）<br /><a href="http://eclipse-tools.sourceforge.net/call-hierarchy/index.html"><font color="#4a664d"><u>http://eclipse-tools.sourceforge.net/call-hierarchy/index.html</u></font></a></div><div><font color="#4a664d"></font> </div><div>17.EclipseTidy 检查和格式化HTML/XML文件<br /><a href="http://eclipsetidy.sourceforge.net/"><font color="#4a664d"><u>http://eclipsetidy.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>18.Checkclipse 检查代码的风格、写法是否符合规范<br /><a href="http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm"><font color="#4a664d"><u>http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm</u></font></a></div><div><font color="#4a664d"></font> </div><div>19.Hibernate Synchronizer Hibernate插件，自动映射等<br /><a href="http://www.binamics.com/hibernatesync/"><font color="#4a664d"><u>http://www.binamics.com/hibernatesync/</u></font></a></div><div><font color="#4a664d"></font> </div><div>20.VeloEclipse  Velocity插件<br /><a href="http://propsorter.sourceforge.net/"><font color="#4a664d"><u>http://propsorter.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>21.EditorList   方便的列出所有打开的Editor<br /><a href="http://editorlist.sourceforge.net/"><font color="#4a664d"><u>http://editorlist.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>22.MemoryManager 内存占用率的监视<br /><a href="http://cloudgarden.com/memorymanager/"><font color="#4a664d"><u>http://cloudgarden.com/memorymanager/</u></font></a></div><div> </div><div><font color="#ff0000">+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</font></div><div><p><strong><font size="2">plug-in网址：</font></strong></p><p><a href="http://www.eclipse-plugins.info/eclipse/index.jsp"><font color="#000080" size="2"><u>http://www.eclipse-plugins.info/eclipse/index.jsp</u></font></a></p><p><a href="http://www.eclipse-workbench.com/jsp/"><font color="#000080" size="2"><u>http://www.eclipse-workbench.com/jsp/</u></font></a></p><p><a href="http://eclipse-plugins.2y.net/eclipse/index.jsp"><font color="#000080" size="2"><u>http://eclipse-plugins.2y.net/eclipse/index.jsp</u></font></a> （非常非常著名的插件更新网站） </p><p><a href="http://www.crionics.com/products/opensource/eclipse/eclipse.jsp"><font color="#000080" size="2"><u>http://www.crionics.com/products/opensource/eclipse/eclipse.jsp</u></font></a> （分类清楚） </p><p><a href="http://www.eclipseplugincentral.com/"><font color="#000080" size="2"><u>http://www.eclipseplugincentral.com/</u></font></a></p><p><strong><font size="2">Preferences无法显示新安装的插件的解决办法</font></strong></p><p><font face="宋体" color="#ff0000" size="4">删除C:\eclipse\configuration\org.eclipse.update下的platform.xml文件，重新启动Eclipse</font></p><p><font face="宋体" color="#ff0000" size="4"></font> </p><p><font face="宋体" color="#ff0000" size="4"><font color="#000000" size="3">perl插件 </font><a href="http://e-p-i-c.sf.net/updates"><font color="#000080" size="2"><u>http://e-p-i-c.sf.net/updates</u></font></a><br /><font color="#000000" size="3">C#插件 </font><a href="http://www.improve-technologies.com/alpha/updates/site.xml"><font color="#000080" size="2"><u>http://www.improve-technologies.com/alpha/updates/site.xml</u></font></a><br /><font color="#000000" size="3">C插件 </font><a href="http://update.eclipse.org/tools/cdt/releases/new"><font color="#000080" size="2"><u>http://update.eclipse.org/tools/cdt/releases/new</u></font></a><br /><font color="#000000" size="3">Hex插件 </font><a href="http://ehep.sourceforge.net/update"><font color="#000080" size="2"><u>http://ehep.sourceforge.net/update</u></font></a></font></p><p><font face="宋体" color="#ff0000" size="4"></font> </p><p><font face="宋体" color="#ff0000" size="4"><strong><font color="#000000"><font size="2">Eclipse加速插件KeepResident</font></font></strong></font></p><p><a href="http://suif.stanford.edu/pub/keepresident/"><font color="#000080"><u>http://suif.stanford.edu/pub/keepresident/</u></font></a></p><p><font color="#000080">原理:利用两个 Windows API - SetProcessWorkingSetSize 与 VirtualLock (适用于 Windows 平台)。</font></p><p><font color="#000080">切换时果然快很多。</font></p><p><font color="#000080">官方建议最小值设定在 100 MB，最大值 250 MB 左右。</font></p></div><div> </div><div> </div><div> </div><div><font color="#800080">Eclipse插件及电子书列表</font></div><div>    近日整理了一下我的软件厂商发布记录，找到了一堆跟Eclipse有关的东东，恩，涵盖的面还非常的广泛有指导学习的书，有插件，有支持工具，自己不敢独享，便拿出来放在这里，跟大家一块儿讨论一下。这个，要声明一下，我只有软件记录，并没有保存，所以找不到列表里面的软件的，不要跟我要，我能做的也只是帮助大家寻找一下而已。所有的软件后面都有链接，但是每次更新列表的时候我的链接都没有拷贝完全，不过，前面有链接里面有软件发布的网站信息，到该网站里面自己搜索就能搞到准确的信息。</div><div><br />2004-12-01<br />Apress.The.Definitive.Guide.to.SWT.and.JFace<br />Apress出版的《The.Definitive.Guide.to.SWT.and.JFace》chm格式电子书，Eclipse平台的两个用户界面工具箱－SWT和JFace的java编程指南。<br /><a href="http://www.amazon.com/exec/obidos/tg/detai...6889430-0550522"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detai...6889430-0550522</u></font></a><br /><a href="http://images.amazon.com/images/P/15905932...SCMZZZZZZZ_.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/15905932...SCMZZZZZZZ_.jpg</u></font></a></div><div>2004-11-29<br />JasperAssistant.v1.4.2<br />JasperAssistant是一款可视化的JasperReports报表设计工具，JasperReports是一个非常流行的开放源码报告引擎。JasperAssistant基于Eclipse的插件程序结构，通过逼真的图形界面方便的创建JasperReports报表定义文件。<br /><a href="http://www.jasperassistant.com/"><font color="#008000"><u>http://www.jasperassistant.com/</u></font></a><br /><a href="http://www.jasperassistant.com/shots/full.png"><font color="#008000"><u>http://www.jasperassistant.com/shots/full.png</u></font></a></div><div>JVider.for.Eclipse.v1.7e1.Java<br />一款为JavaSwing应用程序设计的GUIBuilder工具。在他的帮助下，你可以很简单的为你的Java校应用程序和程序设计图形用户界面。<br /><a href="http://www.jvider.com/"><font color="#008000"><u>http://www.jvider.com/</u></font></a><br /><a href="http://www.jvider.com/jviderscreen.png"><font color="#008000"><u>http://www.jvider.com/jviderscreen.png</u></font></a></div><div>2004-11-28</div><div>RMI.Plugin.for.Eclipse.v1.6.1<br />Eclipse开发平台的RMI（基于Java的分布计算框架）插件，是在JavaSDK平台通过调用RMI编译器自动生成远程对象stub（桩）和skeleton（框架）的简便方法。<br /><a href="http://www.genady.net/rmi/"><font color="#008000"><u>http://www.genady.net/rmi/</u></font></a><br /><a href="http://www.genady.net/rmi/v16/screenshots/...rmi-eclipse.png"><font color="#008000"><u>http://www.genady.net/rmi/v16/screenshots/...rmi-eclipse.png</u></font></a></div><div>2004-11-19</div><div>Addison.Wesley.Professional.SWT.The.Standard.Widget.Toolkit.Volume.1.Jun.2004<br />电子书，Eclipse系列之SWT精解，SWT就是StandardWidgetToolkit，是在java中创建图形界面的类库<br /><a href="http://www.amazon.com/exec/obidos/ASIN/032...8151071-6877408"><font color="#008000"><u>http://www.amazon.com/exec/obidos/ASIN/032...8151071-6877408</u></font></a><br /><a href="http://images.amazon.com/images/P/0321256638.01.LZZZZZZZ.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/0321256638.01.LZZZZZZZ.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/22338_AddisonWesley.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/22338_AddisonWesley.html</u></font></a></div><div>2004-11-13</div><div>Omondo.Eclipse.UML.Studio.Edition.v1.1.0<br />OmondoEclipseUML是一款可视化的模块设计工具，可以完全集成于Eclipse和CVS。<br /><a href="http://www.omondo.com/"><font color="#008000"><u>http://www.omondo.com</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/21757_OmondoEclipse.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/21757_OmondoEclipse.html</u></font></a></div><div>Omondo.Eclipse.UML.Studio.Edition.v1.1.0<br />OmondoEclipseUML是一款可视化建模工具，可以与Eclipse和CVS无缝集成。</div><div>2004-10-20</div><div>Oxygen.XML.Editor.v5.0.Eclipse.plugin<br />OxygenXMLeditor是一款基于Java的XML编辑器，支持XML,XSL,TXT,XSD,DTD文档，能自行校验XML,XSL,XSD代码，提示脚本错误。Oxygen能自动完成结束标签，代码高亮现实，支持Unicode。<br /><a href="http://www.oxygenxml.com/features/"><font color="#008000"><u>http://www.oxygenxml.com/features/</u></font></a><br /><a href="http://www.oxygenxml.com/img/oxygen-mac.gif"><font color="#008000"><u>http://www.oxygenxml.com/img/oxygen-mac.gif</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/19151_OxygenXMLEdit.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/19151_OxygenXMLEdit.html</u></font></a></div><div>2004-10-19</div><div>Jigloo.GUI.Builder.v3.0.1<br />为EclipseJavaIDE和WebSphereStudio设计的插件，可以用来创建和管理Swing和SWTGUI类。<br /><a href="http://cloudgarden.com/jigloo/"><font color="#008000"><u>http://cloudgarden.com/jigloo/</u></font></a><br /><a href="http://cloudgarden.com/jigloo/images/screenshot4_sm.jpg"><font color="#008000"><u>http://cloudgarden.com/jigloo/images/screenshot4_sm.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/19038_JiglooGUIBuil.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/19038_JiglooGUIBuil.html</u></font></a></div><div>2004-10-13</div><div>Code.Pro.Studio.3.0.0<br />一款为那些使用IBMwebspherestuodio和eclipse开发环境的开发者设计的软件。能够让java的开发者有效开速的开发高质量的软件。这款软件可以通过许多重复任务来完成软件的开发，同时能够极大的提高用户界面和使开发活动流水线化。此款软件集成了CodeProAdisor，CodeProAgilityandCodeProBuild。<br /><a href="http://www.instantiations.com/codepro/default.htm"><font color="#008000"><u>http://www.instantiations.com/codepro/default.htm</u></font></a><br /><a href="http://www.instantiations.com/codepro/imag...pstudio3-sm.gif"><font color="#008000"><u>http://www.instantiations.com/codepro/imag...pstudio3-sm.gif</u></font></a></div><div>2004-10-10</div><div>Window.Builder.Pro.2.1.1<br />一款基于EclipseSWT技术上的双向javaGui设计软件。具备SWT设计以及Swing设计两个主要功能。该软件会被作为一个插件镶嵌入Eclipse以及其他一些兼容的IDEs中（WSSD,WSAD,WSED等等）。新的2.0版本支持Eclipse3.0。<br /><a href="http://www.windowbuilderpro.com/"><font color="#008000"><u>http://www.windowbuilderpro.com/</u></font></a><br /><a href="http://www.instantiations.com/swt-designer...ts/designer.gif"><font color="#008000"><u>http://www.instantiations.com/swt-designer...ts/designer.gif</u></font></a></div><div>2004-10-04</div><div>Jigloo.GUI.Builder.v3.0.0<br />Jigloo.GUI.Builder是一个为Eclipsejave和WebSphereStudio开发的插件，能够创建出滚动控制和SWTGUI的效果界面。</div><div>Vi.plugin.for.Eclipse3.v1.86<br />ViPlugin可以在vi编辑器上添加一个功能条，这个是用于Eclipse3+的。</div><div>2004-10-03</div><div>Parasoft.JTest.v5.1.71.DC.20040912.WinNT2kXP<br />自动进行JAVA单元测试和代码标准检查来帮助开发人员编写克号的代码的工具。可分析类，然后生成单元测试案例来包括最大的覆盖测试，发现未处理的异常并校验需求。<br />-自动的基本错误预防，包括单元测试和自动代码标准检查<br />-生成并执行单元测试案例<br />-提供了进行黑盒测试、模型测试和系统测试的快速简单的途径<br />-识别并预防未处理的运行时异常，函数错误，内存泄露，性能问题和安全弱点<br />-对群或方案优先作测试和报告<br />-监控测试的覆盖范围<br />-自动回归测试<br />-支持按比例压缩设计<br />-检查超过400个来自JAVA专家的编码规范<br />-改正违反超过200个编码规范的错误<br />-允许用户创建自己的编码规范<br />-可在小组范围内管理共享测试文件<br />-和IBMWebSphere和Eclipse集成<br />-支持Borland？JBuilder？,Together？ControlCenter？,和Ant</div><div>2004-09-23</div><div>Borland.Together.for.Eclipse.v6.3<br />最佳的程序分析设计工具，提供实时的协同工作能力。<br />·支持所有主要的UML图形<br />充分利用UnifiedModelingLanguage(统一建模语言—UML)搭建正确的架构，以便满足你的业务目标。每一个软件项目都需要一个蓝图，以保持整个小组向相同的方向前进并构建正确的软件。通过集成UML能力的方式，Together扩展了开发框架，简化了构建软件的复杂过程。<br />·TogetherLiveSource自动进行模型与代码的同步<br />使用同步的模型与代码，允许进行更加有效的开发小组沟通与协作。同时的同步化让手工更新成为过去，使用相同的信息保持开发小组的信息更新。模型处于灵活的状态，不会过时，这是因为开发小组做出的任何变化总是同时反映在代码与模型之中，让开发小组更加高效、更加有效。<br />·自动文档生成<br />保持开发小组专注于设计与实现，而不是拟制文档。Together提供了强大的、可以定制的文档生成能力，其中包括多种文档格式与定制模板的能力。通过自动生成文档的方式，开发者可以集中精力搞软件开发，而小组领导随时都有所需要的信息。<br />·支持业界标准的模式<br />使用业界领先的模式着手开发工作，改善了架构的质量。Together支持标准的模式，比如GoF与J2EE，并且同时也提供了更改现有模式、创建新模式的能力。广泛的模式支持使得开发小组在将来的项目中复用模式，改善所有项目的架构质量。<br />·使用审计测定软件质量<br />审计为开发小组提供了在软件开发的初期测定质量，强化企业标准的能力—在软件开发的初期，开发小组还在编制软件的代码呢。在分发之前测定质量，开发者可以改善代码的质量，在代码转交QA小组之前，发现并修复自己的错误。审计变量可以被定制并保存，这样开发小组就能制订代码标准，监视代码超出认可规范的问题。审计也被用来改变开发者的个人代码编制风格，以便符合企业的编码标准。<br />·使用度量进行软件开发的量化<br />量度为开发小组提供了测量软件项目复杂程度、质量与规模的能力。通过测量并对信息进行标准检查，管理人员能够知晓开发小组与开发过程的质量与效率，更好地进行当前与未来项目的量化。<br />·重构<br />在Together技术之中的大量重构特性验证所有的系统变化都被正确地传送到整个应用。所得到的结果便是代码不易出错，应用的质量得到改善。<br />·Together与Eclipse的集成<br />Eclipse是一种开放源代码的业界平台，Together技术与Eclipse的集成为Eclipse用户提供了一种熟悉的环境，用来进行软件开发。在Eclipse环境中，开发者可以利用TogetherEditionforEclipse之中的、领先的建模、设计与质量保证功能，快速构建高质量的企业应用。通过在Eclipse本地开发用于TogetherEditionforEclipse的用户接口，用户可受益于紧密的集成，并利用在同一个工具之中两种技术的优势。<br /><a href="http://www.borland.com/together/index.html"><font color="#008000"><u>http://www.borland.com/together/index.html</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/16494_BorlandTogethe.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/16494_BorlandTogethe.html</u></font></a></div><div>2004-08-02</div><div>Clay.Database.Modeling.Pro.for.Eclipse.v1.0.5<br />作为插件运行于Eclipse开发环境的数据库设计工具。通过直观的界面图形化地设计数据库模型。它可以通过逆向设计来根据现存数据库来设计新的数据库模型。更多地，它还能生成适合你的数据库的SQL(DDL)代码。<br /><a href="http://www.azzurri.jp/en/software/clay/index.jsp"><font color="#008000"><u>http://www.azzurri.jp/en/software/clay/index.jsp</u></font></a><br /><a href="http://www.azzurri.jp/en/software/clay/ima...y_eclipse_1.png"><font color="#008000"><u>http://www.azzurri.jp/en/software/clay/ima...y_eclipse_1.png</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/11208_ClayDatabaseM.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/11208_ClayDatabaseM.html</u></font></a></div><div>2004-07-28</div><div>Oxygen.XML.Editor.v4.2.Eclipse.plugin<br />OxygenXMLeditor是一款基于Java的XML编辑器，支持XML,XSL,TXT,XSD,DTD文档，能自行校验XML,XSL,XSD代码，提示脚本错误。Oxygen能自动完成结束标签，代码高亮现实，支持Unicode。<br /><a href="http://www.oxygenxml.com/features/"><font color="#008000"><u>http://www.oxygenxml.com/features/</u></font></a><br /><a href="http://www.oxygenxml.com/img/oxygen-mac.gif"><font color="#008000"><u>http://www.oxygenxml.com/img/oxygen-mac.gif</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/10689_OxygenXMLEdit.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/10689_OxygenXMLEdit.html</u></font></a></div><div>2004-07-26</div><div>MC.Press.Eclipse.Step.by.Step<br />MCPress出版的《Eclipse循序渐近》(Eclipse:StepbyStep)电子版，Eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言，它只是一个框架和一组服务，用于通过插件组件构建开发环境。幸运的是，Eclipse附带了一个标准的插件集，包括Java开发工具（JavaDevelopmentTools，JDT）。该书包括了Eclipse平台开发的方方面面，可以手把手帮助你编写完整的可用的程序，并更好的立即各种基本概念<br /><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1583470441/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detail/-/1583470441/</u></font></a><br /><a href="http://images.amazon.com/images/P/15834704...SCMZZZZZZZ_.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/15834704...SCMZZZZZZZ_.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/10486_MCPressEclips.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/10486_MCPressEclips.html</u></font></a></div><div>2004-07-24</div><div>Window.Builder.Pro.v2.0.1<br />一款基于EclipseSWT技术上的双向JavaGui设计软件。具备SWT设计以及Swing设计两个主要功能。该软件会被作为一个插件镶嵌入Eclipse以及其他一些兼容的IDEs中（WSSD,WSAD,WSED等等）。新的2.0版本支持Eclipse3.0。<br /><a href="http://www.windowbuilderpro.com/"><font color="#008000"><u>http://www.windowbuilderpro.com/</u></font></a><br /><a href="http://www.instantiations.com/swt-designer...ts/designer.gif"><font color="#008000"><u>http://www.instantiations.com/swt-designer...ts/designer.gif</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/10310_WindowBuilder.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/10310_WindowBuilder.html</u></font></a></div><div>2004-07-20</div><div>XMLBuddy.PRO.v2.0.11<br />Eclipse插件，提供XML编辑功能，支持XML,DTD,XMLSchema,RELAXNG,RELAXNGcompactsyntax,XSLT<br /><a href="http://xmlbuddy.com/"><font color="#008000"><u>http://xmlbuddy.com/</u></font></a><br /><a href="http://xmlbuddy.com/2.0/screen.jpg"><font color="#008000"><u>http://xmlbuddy.com/2.0/screen.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/9848_XMLBuddyPROv2.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/9848_XMLBuddyPROv2.html</u></font></a></div><div>2004-07-09</div><div>Compuware.DevPartner.Java.Edition.v3.0.3<br />快速高质量的开发java程序的开发工具箱，增强组件和软件的可靠性。可以针对个人定制不同的浏览数据窗口和调试工具。<br />新的3.03版本具有如下更新：<br />-具有Eclipse插件<br />-可以在系统，开发环境和应用程序之间交互切换<br />-还有其他更新等。</div><div>2004-05-09</div><div>Manning.Publications.Company.Eclipse.in.Action.A.Guide.for.the.Java.Developer<br />电子书-Eclipse实践：java开发人员指南。<br /><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/</u></font></a><br />PE32_PIdp-schmoo2,TopRight,7,-26_SCMZZZZZZZ.jpg"&gt;http://images.amazon.com/images/P/1930110960.01.&lt;u&gt;PE32_PIdp-schmoo2,TopRight,7,-26_SCMZZZZZZZ&lt;/u&gt;.jpg</div><div>Manning.Publications.Company.Eclipse.in.Action.A.Guide.for.the.Java.Developer<br />电子书《jave开发指南》<br /><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/</u></font></a><br /><a href="http://images.amazon.com/images/P/19301109...SCMZZZZZZZ_.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/19301109...SCMZZZZZZZ_.jpg</u></font></a></div><div>2004-05-06</div><div>SignSoft_intelliBO_v3.6.2<br />一个中间件的应用，不仅仅执行JavaDataObjects标准(JDO)（现在支持JDO标准1.0.1），而且实现智能的数据访问，所以称作：“intelligentBusinessObjects”。可集成于Eclipse及IBMWebsphereApllicationDeveloperIDE。</div><div>2004-04-27</div><div>OReilly.Eclipse.A.Java.Developers.Guide.eBook<br />《Java开发者指南》</div><div>2004-04-21</div><div>IBM.Redbooks.Eclipse.Development.Using.the.Graphical.Editing.Framework.and.the.Eclipse.Modeling.Framework.eBook<br />电子书，提供给那些具备良好知识基础以及丰富经验的使用EclipseSDK来开发插件代码的程序员,用以校验插件的工作性能。<br /><a href="http://publib-b.boulder.ibm.com/Redbooks.n...s/sg246302.html"><font color="#008000"><u>http://publib-b.boulder.ibm.com/Redbooks.n...s/sg246302.html</u></font></a></div><div>IBM.Redbooks.Eclipse.Development.Using.the.Graphical.Editing.Framework.and.the.Eclipse.Modeling.Framework.eBook<br />书名：《使用Graphical.Editing.Framework和Eclipse.Modeling.Framework进行Eclipse开发》<br />作者：BillMooreetal.<br />出版社：IBMRedbooks<br />格式：CHM<br />分类：计算机/软件开发<br />ISBN：0738453161<br />内容简介：<br />一本介绍使用GraphicalEditingFramework(GEF)和EclipseModelingFramework(EMF).进行Eclipseplugin开发的书。</div><div>2004-04-06</div><div>Rational.XDE.v2003.Developer.Plus.NET.Edition.Retail<br />RationalXDEDeveloper是一个十分完善的可视化设计和开发的环境，它可以结合Rational支持的集成开发环境（IDE）来使用，比如Eclipseplatform,IBMWebSphereStudioApplicationDeveloper,MicrosoftVisualStudio.NET等。RationalXDEDeveloper可以在构建企业应用和Web为中心的解决方案上开发人员提供支持。通过结合使用RationalXDEDeveloper的多种特性（比如，代码的双向工程，自动和按需的对代码和模型进行同步，模式引擎支持，多模型的支持，将数据库资产逆向工程为数据模型，团队协作，可选择的过程指南）可以减轻一些被需要的代码开发和设计的工作。这个是VisualStudio.NET版本的License。<br /><a href="http://www.rational.com/products/xde/index.jsp"><font color="#008000"><u>http://www.rational.com/products/xde/index.jsp</u></font></a></div><div>2003-12-29</div><div>Addison.Wesley.Contributing.To.Eclipse.Principles.Patterns.And.Plug-Ins.eBook---1<br />讲述在Eclipse(一种正在兴起的软件开发环境)下进行插件开发的电子图书</div><div>2003-12-28</div><div>Addison.Wesley.Contributing.To.Eclipse.Principles.Patterns.And.Plug-Ins.eBook---2<br />出版：Addison-WesleyPubCo；作者：ErichGamma,KentBeck；ISBN：0321205758。<br />一本关于Eclipse的书。这本书不仅仅教你怎么做而且使你完全理解Eclipse。<br /><a href="http://www.amazon.com/exec/obidos/tg/detai...l/-/0321205758/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detai...l/-/0321205758/</u></font></a></div><div>2003-11-14</div><div>Addison.Wesley.Eclipse.Modeling.Framework.A.Developers.Guide.eBook<br />电子书，EclipseModelingFramework模型构架可以使Java,XML,和UML语言开发者统一起来使用令人惊讶的模板快速构建健康的应用程序,是一本软件开发人员指导书<br /><a href="http://www.amazon.com/exec/obidos/ASIN/013...1308053-5737658"><font color="#008000"><u>http://www.amazon.com/exec/obidos/ASIN/013...1308053-5737658</u></font></a></div><img src ="http://www.blogjava.net/limq/aggbug/40329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2006-04-10 21:43 <a href="http://www.blogjava.net/limq/archive/2006/04/10/40329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4J 最佳实践之全能配置文件(转）</title><link>http://www.blogjava.net/limq/archive/2006/04/10/40328.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Mon, 10 Apr 2006 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2006/04/10/40328.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/40328.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2006/04/10/40328.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/40328.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/40328.html</trackback:ping><description><![CDATA[LOG4J的配置之简单使它遍及于越来越多的应用中了：Log4J配置文件实现了输出到控制台、文件、回滚文件、发送日志邮件、输出到数据库日志表、自定义标签等全套功能。择其一二使用就够用了， <br /><br /><br /><br />log4j.rootLogger=DEBUG,CONSOLE,A1,im <br />log4j.addivity.org.apache=true <br /><br /><br /><br /># 应用于控制台 <br /><br />log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender <br />log4j.appender.Threshold=DEBUG <br />log4j.appender.CONSOLE.Target=System.out <br />log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout <br />log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br />#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n <br /><br /><br />#应用于文件 <br /><br />log4j.appender.FILE=org.apache.log4j.FileAppender <br />log4j.appender.FILE.File=file.log <br />log4j.appender.FILE.Append=false <br />log4j.appender.FILE.layout=org.apache.log4j.PatternLayout <br />log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br /># Use this layout for LogFactor 5 analysis <br /><br /><br /><br /># 应用于文件回滚 <br /><br />log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender <br />log4j.appender.ROLLING_FILE.Threshold=ERROR <br />log4j.appender.ROLLING_FILE.File=rolling.log <br />log4j.appender.ROLLING_FILE.Append=true <br />log4j.appender.ROLLING_FILE.MaxFileSize=10KB <br />log4j.appender.ROLLING_FILE.MaxBackupIndex=1 <br />log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout <br />log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br /><br /><br />#应用于socket <br />log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender <br />log4j.appender.SOCKET.RemoteHost=localhost <br />log4j.appender.SOCKET.Port=5001 <br />log4j.appender.SOCKET.LocationInfo=true <br /># Set up for Log Facter 5 <br />log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout <br />log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n <br /><br /><br /># Log Factor 5 Appender <br />log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender <br />log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000 <br /><br /><br /><br /># 发送日志给邮件 <br /><br />log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender <br />log4j.appender.MAIL.Threshold=FATAL <br />log4j.appender.MAIL.BufferSize=10 <br />log4j.appender.MAIL.From=web@www.wuset.com <br />log4j.appender.MAIL.SMTPHost=www.wusetu.com <br />log4j.appender.MAIL.Subject=Log4J Message <br />log4j.appender.MAIL.To=web@www.wusetu.com <br />log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout <br />log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br /><br /><br /><br /># 用于数据库 <br />log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender <br />log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test <br />log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver <br />log4j.appender.DATABASE.user=root <br />log4j.appender.DATABASE.password= <br />log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n') <br />log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout <br />log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <br /><br /><br />log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender <br />log4j.appender.A1.File=SampleMessages.log4j <br />log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j' <br />log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout <br /><br />#自定义Appender <br /><br />log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender <br /><br />log4j.appender.im.host = mail.cybercorlin.net <br />log4j.appender.im.username = username <br />log4j.appender.im.password = password <br />log4j.appender.im.recipient = corlin@cybercorlin.net <br /><br />log4j.appender.im.layout=org.apache.log4j.PatternLayout <br />log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n <img src ="http://www.blogjava.net/limq/aggbug/40328.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2006-04-10 21:41 <a href="http://www.blogjava.net/limq/archive/2006/04/10/40328.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Acegi＋hibernate 动态实现基于角色的权限管理 </title><link>http://www.blogjava.net/limq/archive/2006/01/19/28585.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Wed, 18 Jan 2006 18:16:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2006/01/19/28585.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/28585.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2006/01/19/28585.html#Feedback</comments><slash:comments>27</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/28585.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/28585.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;&nbsp;&nbsp;&nbsp; 最近在做项目遇到了权限管理，用户要求可以自己建立不同的角色对系统的资源进行控制， 不同的用户有不同的角色，又恰恰框架中用到了struts＋spring＋hibernate，要求在web层调用 业务逻辑层 时不考虑权限，web层可以控制用户的显示界面，逻辑层处理用户权限问题。 想来想去好像只有spring 的aop 可以做到，在调用到 接口 中的...&nbsp;&nbsp;<a href='http://www.blogjava.net/limq/archive/2006/01/19/28585.html'>阅读全文</a><img src ="http://www.blogjava.net/limq/aggbug/28585.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2006-01-19 02:16 <a href="http://www.blogjava.net/limq/archive/2006/01/19/28585.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>四舍五入保留小数后两位</title><link>http://www.blogjava.net/limq/archive/2005/09/21/13694.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Wed, 21 Sep 2005 15:59:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2005/09/21/13694.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/13694.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2005/09/21/13694.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/13694.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/13694.html</trackback:ping><description><![CDATA[<P>&nbsp;</P>
<DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080">&nbsp;1</SPAN>&nbsp;<SPAN style="COLOR: #008000">/**</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;2</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;*&nbsp;Contains&nbsp;static&nbsp;utility&nbsp;methods.<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;3</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;4</SPAN>&nbsp;<SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000">&nbsp;BOUtils&nbsp;{<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;5</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;6</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000">&nbsp;Double&nbsp;getRoundedDouble(&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;unroundedValue&nbsp;){<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;7</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Get&nbsp;the&nbsp;integer&nbsp;portion&nbsp;of&nbsp;the&nbsp;value</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">&nbsp;8</SPAN>&nbsp;<SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;intPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Math.floor(&nbsp;unroundedValue&nbsp;);<BR></SPAN><SPAN style="COLOR: #008080">&nbsp;9</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">10</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Get&nbsp;the&nbsp;unrounded&nbsp;decimal&nbsp;portion</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">11</SPAN>&nbsp;<SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;unroundedDecimalPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;(&nbsp;unroundedValue&nbsp;</SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000">&nbsp;intPortion&nbsp;);<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">13</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">&nbsp;ALERT&nbsp;-&nbsp;This&nbsp;next&nbsp;code&nbsp;interferes&nbsp;with&nbsp;I18N.&nbsp;We&nbsp;eventually&nbsp;need&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">14</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;change&nbsp;this&nbsp;not&nbsp;assume&nbsp;only&nbsp;round&nbsp;to&nbsp;2&nbsp;decimal&nbsp;places.&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">15</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">16</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">&nbsp;Multiply&nbsp;the&nbsp;decimal&nbsp;places&nbsp;by&nbsp;100,&nbsp;which&nbsp;shitfs&nbsp;the&nbsp;decimal&nbsp;point<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;two&nbsp;places&nbsp;to&nbsp;the&nbsp;left.&nbsp;Then&nbsp;round&nbsp;it&nbsp;so&nbsp;that&nbsp;we&nbsp;get&nbsp;a&nbsp;round&nbsp;to<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;two&nbsp;decimal&nbsp;places.&nbsp;For&nbsp;example,&nbsp;if&nbsp;we&nbsp;started&nbsp;with&nbsp;17.655&nbsp;and&nbsp;stripped<BR></SPAN><SPAN style="COLOR: #008080">19</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;off&nbsp;the&nbsp;int&nbsp;portion,&nbsp;which&nbsp;left&nbsp;.655.&nbsp;After&nbsp;we&nbsp;shift,&nbsp;we&nbsp;are&nbsp;left&nbsp;with<BR></SPAN><SPAN style="COLOR: #008080">20</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;65.5.&nbsp;Then&nbsp;a&nbsp;round&nbsp;will&nbsp;gives&nbsp;us&nbsp;66.&nbsp;We&nbsp;can&nbsp;then&nbsp;put&nbsp;it&nbsp;all&nbsp;back<BR></SPAN><SPAN style="COLOR: #008080">21</SPAN>&nbsp;<SPAN style="COLOR: #008000">&nbsp;&nbsp;&nbsp;&nbsp;/*&nbsp;together&nbsp;</SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">22</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;roundedDecimalPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;Math.round(&nbsp;unroundedDecimalPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">100</SPAN><SPAN style="COLOR: #000000">&nbsp;);<BR></SPAN><SPAN style="COLOR: #008080">23</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">24</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Shift&nbsp;the&nbsp;decimal&nbsp;point&nbsp;back&nbsp;two&nbsp;places&nbsp;to&nbsp;the&nbsp;right</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">25</SPAN>&nbsp;<SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;roundedDecimalPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;roundedDecimalPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #000000">100</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">26</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">27</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000">&nbsp;Add&nbsp;the&nbsp;int&nbsp;portion&nbsp;and&nbsp;decimal&nbsp;portions&nbsp;back&nbsp;together</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">28</SPAN>&nbsp;<SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000">&nbsp;total&nbsp;</SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000">&nbsp;intPortion&nbsp;</SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000">&nbsp;roundedDecimalPortion;<BR></SPAN><SPAN style="COLOR: #008080">29</SPAN>&nbsp;<SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">30</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000">&nbsp;</SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000">&nbsp;Double(&nbsp;total&nbsp;);<BR></SPAN><SPAN style="COLOR: #008080">31</SPAN>&nbsp;<SPAN style="COLOR: #000000">&nbsp;&nbsp;}<BR></SPAN><SPAN style="COLOR: #008080">32</SPAN>&nbsp;<SPAN style="COLOR: #000000">}</SPAN></DIV><img src ="http://www.blogjava.net/limq/aggbug/13694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2005-09-21 23:59 <a href="http://www.blogjava.net/limq/archive/2005/09/21/13694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jakarta Commons:巧用类和组件（转）</title><link>http://www.blogjava.net/limq/archive/2005/09/21/13611.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Wed, 21 Sep 2005 02:03:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2005/09/21/13611.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/13611.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2005/09/21/13611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/13611.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/13611.html</trackback:ping><description><![CDATA[Jakarta Commons是Jakarta的子项目，它创建和维护着许多独立软件包，这些包一般与其他框架或产品无关，其中收集了大量小型、实用的组件，大部分面向服务器端编程。 <br /><br />　　Commons的包分成两部分：Sandbox，Commons代码库。Sandbox是一个测试平台，用来检验各种设想、计划。本文介绍的组件属于Commons代码库，文章将展示各个组件的功能、适用场合，并通过简单的例子介绍其用法。 <br /><br />　　<b>一、概述</b><br /><br />　　可重用性是Jakarta Commons项目的灵魂所在。这些包在设计阶段就已经考虑了可重用性问题。其中一些包，例如Commons里面用来记录日志的Logging包，最初是为其他项目设计的，例如Jakarta Struts项目，当人们发现这些包对于其他项目也非常有用，能够极大地帮助其他项目的开发，他们决定为这些包构造一个"公共"的存放位置，这就是Jakarta Commons项目。 <br /><br />　　为了真正提高可重用性，每一个包都必须不依赖于其他大型的框架或项目。因此，Commons项目的包基本上都是独立的，不仅是相对于其他项目的独立，而且相对于Commons内部的大部分其他包独立。虽然存在一些例外的情况，例如Betwixt包要用到XML API，但绝大部分只使用最基本的API，其主要目的就是要能够通过简单的接口方便地调用。 <br /><br />　　不过由于崇尚简洁，许多包的文档变得过于简陋，缺乏维护和支持，甚至有一部分还有错误的链接，文档也少得可怜。大部分的包需要我们自己去找出其用法，甚至有时还需要我们自己去分析其适用场合。本文将逐一介绍这些包，希望能够帮助你迅速掌握这一积累了许多人心血的免费代码库。 <br /><br />　　说明：Jakarta Commons和<a href="http://commons.apache.org/" target="_blank">Apache Commons</a>是不同的，后者是Apache Software Foundation的一个顶层项目，前者则是Jakarta项目的一个子项目，同是也是本文要讨论的主角。本文后面凡是提到Commons的地方都是指Jakarta的Commons。 <br /><br />　　为了便于说明，本文把Commons项目十八个成品级的组件（排除了EL、Latka和Jexl）分成5类，如下表所示。 <br /><br /><br />参考 <a href="/sean/archive/2005/08.html">http://www.blogjava.net/sean/archive/2005/08.html</a><br /><br /><center> </center><br /><br />　　必须指出的是，这种分类只是为了方便文章说明，Commons项目里面实际上并不存在这种分类，同时这些分类的边界有时也存在一定的重叠。 <br /><br />　　本文首先介绍Web相关类和其他类里面的组件，下一篇文章将涉及XML相关、包装这两类，最后一篇文章专门介绍属于工具类的包。 <br /><br />　　<b>二、其他类</b><br /><br />　　CLI、Discovery、Lang和Collections包归入其他类，这是因为它们都各自针对某个明确、实用的小目标，可谓专而精。 <br /><br />　　<b>2.1 CLI</b><br /><br />　　■ 概况：CLI即Command Line Interface，也就是"命令行接口"，它为Java程序访问和解析命令行参数提供了一种统一的接口。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/cli/index.html" target="_blank">主页</a>，<a href="http://www.apache.org/dist/jakarta/commons/discovery/binaries/commons-discovery-0.2.zip" target="_blank">二进制</a>，<a href="http://www.apache.org/dist/jakarta/commons/discovery/source/commons-discovery-0.2-src.zip" target="_blank">源代码</a><br /><br />　　■ 何时适用：当你需要以一种一致的、统一的方式访问命令行参数之时。 <br /><br />　　■ 示例应用：CLIDemo.java。CLASSPATH中必须包含commons-cli-1.0.jar。 <br /><br />　　■ 说明： <br /><br />　　有多少次你不得不为一个新的应用程序重新设计新的命令行参数处理方式？如果能够只用某个单一的接口，统一完成诸如定义输入参数（是否为强制参数，数值还是字符串，等等）、根据一系列规则分析参数、确定应用要采用的路径等任务，那该多好！答案就在CLI。 <br /><br />　　在CLI中，每一个想要在命令中指定的参数都是一个Option对象。首先创建一个Options对象，将各个Option对象加入Options对象，然后利用CLI提供的方法来解析用户的输入参数。Option对象可以要求用户必须输入某个参数，例如必须在命令行提供文件名字。如果某个参数是必须的，创建Option对象的时候就要显式地指定。 <br /><br />　　下面是使用CLI的步骤。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// …
// ①  创建一个Options：
Options options = new Options();
options.addOption("t", false, "current time");
// …
// ② 创建一个解析器，分析输入：
CommandLineParser parser = new BasicParser();
CommandLine cmd;
try {
	cmd = parser.parse(options, args); 
} catch (ParseException pe) {
	usage(options);
	return;
}
// …
// ③ 最后就可以根据用户的输入，采取相应的操作：
if (cmd.hasOption("n")) {
	System.err.println("Nice to meet you: " +
	cmd.getOptionValue('n'));
}</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　这就是使用CLI的完整过程了。当然，CLI还提供了其他高级选项，例如控制格式和解析过程等，但基本的使用思路仍是一致的。请参见本文最后提供的示例程序。 <br /><br />　　<b>2.2 Discovery</b><br /><br />　　■ 概况：Discovery组件是发现模式（Discovery Pattern）的一个实现，它的目标是按照一种统一的方式定位和实例化类以及其他资源。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/discovery/" target="_blank">主页</a>，<a href="http://www.apache.org/dist/jakarta/commons/discovery/binaries/commons-discovery-0.2.zip" target="_blank">二进制</a>，<a href="http://www.apache.org/dist/jakarta/commons/discovery/source/commons-discovery-0.2-src.zip" target="_blank">源代码</a>。 <br /><br />　　■ 何时适用：当你想用最佳的算法在Java程序中查找Java接口的各种实现之时。 <br /><br />　　■ 应用实例：DiscoveryDemo.java，MyInterface.java，MyImpl1.java，MyImpl2.java，MyInterface。要求CLASSPATH中必须包含commons-discovery.jar和commons-logging.jar。 <br /><br />　　■ 说明： <br /><br />　　Discovery的意思就是"发现"，它试图用最佳的算法查找某个接口的所有已知的实现。在使用服务的场合，当我们想要查找某个服务的所有已知的提供者时，Discovery组件尤其有用。 <br /><br />　　考虑一下这种情形：我们为某个特别复杂的任务编写了一个接口，所有该接口的实现都用各不相同的方式来完成这个复杂任务，最终用户可以根据需要来选择完成任务的具体方式。那么，在这种情形下，最终用户应该用什么办法来找出接口的所有可用实现（即可能的完成任务的方式）呢？ <br /><br />　　上面描述的情形就是所谓的服务-服务提供者体系。服务的功能由接口描述，服务提供者则提供具体的实现。现在的问题是最终用户要用某种办法来寻找系统中已经安装了哪些服务提供者。在这种情形下，Discovery组件就很有用了，它不仅可以用来查找那些实现了特定接口的类，而且还可以用来查找资源，例如图片或其他文件等。在执行这些操作时，Discovery遵从Sun的服务提供者体系所定义的规则。 <br /><br />　　由于这个原因，使用Discovery组件确实带来许多方便。请读者参阅本文后面示例程序中的接口MyInterface.java和两个实现类MyImpl1.java、MyImple2.java，了解下面例子的细节。在使用Discovery的时候要提供MyInterface文件，把它放入META-INF/services目录，注意该文件的名字对应接口的完整限定名称（Fully Qualified Name），如果接口属于某个包，该文件的名字也必须相应地改变。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// …
// ① 创建一个类装入器的实例。
ClassLoaders loaders =
	ClassLoaders.getAppLoaders(MyInterface.class, getClass(), false);
// …
// ② 用DiscoverClass的实例来查找实现类。
DiscoverClass discover = new DiscoverClass(loaders);
// …
// ③ 查找实现了指定接口的类：
Class implClass = discover.find(MyInterface.class);
System.err.println("Implementing Provider: " + implClass.getName());</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　运行上面的代码，就可以得到在MyInterface文件中注册的类。再次提醒，如果你的实现是封装在包里面的，在这里注册的名字也应该作相应地修改，如果该文件没有放在正确的位置，或者指定名字的实现类不能找到或实例化，程序将抛出DiscoverException，表示找不到符合条件的实现。下面是MyInterface文件内容的一个例子：MyImpl2 # Implementation 2。 <br /><br />　　当然，实现类的注册办法并非只有这么一种，否则的话Discovery的实用性就要大打折扣了！实际上，按照Discovery内部的类查找机制，按照这种方法注册的类将是Discovery最后找到的类。另一种常用的注册方法是通过系统属性或用户定义的属性来传递实现类的名字，例如，放弃META-INF/services目录下的文件，改为执行java -DMyInterface=MyImpl1 DiscoveryDemo命令来运行示例程序，这里的系统属性是接口的名字，值是该接口的提供者，运行的结果是完全一样的。 <br /><br />　　Discovery还可以用来创建服务提供者的(singleton)实例并调用其方法，语法如下：((MyInterface)discover.newInstance(MyInterface.class)).myMethod();。注意在这个例子中，我们并不知道到底哪一个服务提供者实现了myMethod，甚至我们根本不必关心这一点。具体的情形与运行这段代码的方式以及运行环境中已经注册了什么服务提供者有关，在不同的环境下运行，实际得到的服务提供者可能不同。 <br /><br />　　<b>2.3 Lang</b><br /><br />　　■ 概况：Lang是java.lang的一个扩展包，增加了许多操作String的功能，另外还支持C风格的枚举量。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/lang.html" target="_blank">主页</a>，<a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-lang/v1.0.1/commons-lang-1.0.1.zip" target="_blank">二进制</a>，<a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-lang/v1.0.1/commons-lang-1.0.1-src.zip" target="_blank">源代码</a>。 <br /><br />　　■ 何时适用：当java.lang包提供的方法未能满足需要，想要更多的功能来处理String、数值和System属性时；还有，当你想要使用C风格的枚举量时。 <br /><br />　　■ 示例应用：LangDemo.java，Mortgage.java，OnTV.java。CLASSPATH中必须包含commons-lang.jar。 <br /><br />　　■ 说明： <br /><br />　　这个包提供了许多出于方便目的而提供的方法，它们中的大多数是静态的，简化了日常编码工作。StringUtils类是其中的一个代表，它使得开发者能够超越标准的java.lang.String包来处理字符串。使用这些方法很简单，通常只要在调用静态方法时提供适当的参数就可以了。例如，如果要将某个单词的首字符改为大写，只需调用：StringUtils.capitalise("name")，调用的输出结果是Name。请浏览StringUtils API文档了解其他静态方法，也许你会找到一些可以直接拿来使用的代码。本文提供的示例程序示范了其中一些方法的使用。 <br /><br />　　另一个值得注意的类是RandomStringUtils，它提供了生成随机字符串的方法，用来创建随机密码实在太方便了。 <br /><br />　　NumberUtils类提供了处理数值数据的方法，许多方法值得一用，例如寻找最大、最小数的方法，将String转换成数值的方法，等等。NumberRange和CharRange类分别提供了创建和操作数值范围、字符范围的方法。 <br /><br />　　Builder包里的类提供了一些特殊的方法，可用来构造类的toString、hashCode、compareTo和equals方法，其基本思路就是构造出类的高质量的toString、hashCode、compareTo和equals方法，从而免去了用户自己定义这些方法之劳，只要调用一下Builder包里面的方法就可以了。例如，我们可以用ToStringBuilder来构造出类的toString描述，如下例所示： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>public class Mortgage {
	private float rate;
	private int years;
	....
	public String toString() {
		return new ToStringBuilder(this).
			append("rate",  this.rate).
			append("years", this.years).
			toString();
	}
}</ccid_code></pre></td></tr></tbody></table><span class="myp11"><font id="zoom">　　使用这类方法有什么好处呢？显然，它使得我们有可能通过一种统一的方式处理所有数据类型。所有Builder方法的用法都和上例相似。 <br /><br />　　Java没有C风格的枚举量，为此，lang包提供了一个类型安全的Enum类型，填补了空白。Enum类是抽象的，如果你要创建枚举量，就要扩展Enum类。下面的例子清楚地说明了Enum的用法。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>import org.apache.commons.lang.enum.Enum;
import java.util.Map;
import java.util.List;
import java.util.Iterator;
    
public final class OnTV extends Enum {
            
	public static final OnTV IDOL= 
	  new OnTV("Idol");
	public static final OnTV SURVIVOR =
	  new OnTV("Survivor");
	public static final OnTV SEINFELD = 
	  new OnTV("Seinfeld");

	private OnTV(String show) {
		super(show);
	}
	public static OnTV getEnum(String show){
		return (OnTV) getEnum(OnTV.class, show);
	}
	public static Map getEnumMap() {
		return getEnumMap(OnTV.class);
	}
	public static List getEnumList() {
		return getEnumList(OnTV.class);
	}
	public static Iterator iterator() {
		return iterator(OnTV.class);
	}
}</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　以后我们就可以按照下面的方式使用枚举变量：OnTV.getEnum("Idol")。该调用从前面创建的枚举数据类型返回Idol。这个例子比较简单，实际上Enum类还提供了许多有用的方法，请参见本文后面提供的完整实例。 <br /><br />　　<b>2.4 Collections</b><br /><br />　　■ 概况：扩展了Java Collection框架，增添了新的数据结构、迭代机制和比较操作符。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/collections.html" target="_blank">主页</a>，<a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-collections/v2.1/commons-collections-2.1.zip" target="_blank">二进制</a>，<a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-collections/v2.1/commons-collections-2.1-src.zip" target="_blank">源代码</a>。 <br /><br />　　■ 何时适用：几乎所有需要操作数据结构的重要Java开发项目都可以使用Collections API。和Java的标准实现相比，Collections API有着诸多优势。 <br /><br />　　■ 示例应用：CollectionsDemo.java。要求CLASSPATH中包含commons-collections.jar。 <br /><br />　　■ 说明： <br /><br />　　要在有限的文章篇幅之内详尽地介绍 Collections API实在是太困难了，不过这里仍将涵盖大多数最重要的类，希望能够引起你的兴趣，认真了解一下其余的类。Collections本身的文档也提供了许多资料并解释了每一个类的用法。 <br /><br />　　Bag接口扩展标准的Java Collection，允许生成计数器来跟踪Bag里面的所有元素。当你想要跟踪进出某个集合的元素的总数时，Bag是非常有用的。由于Bag本身是一个接口，所以实际使用的应该是实现了该接口的类，例如HashBag或TreeBag--从这些类的名字也可以看出，HashBag实现的是一个HashMap的Bag，而TreeBag实现的是TreeMap的Bag。Bag接口中两个最重要的方法是：getCount(Object o)，用来返回Bag里面特定对象的出现次数；uniqueSet()，返回所有唯一元素。 <br /><br />　　Buffer接口允许按照预定义的次序删除集合中的对象，删除次序可以是LIFO（Last In First Out，后进先出），或FIFO（First In First Out，先进先出），另外还可以是自定义的次序。下面来看看如何实现一个Buffer，按照自然次序删除元素。 <br /><br />　　BinaryHeap类实现了Buffer接口，能够按照自然次序删除元素。如果要颠倒次序，则必须传入一个false，告诉Heap采用自然次序的逆序。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>BinaryHeap heap = new BinaryHeap();
// …
// 将元素加入该Heap
heap.add(new Integer(-1));
heap.add(new Integer(-10));
heap.add(new Integer(0));
heap.add(new Integer(-3));
heap.add(new Integer(5));
//…
// 删除一个元素
heap.remove();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　调用该Heap的remove，按照自然次序，元素集合中的-10将被删除。如果我们要求按照逆序排序，则被删除的将是5。 <br /><br />　　FastArrayList、FastHashMap和FastTreeMap类能够按照两种模式操作，超越了与它们对应的标准Collection。第一种模式是"慢模式"，类的修改操作（添加、删除元素）是同步的。与此相对，另一种模式是"快模式"，对这些类的访问假定为只读操作，因此不需要同步，速度较快。在快模式中，结构性的改动通过下列方式完成：首先克隆现有的类，修改克隆得到的类，最后用克隆得到的类替换原有的类。FastArrayList、FastHashMap和FastTreeMap类特别适合于那种初始化之后大部分操作都是只读操作的多线程环境。 <br /><br />　　iterators包为各种集合和对象提供标准Java Collection包没有提供的迭代器。本文的示例应用示范了ArrayIterator，通过迭代方式访问Array的内容。iterators包里面各种迭代器的用法基本上与标准Java迭代器一样。 <br /><br />　　最后，comparators包提供了一些实用的比较符。所谓比较符其实也是一个类，它定义的是如何比较两个属于同一类的对象，决定它们的排序次序。例如，在前面提到的Buffer类中，我们可以定义自己的比较符，用自定义的比较符来决定元素的排序次序，而不是采用元素的自然排序次序。下面来看看具体的实现经过。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// …
// ① 创建一个BinaryHeap类，但这一次参数中
//    指定NullComparator。NullComparator比较
//    null与其他对象，根据nullsAreHigh标记来
//    判断null值比其他对象大还是小：如果
//    nullsAreHigh的值是false，则认为null要比
//    其他对象小。
BinaryHeap heap2 = new BinaryHeap
 (new NullComparator(false));
// …
// ② 将一些数据（包括几个null值）加入heap：
heap2.add(null);
heap2.add(new Integer("6"));
heap2.add(new Integer("-6"));
heap2.add(null);
// …
// ③ 最后删除一个元素，Bag包含的null将减少
//    一个，因为null要比其他对象小。
heap2.remove();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　有关其他类Commons组件的介绍就到这里结束。如果你想了解更多细节信息，请参见API文档，最好再看看这些包的源代码。 <br /><br />　　<b>三、Web类</b><br /><br />　　Web类的组件用来执行与Web相关的任务。 <br /><br />　　<b>3.1 FileUpload</b><br /><br />　　■ 概况：一个可以直接使用的文件上载组件。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/fileupload/index.html" target="_blank">主页</a>。由于这个组件尚未正式发布，今年二月发布的Beta版又有许多BUG，所以建议从<a href="http://cvs.apache.org/builds/jakarta-commons/nightly/commons-fileupload/" target="_blank">nightly builds</a>下载最新的版本。 <br /><br />　　■ 何时适用：当你想要在Java服务器环境中加入一个易用、高性能的文件上载组件之时。 <br /><br />　　■ 示例应用：fileuploaddemo.jsp，fileuploaddemo.htm，和msg.jsp。要求服务器端应用目录的WEB-INF/lib下面有commons-fileupload-1.0-dev.jar。 <br /><br />　　■ 说明： <br /><br />　　FileUpload组件解决了常见的文件上载问题。它提供了一个易用的接口来管理上载到服务器的文件，可用于JSP和Servlet之中。FileUpload组件遵从RFC1867，它分析输入请求，向应用程序提供一系列上载到服务器的文件。上载的文件可以保留在内存中，也可以放入一个临时位置（允许配置一个表示文件大小的参数，如果上载的文件超过了该参数指定的大小，则把文件写入一个临时位置）。另外还有一些参数可供配置，包括可接受的最大文件、临时文件的位置等。 <br /><br />　　下面介绍一下使用FileUpload组件的步骤。 <br /><br />　　首先创建一个HTML页面。注意，凡是要上载文件的表单都必须设置enctype属性，且属性的值必须是multipart/form-data，同时请求方法必须是POST。下面的表单除了上载两个文件，另外还有一个普通的文本输入框： <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code><form name="myform" action="fileuploaddemo.jsp" method="post" enctype="multipart/form-data">
    输入你的名字:<br /><input size="15" name="name" /><br />
  图形:<br /><input type="file" name="myimage" /><br />
  文件:<br /><input type="file" name="myfile" /><br /><br /><input type="submit" value="Submit your files" name="Submit" /></form></ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　接下来创建JSP页面。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// …
// ① 检查输入请求是否为multipart的表单数据。
boolean isMultipart = FileUpload.
  isMultipartContent(request);
// …
// ② 为该请求创建一个句柄，通过它来解析请求。执行
//    解析后，所有的表单项目都保存在一个List中。
DiskFileUpload upload = new DiskFileUpload();
// 通过句柄解析请求，解析得到的项目保存在一个List中
List items = upload.parseRequest(request);
// …
// ③ 通过循环依次获得List里面的文件项目。要区分表示
//    文件的项目和普通的表单输入项目，使用isFormField()
//    方法。根据处理请求的要求，我们可以保存上载的文
//    件，或者一个字节一个字节地处理文件内容，或者打
//    开文件的输入流。
Iterator itr = items.iterator();

while(itr.hasNext()) {
	FileItem item = (FileItem) itr.next();
        
// 检查当前的项目是普通的表单元素，还是一个上载的文件
	if(item.isFormField()) {
// 获得表单域的名字
	String fieldName = item.getFieldName();
// 如果表单域的名字是name…
	if(fieldName.equals("name"))
		request.setAttribute("msg", 
		"Thank You: " + item.getString());
		
	} else {
// 该项目是一个上载的文件，把它保存到磁盘。
// 注意item.getName()
// 会返回上载文件在客户端的完整路径名称，这似乎是一个BUG。
// 为解决这个问题，这里使用了fullFile.getName()。
		File fullFile  = new File(item.getName());  
		File savedFile = new File
		(getServletContext().getRealPath("/"),
		fullFile.getName());
		item.write(savedFile);
	}
}</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　我们可以通过上载句柄的upload.setSizeMax来限制上载文件的大小。当上载文件的大小超过允许的值时，程序将遇到异常。在上面的例子中，文件大小的限制值是-1，表示允许上载任意大小的文件。 <br /><br />　　还有其他一些略有变化的使用形式，正如前面所指出的，我们可以在上载的文件上打开一个输入流，或者让它们驻留在内存中直至空间占用达到一定的限制值，或者在判断文件类型的基础上，以String或Byte数组的形式获取其内容，或者直接删除文件。这一切都只要使用FileItem类提供的方法就可以方便地做到（DefaultFileItem是FileItem的一个实现）。</font></span><span class="myp11"><font id="zoom">　　<b>3.2 HttpClient</b><br /><br />　　■ 概况：这个API扩展了java.net包，提供了模拟浏览器的功能。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/httpclient/index.html" target="_blank">主页</a>，<a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-httpclient/v2.0/commons-httpclient-2.0-beta1.zip" target="_blank">二进制</a>，<a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-httpclient/v2.0/commons-httpclient-2.0-beta1-src.zip" target="_blank">源代码</a>。 <br /><br />　　■ 何时适用：当你要构造Web浏览器的功能；当你的应用需要一种高效的办法进行HTTP/HTTPS通信时。 <br /><br />　　■ 示例应用：HttpClientDemo.java。要求CLASSPATH中有commons-httpclient.jar，common-logging.jar。要求使用JDK 1.4或更高版本。 <br /><br />　　■ 说明： <br /><br />　　HttpClient扩展和增强了标准java.net包，是一个内容广泛的代码库，功能极其丰富，能够构造出各种使用HTTP协议的分布式应用，或者也可以嵌入到现有应用，为应用增加访问HTTP协议的能力。在Commons稳定版中，HttpClient的文档似乎要比其他包更完善一些，而且还带有几个实例。下面我们通过一个简单的例子来了解如何提取一个Web页面，HttpClient文档中也有一个类似的例子，我们将扩充那个例子使其支持SSL。注意本例需要JDK 1.4支持，因为它要用到Java Secure Socket Connection库，而这个库只有JDK 1.4及更高的版本才提供。 <br /><br />　　① 首先确定一个可以通过HTTPS下载的页面，本例使用的是https://www.paypal.com/。同时确保%JAVA_HOME%/jre/lib/security/java.security文件包含了下面这行代码：security.provider.2=com.sun.net.ssl.internal.ssl.Provider。 <br /><br />　　除了这些设置之外，HTTPS连接的处理方式没有其他特别的地方--至少对于本例来说如此。不过，如果远程网站使用的根证书不被你使用的Java认可，则首先必须导入它的证书。 <br /><br />　　② 创建一个HttpClient的实例。HttpClient类可以看成是应用的主驱动程序，所有针对网络的功能都依赖于它。HttpClient类需要一个Connection Manager来管理连接。HttpConnectionManager允许我们创建自己的连接管理器，或者，我们也可以直接使用内建的SimpleHttpConnectionManager或MultiThreadedHttpConnectionManager类。如果在创建HttpClient时没有指定连接管理器，HttpClient默认使用SimpleHttpConnectionManager。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// 创建一个HttpClient的实例
HttpClient client = new HttpClient();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　③ 创建一个HttpMethod的实例，即确定与远程服务器的通信要采用哪种传输方式，HTTP允许采用的传输方式包括：GET，POST，PUT，DELETE，HEAD，OPTIONS，以及TRACE。这些传输方式分别作为一个独立的类实现，但所有这些类都实现HttpMethod接口。在本例中，我们使用的是GetMethod，创建GetMethod实例时在参数中指定我们想要GET的URL。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// 创建一个HttpMethod的实例
HttpMethod method = new GetMethod(url);</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　④ 执行HttpMethod定义的提取操作。执行完毕后，executeMethod方法将返回远程服务器报告的状态代码。注意executeMethod属于HttpClient，而不是HttpMethod。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// 执行HttpMethod定义的提取操作
statusCode = client.executeMethod(method);</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　⑤ 读取服务器返回的应答。如果前面的连接操作失败，程序将遇到HttpException或IOException，其中IOException一般意味着网络出错，继续尝试也不太可能获得成功。服务器返回的应答可以按照多种方式读取，例如作为一个字节数组，作为一个输入流，或者作为一个String。获得服务器返回的应答后，我们就可以按照自己的需要任意处置它了。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>byte[] responseBody = method.getResponseBody();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　⑥ 最后要做的就是释放连接。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>method.releaseConnection();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　以上只是非常简单地介绍了一下HttpClient库，HttpClient实际的功能要比本文介绍的丰富得多，不仅健壮而且高效，请参阅API文档了解详情。 <br /><br />　　<b>3.3 Net</b><br /><br />　　■ 概况：一个用于操作Internet基础协议的底层API。 <br /><br />　　■ 官方资源：<a href="http://jakarta.apache.org/commons/net/" target="_blank">主页</a>，<a href="http://apache.planetmirror.com/dist/jakarta/commons/net/binaries/" target="_blank">二进制</a>，<a href="http://apache.planetmirror.com.au/dist/jakarta/commons/net/source/" target="_blank">源代码</a>。 <br /><br />　　■ 何时适用：当你想要访问各种Internet底层协议之时（Finger，Whois，TFTP，Telnet，POP3，FTP，NNTP，以及SMTP）。 <br /><br />　　■ 示例应用：NetDemo.java。要求CLASSPATH中包含commons-net-1.0.0.jar。 <br /><br />　　■ 说明： <br /><br />　　Net包是一个强大、专业的类库，类库里的类最初属于一个叫做NetComponents的商业产品。 <br /><br />　　Net包不仅支持对各种低层次协议的访问，而且还提供了一个高层的抽象。大多数情况下，Net包提供的抽象已能满足一般需要，它使得开发者不再需要直接面对各种协议的Socket级的低层命令。使用高层抽象并不减少任何功能，Net API在这方面做得很出色，既提供了足够的功能，又不至于在特色方面作过多的妥协。 <br /><br />　　SocketClient是支持所有协议的基础类，它是一个抽象类，聚合了各种协议都需要的公用功能。各种不同协议的使用过程其实很相似，首先利用connect方法建立一个指向远程服务器的连接，执行必要的操作，最后终止与服务器的连接。下面通过实例介绍具体的使用步骤。 <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// …
// ① 创建一个客户端。我们将用NNTPClient
//　　从新闻服务器下载新闻组清单。
client = new NNTPClient();
// …
// ② 利用前面创建的客户端连接到新闻服务器。
//　　这里选用的是一个新闻组较少的服务器。
client.connect("aurelia.deine.net");
// …
// ③ 提取新闻组清单。下面的命令将返回一个
//　　NewsGroupInfo对象的数组。如果指定的服
//　　务器上不包含新闻组，返回的数组将是空的，
//　　如果遇到了错误，则返回值是null。
list = client.listNewsgroups();
//...
// ④ 最后终止与服务器的连接。
 if (client.isConnected())
   client.disconnect();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />　　必须说明的是，listNewsgroups命令可能需要较长的时间才能返回，一方面是因为网络速度的影响，另外也可能是由于新闻组清单往往是很庞大的。NewsGroupInfo对象包含有关新闻组的详细信息，并提供了一些操作新闻组的命令，比如提取文章总数、最后发布的文章、发布文章的权限，等等。 <br /><br />　　其他客户端，例如FingerClient、POP3Client、TelnetClient等，用法也差不多。 <br /><br />　　结束语：有关Web相关类和其他类的介绍就到此结束。在下一篇文章中，我们将探讨XML类和包装类，最后一篇文章则介绍工具类。 <br /><br />　　希望读者有兴趣试试本文提供的程序实例。很多时候Jakarta Commons给人以混乱的感觉，希望本文使你加深了对Jakarta Commons了解，或者至少引起了你对Commons子项目以及它提供的各种实用API和库的兴趣。 <br /><br />请从这里下载本文代码：<a href="http://developer.ccidnet.com/pub/html/developer/code/download/jakartacommons1code.zip" target="_blank">JakartaCommons1_code.zip</a><br /></font></span></ccid_nobr><img src ="http://www.blogjava.net/limq/aggbug/13611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2005-09-21 10:03 <a href="http://www.blogjava.net/limq/archive/2005/09/21/13611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Struts＋Spring＋Hibernate开发实例</title><link>http://www.blogjava.net/limq/archive/2005/09/20/13565.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Tue, 20 Sep 2005 12:47:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2005/09/20/13565.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/13565.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2005/09/20/13565.html#Feedback</comments><slash:comments>58</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/13565.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/13565.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一 介绍本文并不想介绍Struts，Spring，Hibernate的原理系统架构等，本文地目的是通过一个较复杂地实例介绍如何整合Struts，Spring，Hibernate，网上现有的例子虽然也能达到目的，但功能都比较单一，复杂的例子时会有意想不到的麻烦。本文对读者假设已经具备了以上框架的基础知识。以及那些已经了解Struts，Spring，Hibernate的基本概念，但是还没有亲身在较...&nbsp;&nbsp;<a href='http://www.blogjava.net/limq/archive/2005/09/20/13565.html'>阅读全文</a><img src ="http://www.blogjava.net/limq/aggbug/13565.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/limq/" target="_blank">limq</a> 2005-09-20 20:47 <a href="http://www.blogjava.net/limq/archive/2005/09/20/13565.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>条件查询(Criteria Query)</title><link>http://www.blogjava.net/limq/archive/2005/09/20/13564.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Tue, 20 Sep 2005 12:42:00 GMT</pubDate><guid>http://www.blogjava.net/limq/archive/2005/09/20/13564.html</guid><wfw:comment>http://www.blogjava.net/limq/comments/13564.html</wfw:comment><comments>http://www.blogjava.net/limq/archive/2005/09/20/13564.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/limq/comments/commentRss/13564.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/limq/services/trackbacks/13564.html</trackback:ping><description><![CDATA[<P>现在Hibernate也支持一种直观的、可扩展的条件查询API。目前为止，这个API还没有更成熟的HQL查询那么强大，也没有那么多查询能力。特别要指出，条件查询也不支持投影（projection）或统计函数（aggregation）。 </P>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=querycriteria-creating></A>12.1.&nbsp;创建一个<TT class=literal>Criteria</TT>实例</H2></DIV></DIV></DIV>
<P><TT class=literal>net.sf.hibernate.Criteria</TT>这个接口代表对一个特定的持久化类的查询。<TT class=literal>Session</TT>是用来制造<TT class=literal>Criteria</TT>实例的工厂。 </P><PRE class=programlisting>Criteria crit = sess.createCriteria(Cat.class);<BR>crit.setMaxResults(50);<BR>List cats = crit.list();</PRE></DIV>
<DIV class=sect1 lang=zh-cn>
<DIV class=titlepage>
<DIV>
<DIV>
<H2 class=title style="CLEAR: both"><A name=querycriteria-narrowing></A>12.2.&nbsp;缩小结果集范围</H2></DIV></DIV></DIV>
<P>一个查询条件(Criterion)是<TT class=literal>net.sf.hibernate.expression.Criterion</TT>接口的一个实例。类<TT class=literal>net.sf.hibernate.expression.Expression</TT>定义了获得一些内置的<TT class=literal>Criterion</TT>类型。 </P><PRE class=programlisting>List cats = sess.createCriteria(Cat.class)<BR>    .add( Expression.like("name", "Fritz%") )<BR>    .add( Expression.between("weight", minWeight, maxWeight) )<BR>    .list();</PRE>
<P>表达式（Expressions）可以按照逻辑分组. </P><PRE class=programlisting>List cats = sess.createCriteria(Cat.class)<BR>    .add( Expression.like("name", "Fritz%") )<BR>    .add( Expression.or(<BR>    	Expression.eq( "age", new Integer(0) ),<BR>    	Expression.isNull("age")<BR>    ) )<BR>    .list();</PRE><PRE class=programlisting>List cats = sess.createCriteria(Cat.class)<BR>    .add( Expression.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )<BR>    .add( Expression.disjunction()<BR>        .a