﻿<?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-马尔代夫-文章分类-框架学习</title><link>http://www.blogjava.net/lvlinghui/category/15924.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 07:04:00 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 07:04:00 GMT</pubDate><ttl>60</ttl><item><title>配置Log4j</title><link>http://www.blogjava.net/lvlinghui/articles/74017.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Mon, 09 Oct 2006 03:23:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/74017.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/74017.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/74017.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/74017.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/74017.html</trackback:ping><description><![CDATA[
		<p>
				<font face="Arial" size="2">Log4J的配置文件(Configuration File)就是用来设置记录器的级别、存放器和布局的，它可接key=value格式的设置或xml格式的设置信息。通过配置，可以创建出Log4J的运行环境。<br /><br /><strong>1. 配置文件</strong><br />Log4J配置文件的基本格式如下： </font>
		</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">
				<font face="Arial" size="2">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000">#配置根Logger<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.rootLogger </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> </span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">[</span>
								<span style="COLOR: #800000">level</span>
								<span style="FONT-WEIGHT: bold; COLOR: #800000">]</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #000000"> appenderName1</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #000000"> appenderName2</span>
								<span style="COLOR: #000000">,</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> …<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#配置日志信息输出目的地Appender<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.appenderName </span>
								<span style="COLOR: #000000">=</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> fully.qualified.name.of.appender.class <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　log4j.appender.appenderName.option1 </span>
								<span style="COLOR: #000000">=</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> value1 <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　… <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　log4j.appender.appenderName.optionN </span>
								<span style="COLOR: #000000">=</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> valueN <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />#配置日志信息的格式（布局）<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.appenderName.layout </span>
								<span style="COLOR: #000000">=</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> fully.qualified.name.of.layout.class <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　log4j.appender.appenderName.layout.option1 </span>
								<span style="COLOR: #000000">=</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> value1 <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　… <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　log4j.appender.appenderName.layout.optionN </span>
								<span style="COLOR: #000000">=</span>
								<span style="COLOR: #000000"> valueN </span>
						</font>
				</font>
		</div>
		<br />
		<font face="Arial" size="2">其中 <strong>[level] </strong>是日志输出级别，共有5级：<br /></font>
		<span style="COLOR: #000000">
				<strong>
						<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">
								<font face="Arial" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
										<span style="COLOR: #000000">FATAL     </span>
										<span style="COLOR: #000000">0</span>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />ERROR     </span>
												<span style="COLOR: #000000">3</span>
										</font>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />WARN      </span>
												<span style="COLOR: #000000">4</span>
										</font>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />INFO      </span>
												<span style="COLOR: #000000">6</span>
										</font>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />DEBUG     </span>
												<span style="COLOR: #000000">7</span>
										</font>
								</font>
								<span style="COLOR: #000000">
										<br />
										<font face="Arial" size="2">
												<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
										</font>
								</span>
						</div>
						<br />
						<font face="Arial" size="2">Appender </font>
				</strong>
				<font face="Arial" size="2">为日志输出目的地，Log4j提供的appender有以下几种：<br /></font>
				<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">
						<font face="Arial" size="2">
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</font>
						<span style="COLOR: #000000">
								<font face="Arial" size="2">org.apache.log4j.ConsoleAppender（控制台），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.FileAppender（文件），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.DailyRollingFileAppender（每天产生一个日志文件），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.RollingFileAppender（文件大小到达指定尺寸的时候产生一个新的文件），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.WriterAppender（将日志信息以流格式发送到任意指定的地方） </font>
						</span>
				</div>
		</span>
		<br />
		<font face="Arial">
				<font size="2">
						<strong>Layout</strong>：日志输出格式，Log4j提供的layout有以下几种：<br /></font>
		</font>
		<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">
				<font face="Arial" size="2">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</font>
				<span style="COLOR: #000000">
						<font face="Arial" size="2">org.apache.log4j.HTMLLayout（以HTML表格形式布局），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.PatternLayout（可以灵活地指定布局模式），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.SimpleLayout（包含日志信息的级别和信息字符串），<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />org.apache.log4j.TTCCLayout（包含日志产生的时间、线程、类别等等信息） </font>
				</span>
		</div>
		<br />
		<font face="Arial">
				<font size="2">
						<strong>打印参数: </strong>Log4J采用类似C语言中的printf函数的打印格式格式化日志信息，如下:<br /></font>
		</font>
		<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">
				<font face="Arial" size="2">
						<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000">　　<strong>%m</strong>   输出代码中指定的消息<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%p</strong>   输出优先级，即DEBUG，INFO，WARN，ERROR，FATAL <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%r</strong>   输出自应用启动到输出该log信息耗费的毫秒数 <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%c</strong>   输出所属的类目，通常就是所在类的全名 <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%t</strong>   输出产生该日志事件的线程名 <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%n </strong>  输出一个回车换行符，Windows平台为“\r\n”，Unix平台为“\n” <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%d</strong>   输出日志时间点的日期或时间，默认格式为ISO8601，也可以在其后指定格式，比如：%d{yyy MMM dd HH:mm:ss</span>
								<span style="COLOR: #000000">,</span>
								<span style="COLOR: #000000">SSS}，输出类似：2002年10月18日 </span>
								<span style="COLOR: #000000">22</span>
								<span style="COLOR: #000000">：</span>
								<span style="COLOR: #000000">10</span>
								<span style="COLOR: #000000">：</span>
								<span style="COLOR: #000000">28</span>
								<span style="COLOR: #000000">，</span>
								<span style="COLOR: #000000">921</span>
						</font>
				</font>
				<font face="Arial">
						<font size="2">
								<span style="COLOR: #000000"> <br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />　　<strong>%l </strong>  输出日志事件的发生位置，包括类目名、发生的线程，以及在代码中的行数。举例：Testlog4.main(TestLog4.java:</span>
								<span style="COLOR: #000000">10</span>
								<span style="COLOR: #000000">) <img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span>
						</font>
				</font>
		</div>
		<br />
		<font face="Arial">
				<font size="2">
						<strong>2. 在代码中初始化Logger:</strong>
						<br />1）在程序中调用<strong>BasicConfigurator.configure()</strong>方法：给根记录器增加一个ConsoleAppender，输出格式通过PatternLayout设为<strong>"%-4r [%t] %-5p %c %x - %m%n"</strong>，还有根记录器的默认级别是<strong>Level.DEBUG</strong>. <br />2）配置放在文件里，通过命令行参数传递文件名字，通过<strong>PropertyConfigurator.configure(args[x])</strong>解析并配置；<br />3）配置放在文件里，通过环境变量传递文件名等信息，利用log4j默认的初始化过程解析并配置；<br />4）配置放在文件里，通过应用服务器配置传递文件名等信息，利用一个特殊的servlet来完成配置。<br /><br /><strong>3. 为不同的 Appender 设置日志输出级别：</strong><br />当调试系统时，我们往往注意的只是异常级别的日志输出，但是通常所有级别的输出都是放在一个文件里的，如果日志输出的级别是BUG！？那就慢慢去找吧。<br />这时我们也许会想要是能把异常信息单独输出到一个文件里该多好啊。当然可以，Log4j已经提供了这样的功能，我们只需要在配置中修改<strong>Appender</strong>的<font color="#990000"><strong>Threshold</strong></font></font>
		</font>
		<font color="#000000">
				<font face="Arial" size="2">就能实现,比如下面的例子：<br /><br /><strong>[配置文件]</strong><br /></font>
				<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">
						<font face="Arial" size="2">
								<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">### set log levels ###<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.rootLogger</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">debug</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000"> stdout</span>
										<span style="COLOR: #000000">,</span>
										<span style="COLOR: #000000"> D</span>
										<span style="COLOR: #000000">,</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000"> E<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />### 输出到控制台 ###<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.stdout</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">org.apache.log4j.ConsoleAppender<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.stdout.Target</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">System.out<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.stdout.layout</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">org.apache.log4j.PatternLayout<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.stdout.layout.ConversionPattern</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000"> %d{ABSOLUTE} %5p %c{</span>
										<span style="COLOR: #000000">1</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">}:%L - %m%n<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />### 输出到日志文件 ###<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">org.apache.log4j.DailyRollingFileAppender<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.File</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">logs/log.log<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.Append</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">true<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.<strong><font color="#990000">Threshold</font></strong></span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">DEBUG <strong>## 输出DEBUG级别以上的日志</strong><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.layout</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">org.apache.log4j.PatternLayout<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.layout.ConversionPattern</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">%-d{yyyy-MM-dd HH:mm:ss} </span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">[</span>
										<span style="COLOR: #800000">%t:%r</span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">]</span>
										<span style="COLOR: #000000">-</span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">[</span>
										<span style="COLOR: #800000">%p</span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">]</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000"> %m%n<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />### 保存异常信息到单独文件 ###<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">org.apache.log4j.DailyRollingFileAppender<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.File</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">logs/error.log ## 异常日志文件名<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.Append</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">true<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.<strong><font color="#990000">Threshold</font></strong></span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">ERROR<strong> ## 只输出ERROR级别以上的日志!!!<br /></strong><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.layout</span>
										<span style="COLOR: #000000">=</span>
								</font>
						</font>
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">org.apache.log4j.PatternLayout<br /><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />log4j.appender.D.layout.ConversionPattern</span>
										<span style="COLOR: #000000">=</span>
										<span style="COLOR: #000000">%-d{yyyy-MM-dd HH:mm:ss} </span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">[</span>
										<span style="COLOR: #800000">%t:%r</span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">]</span>
										<span style="COLOR: #000000">-</span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">[</span>
										<span style="COLOR: #800000">%p</span>
										<span style="FONT-WEIGHT: bold; COLOR: #800000">]</span>
										<span style="COLOR: #000000"> %m%n</span>
								</font>
						</font>
				</div>
		</font>
		<br />
		<font face="Arial">
				<font size="2">
						<strong>[代码中使用]</strong>
						<br />
				</font>
		</font>
		<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">
				<font face="Arial">
						<font size="2">
								<img id="Codehighlighter1_23_240_Open_Image" onclick="this.style.display='none'; Codehighlighter1_23_240_Open_Text.style.display='none'; Codehighlighter1_23_240_Closed_Image.style.display='inline'; Codehighlighter1_23_240_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" />
								<img id="Codehighlighter1_23_240_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_23_240_Closed_Text.style.display='none'; Codehighlighter1_23_240_Open_Image.style.display='inline'; Codehighlighter1_23_240_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" />
								<span style="COLOR: #0000ff">public</span>
								<span style="COLOR: #000000"> </span>
								<span style="COLOR: #0000ff">class</span>
								<span style="COLOR: #000000"> TestLog4j </span>
								<span id="Codehighlighter1_23_240_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
										<img src="http://www.blogjava.net/images/dot.gif" />
								</span>
						</font>
				</font>
				<span id="Codehighlighter1_23_240_Open_Text">
						<font face="Arial">
								<font size="2">
										<span style="COLOR: #000000">{<br /><img id="Codehighlighter1_65_238_Open_Image" style="DISPLAY: inline" onclick="this.style.display='none'; Codehighlighter1_65_238_Open_Text.style.display='none'; Codehighlighter1_65_238_Closed_Image.style.display='inline'; Codehighlighter1_65_238_Closed_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_65_238_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_65_238_Closed_Text.style.display='none'; Codehighlighter1_65_238_Open_Image.style.display='inline'; Codehighlighter1_65_238_Open_Text.style.display='inline';" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span>
										<span style="COLOR: #0000ff">public</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #0000ff">static</span>
										<span style="COLOR: #000000"> </span>
										<span style="COLOR: #0000ff">void</span>
										<span style="COLOR: #000000"> main(String[] args) </span>
										<span id="Codehighlighter1_65_238_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">
												<img src="http://www.blogjava.net/images/dot.gif" />
										</span>
								</font>
						</font>
						<span id="Codehighlighter1_65_238_Open_Text" style="DISPLAY: inline">
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000">{<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        PropertyConfigurator.configure(</span>
												<span style="COLOR: #000000">"</span>
												<span style="COLOR: #000000">D:/Code/conf/log4j.properties</span>
												<span style="COLOR: #000000">"</span>
										</font>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        Logger logger </span>
												<span style="COLOR: #000000">=</span>
												<span style="COLOR: #000000"> Logger.getLogger(TestLog4j.</span>
												<span style="COLOR: #0000ff">class</span>
										</font>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        logger.debug(</span>
												<span style="COLOR: #000000">"</span>
												<span style="COLOR: #000000">debug</span>
												<span style="COLOR: #000000">"</span>
										</font>
								</font>
								<font face="Arial">
										<font size="2">
												<span style="COLOR: #000000">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />        logger.error(</span>
												<span style="COLOR: #000000">"</span>
												<span style="COLOR: #000000">error</span>
												<span style="COLOR: #000000">"</span>
										</font>
								</font>
								<span style="COLOR: #000000">
										<font face="Arial" size="2">);<br /><img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</font>
								</span>
						</span>
						<span style="COLOR: #000000">
								<br />
								<font face="Arial" size="2">
										<img src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</font>
						</span>
				</span>
		</div>
		<br />
		<font face="Arial" size="2">运行一下，看看异常信息是不是保存在了一个单独的文件error.log中。</font>
<img src ="http://www.blogjava.net/lvlinghui/aggbug/74017.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-09 11:23 <a href="http://www.blogjava.net/lvlinghui/articles/74017.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>10秒为任意数据库增加执行日志功能</title><link>http://www.blogjava.net/lvlinghui/articles/73334.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Tue, 03 Oct 2006 13:41:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/73334.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/73334.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/73334.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/73334.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/73334.html</trackback:ping><description><![CDATA[JDBMonitor是一个开源项目。使用它开发者可以很轻松为系统增加数据库执行日志功能。它使用十分方便，您所需要做的唯一事情就是在您系统的JDBC连接字符串前增加类似于 "listenerconfig=/config.xml:url=" 的字符即可，不用写任何代码。<br /><br />使用 JDBMonitor，您可以把数据库执行情况记录通过各种方式记录下来，比如打印到控制台、输出到文件或者通过socket传送给远程客户端。JDBMonitor是可扩展的，您可以扩展它来将执行情况通过其他方式记录下来，您所需要做的就是写一个实现IDBListener接口的类即可。<br /><br />JDBMonitor遵守 GNU Lesser General Public Licence (LGPL)协议。此协议包含在发行包中。<br /><br />入门<br />几乎所有大型数据库应用都包含有自己的SQL执行日志功能，此功能不仅能帮助开发人员调试，而且可以为DBA（数据库管理员）提供系统的运行信息。<br /><br />（1）很难将业务逻辑同日志代码分离<br /><br />（2）降低了代码的可读性。<br /><br />（3）降低了系统的运行速度。在记录日志的时候，程序会暂停运行等待直到记录完成，而I/O操作是相当耗时的。<br /><br />（4）很难记录运行耗时、语句参数等其他信息<br /><br />（5）很难为我们无法修改代码的系统（例如没有源代码的系统）或者很难增加记录日志功能代码的系统（比如系统使用了ORMapping）增加日志功能。<br /><br />JDBMonitor 则不同：<br /><br />（1）您最多只需要修改一行代码。您需要修改的代码就是这一行:Class.forName("com.cownew.JDBMonitor.jdbc.DBDriver") ,然后再修改一下 JDBC连接字符串，只要从 “jdbc:db2://10.74.198.247:50000/app”修改成” listenerconfig=config.xml:url= jdbc:db2://10.74.198.247:50000/app”就可以了。在您使用WebLogic ,Tomcat或其他服务器的数据源功能的时候，连修改代码这一步都是无需的。<br /><br />（2）JDBMonitor另起一个线程来记录SQL，所以它不会对程序运行速度有任何影响。<br /><br />（3）它是高度可扩展的，所以您可以扩展它来把执行情况通过其他方式记录。比如，您可以写一个扩展类，来通过电子邮件将日志发送出去。<br /><br />取得 JDBMonitor<br />JDBMonitor的最新稳定版本可以在JDBMonitor的网站上取得：<br /><br /><a href="http://www.cownew.com/JDBMonitor">http://www.cownew.com/JDBMonitor</a><br /><br />使用 JDBMonitor<br />1 将 jdbmonitor.jar放到您系统的类路径下。<br /><br />2 让系统加载 JDBMonitor的JDBC驱动。<br /><br />这一步将会依您系统加载JDBC驱动的方式的不同而不同。<br /><br />（1）如果您通过代码的形式加载JDBC驱动，例如：<br /><br />   Class.forName(“com.microsoft.jdbc.sqlserver.SQLServerDriver”);<br />   Connection cn = DriverManager.getConnection(……);<br /><br />在这种情况下 ，您必须修改 “Class.forName”这一句来加载JDBMonitor的JDBC驱动（“com.cownew.JDBMonitor.jdbc.DBDriver”），而非以前的数据库JDBC驱动。<br /><br />例如：<br /><br />Class.forName(“com.cownew.JDBMonitor.jdbc.DBDriver”);<br />   Connection cn = DriverManager.getConnection(……);<br /><br />（2）如果您在配置文件中指定JDBC驱动，比如，数据源配置文件或者其他类似的文件。<br /><br />请修改原来的  JDBC驱动类为 “com.cownew.JDBMonitor.jdbc.DBDriver” 。 <br /><br /><br />3 让 JDBMonitor加载能够加载原来的JDBC驱动<br /><br />JDBMonitor的工作原理就是截获JDBC驱动的SQL语句调用、记录SQL语句，然后将SQL语句重新转发给原来的JDBC驱动，所以JDBMonitor必须首先向DriverManager注册JDBC驱动。<br /><br />原来的JDBC驱动定义在配置文件的“JdbcDrivers” 段中。 <br />&lt;JdbcDrivers&gt;<br />    &lt;JdbcDriver class=" com.mysql.jdbc.Driver"/&gt;<br />  &lt;/JdbcDrivers&gt;<br /><br />4 在原来的JDBC连接字符串前增加 JDBMonitor所需的信息。<br /><br />您所需要做的就是将” listenerconfig=&lt;configfilepath&gt;:url=” 增加到原来的JDBC连接字符串前。“&lt;configfilepath&gt;”代表配置文件的路径，下面集中路径都是合法的：<br /><br />/com/jdbmonitor/config.xml <br />com/jdbmonitor/config.xml<br />c:/ jdbmonitor /config.xml<br /><br />JDBMoinitor使用getClass().getResourceAsStream加载类似于“/com/jdbmonitor/config.xml” and “com/jdbmonitor/config.xml” 的类路径文件，使用 FileInputStream加载类似于 “c:/ jdbmonitor /config.xml”的配置文件。<br /><br /><br />5 指定您要使用监听器：<br /><br />您可以把数据库执行情况记录通过各种方式记录下来，比如打印到控制台、输出到文件或者通过socket传送给远程客户端。<br /><br />我们已经开发了如下常用的监听器：FileDBListener、ConsoleDBListener、 SocketDBListene、DataBaseDBListener。当然您也可以开发满足您要求的监听器。<br />监听器定义在配置文件的 “Listeners”段中：<br /><br />&lt;Listeners&gt; <br />    &lt;!--ConsoleDBListener no arguments--&gt; <br />    &lt;Listener class="com.cownew.JDBMonitor.listenerImpl.ConsoleDBListener" arg=""/&gt; <br />    <br />    &lt;!--the arguments of FileDBListener is the file to log the SQL statement --&gt; <br />    &lt;Listener class="com.cownew.JDBMonitor.listenerImpl.FileDBListener" arg="c:/aaa.txt"/&gt; <br />    <br />    &lt;!--the arguments of SocketDBListener is the bound socket port of the listener server --&gt; <br />    &lt;Listener class="com.cownew.JDBMonitor.listenerImpl.SocketDBListener" arg="9527"/&gt; <br />  &lt;/Listeners&gt; <br /><br />搞定！启动您的系统。耶！SQL语句被记录下来了，我们可以在控制台、文件甚至远程监视器中看到日志了。<br /><br />举例<br />mvnforum的例子：<br />您可以从<a href="http://www.mvnforum.com/">http://www.mvnForum.com</a>得到mvnforum。我演示用的版本是1.0。<br /><br />（1）打开webapp\WEB-INF\classes\ mvncore.xml，重新配置：<br /><br />修改之前：<br /><br />&lt;driver_class_name&gt;com.mysql.jdbc.Driver&lt;/driver_class_name&gt;<br />&lt;database_url&gt;listenerconfig=c:/log/jdbmonitor/config.xml:url= jdbc:mysql://localhost/mvnforum?useUnicode=true&amp;characterEncoding=utf-8&lt;/database_url&gt;<br /><br />修改之后： <br />&lt;driver_class_name&gt; com.cownew.JDBMonitor.jdbc.DBDriver &lt;/driver_class_name&gt;<br />        &lt;database_url&gt;jdbc:mysql://localhost/mvnforum?useUnicode=true&amp;characterEncoding=utf-8&lt;/database_url&gt;<br /><br />（2）创建文件 c:/log/jdbmonitor/config.xml。我只想将SQL语句记录到文本文件中，所以我做如下配置： <br />&lt;config&gt;<br />  &lt;Listeners&gt;<br />    &lt;!--the arguments of FileDBListener is the file to log the SQL statement --&gt;<br />    &lt;Listener class="com.cownew.JDBMonitor.listenerImpl.FileDBListener" arg="c:/log.txt"/&gt;<br />  &lt;/Listeners&gt;<br />  &lt;JdbcDrivers&gt;<br />    &lt;JdbcDriver class="com.mysql.jdbc.Driver"/&gt;<br />  &lt;/JdbcDrivers&gt;<br />&lt;/config&gt;<br />（3） 将 jdbmonitor.jar放到webapp\WEB-INF\lib下。<br />(4) 搞定！<br /><br />Jive的例子：<br /><br />您可以从<a href="http://www.jivesoftware.com/">http://www.jivesoftware.com</a>得到Jive。我演示用的版本是 Jive 2.0 beta版。<br /><br />（1）打开<a href="http://localhost:8080/jive/admin/">http://localhost:8080/jive/admin/</a><br />“jdbc” 填为：com.cownew.JDBMonitor.jdbc.DBDriver<br />“server” 填为：c:/log/jdbmonitor/config.xml:url=jdbc:mysql://locahost/jive<br />（2）将 jdbmonitor.jar放到WEB-INF\lib下<br />(4) 象mvnforum中一样创建同样的 c:/log/jdbmonitor/config.xml 文件.<br />(4) 搞定!<br />代码方式的例子：<br /><br />尽管直接在代码中指定系统所用的JDBC驱动类名和JDBC连接字符串是不推荐的，但是仍然有系统是这么做的。<br /><br />比如：<br /><br />              Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");<br />              Connection conn = null;<br />              PreparedStatement ps = null;<br />              try<br />              {<br />                     conn = DriverManager<br />                                   .getConnection("jdbc:odbc:MQIS");<br />                     for (int i = 0; i &lt; 1000; i++)<br />                     {                    <br />                            ps = conn.prepareStatement("update T_Material set fid=fid");<br />                            ps.execute();<br />                            ps.close();<br />                     }<br />              } finally<br />              {<br />                     ....          <br />              }<br /><br />（1）修改一下代码为：<br />               Class.forName("com.cownew.JDBMonitor.jdbc.DBDriver");<br />              Connection conn = null;<br />              PreparedStatement ps = null;<br />              try<br />              {<br />                     conn = DriverManager.getConnection("listenerconfig= c:/log/jdbmonitor/config.xml:url=jdbc:odbc:MQIS");<br />                     for (int i = 0; i &lt; 1000; i++)<br />                     {<br />                            ps = conn.prepareStatement("update T_Material set fid=fid");<br />                            ps.execute();<br />                            ps.close();<br />                     }<br />              } finally<br />              {<br />                     ....          <br />              }<br /><br />（2）创建c:/log/jdbmonitor/config.xml文件。我想记录SQL语句到文本文件中同时输出到控制台，这样可以辅助我进行调试，所以我配置如下： <br />&lt;config&gt;<br />  &lt;Listeners&gt;<br />    &lt;!--the arguments of FileDBListener is the file to log the SQL statement --&gt;<br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.FileDBListener" arg="c:/log.txt"/&gt;<br /><br />&lt;!--ConsoleDBListener no arguments--&gt;<br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.ConsoleDBListener" arg=""/&gt;<br />  &lt;/Listeners&gt;<br />  &lt;JdbcDrivers&gt;<br />    &lt;JdbcDriver class="com.mysql.jdbc.Driver"/&gt;<br />  &lt;/JdbcDrivers&gt;<br />&lt;/config&gt;<br />(3) 将 jdbmonitor.jar放到类路径下。<br />(4) 搞定!<br /><br />监听器<br />我们已经开发了如下常用的监听器：FileDBListener、ConsoleDBListener、 SocketDBListener、DataBaseDBListener。<br /><br />1、ConsoleDBListener 控制台监听器<br /><br />ConsoleDBListener会将SQL语句打印到控制台中。<br /><br /><br /><br />这个监听器很容易配置：<br /><br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.ConsoleDBListener" arg=""/&gt;<br /><br />2、FileDBListener 文件监听器<br /><br />FileDBListener 会将SQL语句保存到文本文件中。<br /><br /> <br /><br />如下配置：<br /><br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.FileDBListener" arg="c:/aaa.txt"/&gt;<br /><br />arg="c:/aaa.txt"表示日志将保存到文件c:/aaa.txt中。<br /><br />3、SocketDBListener Socket监听器<br /><br />SocketDBListener是一个socket服务器，客户端连接到它上边以后就可以接收到它发出的SQL语句。<br /><br />如下配置：<br /><br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.SocketDBListener" arg="9527"/&gt;<br /><br />arg="9527"表示服务器将在9527端口监听。<br /><br />我们已经开发了如下两种客户端：SocketConsoleClient（Socket控制台客户端） 和 SocketSwingClient（Socket Swing客户端）。<br /><br />SocketConsoleClient工作在控制台中：<br /><br /><br /><br />SocketSwingClient是一个Swing GUI客户端：<br /><br /><br /><br />您可以运行"java -classpath jdbmonitor.jar com.cownew.JDBMonitor.listenerImpl.sckListenerClient.SocketConsoleClient" 来启动SocketConsoleClient，运行"java -classpath jdbmonitor.jar com.cownew.JDBMonitor.listenerImpl.sckListenerClient.SocketSwingClient"启动SocketSwingClient。<br /><br />您可以编写符合您自己要求的客户端，具体细节请参考com.cownew.JDBMonitor.listenerImpl.sckListenerClient.ListenerClient和com.cownew.JDBMonitor.listenerImpl.sckListenerClient.IDBSocketClientListener.<br /><br />4、DataBaseDBListener<br /><br />DataBaseDBListener将会把SQL语句记录到数据库中：<br /><br /><br /><br />如下配置：<br /><br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.DataBaseDBListener" <br />arg="dburl=jdbc:odbc:MQIS;user=;password=;logtable=T_Log_SQLLog"/&gt; <br /><br />"dburl=jdbc:odbc:MQIS;user=;password=;"表示目标数据库的JDBC连接字符串。"logtable=T_Log_SQLLog" 表示SQL记录将被保存到哪个表中，默认的是T_Log_SQLLog。<br /><br />如果目标数据库用的JDBC驱动与被监控的数据库不同，请将它加入配置文件的 "JdbcDrivers" 部分，例如：<br /><br />&lt;config&gt;<br />&lt;Active&gt;true&lt;/Active&gt;<br />&lt;Listeners&gt;<br /><br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.ConsoleDBListener" arg=""/&gt;<br /><br />&lt;Listener class="com.cownew.JDBMonitor.listenerImpl.DataBaseDBListener" <br />arg="dburl=jdbc:odbc:MQIS;user=;password=;logtable=T_Log_SQLLog"/&gt;<br />&lt;/Listeners&gt;<br />&lt;JdbcDrivers&gt;<br />&lt;JdbcDriver class="com.microsoft.jdbc.sqlserver.SQLServerDriver"/&gt;<br />&lt;JdbcDriver class="sun.jdbc.odbc.JdbcOdbcDriver"/&gt;<br />&lt;/JdbcDrivers&gt;<br />&lt;/config&gt;<br /><br />"T_Log_SQLLog"的结构是：<br /><br /><br /><br />"T_Log_SQLLog"的建库脚本在com/cownew/JDBMonitor/listenerImpl/dataBaseListener,(db2.sql,mssqlserver.sql,oracle.sql)。<br /><br />DataBaseDBListener是跨数据库的，你可以把记录SQL到任何关系数据库中。<br /><br />FAQ:<br />1 如果我暂时不想记录SQL语句执行怎么办？难道我要重新修改成原来的样子？<br /><br />答：无须如此。您只要修改config.xml，增加&lt;Active&gt;false&lt;/Active&gt;到文件中即可。<br /><br />如下： <br /><br />&lt;config&gt;<br />  &lt;Active&gt; false &lt;/Active&gt;<br />  &lt;Listeners&gt;<br />......<br />&lt;/config&gt;<br /><br />如何扩展JDBMonitor？<br />我们已经开发了如下常用的监听器：FileDBListener、ConsoleDBListener、 SocketDBListener、DataBaseDBListener。当然您也可以开发满足您要求的监听器。所有的监听器必须实现接口：com.cownew.JDBMonitor.commo. IDBListener。IDBListener有两个方法需要实现：<br /><br />public void init(String arg);<br />public void logSql(SQLInfo info);<br /><br />JDBMonitor会将配置文件中监听器定义中“arg”的值传递给 “init”方法、将代表SQL语句执行信息的SQLInfo传递给“logSql”方法。<br /><br />更多信息请参考API文档。<br /><img src ="http://www.blogjava.net/lvlinghui/aggbug/73334.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-03 21:41 <a href="http://www.blogjava.net/lvlinghui/articles/73334.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Struts的一种分页方法</title><link>http://www.blogjava.net/lvlinghui/articles/73332.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Tue, 03 Oct 2006 13:19:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/73332.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/73332.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/73332.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/73332.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/73332.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 和绝大多数分页一样，本例也是把所有数据查询出来，然后通过						rsHandler						(rs,offset,limit)来取出当前页所该显示的数据，这样做非常消耗系统资源，如果数据库中存在几十万数据，估计服务器成拖拉机了																						　　conn = ds.getConnection();														...&nbsp;&nbsp;<a href='http://www.blogjava.net/lvlinghui/articles/73332.html'>阅读全文</a><img src ="http://www.blogjava.net/lvlinghui/aggbug/73332.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-03 21:19 <a href="http://www.blogjava.net/lvlinghui/articles/73332.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>规范分页</title><link>http://www.blogjava.net/lvlinghui/articles/73330.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Tue, 03 Oct 2006 13:14:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/73330.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/73330.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/73330.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/73330.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/73330.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 分页，这是Web应用中经常要涉及的问题，相信每一位开发人员都有这个自信解决这个问题，看了不少各式各样的分页实现代码，总觉得应该有一个比较好的规范来处理分页。有没有一个比较好、规范的分页接口，这样大家都可以围绕此接口做实现，这样分页处理就统一起来，简单多，而不我们看到现象：不同公司个人的不同版本的分页实现。个人非常欣赏aopalliance项目，虽然只是一些接口的定义，但定于规范化AOP确实做出不小...&nbsp;&nbsp;<a href='http://www.blogjava.net/lvlinghui/articles/73330.html'>阅读全文</a><img src ="http://www.blogjava.net/lvlinghui/aggbug/73330.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-03 21:14 <a href="http://www.blogjava.net/lvlinghui/articles/73330.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ArticlesManager 0.1 分页功能的实现--Hibernate</title><link>http://www.blogjava.net/lvlinghui/articles/73329.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Tue, 03 Oct 2006 13:10:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/73329.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/73329.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/73329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/73329.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/73329.html</trackback:ping><description><![CDATA[
		<div class="content">
				<p>ArticlesManager 的分页功能基于 Hibernate 的 分页实现。</p>
				<p>主要好处就是移植了，至于效率如何，暂时还没有考虑到，Hibernate推荐的，应该还不错吧！</p>
				<p>将含有分页的列表页面作为一个对象，对象中组合了 Articles 这个对象。</p>
				<p>该对象还具有返回是否是首页，是否为末页，是否有上页，下页 等方法。</p>
				<p>PageNavigation.java  的类的具体代码：</p>
				<p>
				</p>
				<pre class="java" style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; FONT: 10px Verdana, Courier, monospace; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #000066; BORDER-BOTTOM: #d0d0d0 1px solid; BACKGROUND-COLOR: #f0f0f0">
						<div style="PADDING-RIGHT: 2px; PADDING-LEFT: 2px; FONT-SIZE: 10px; PADDING-BOTTOM: 2px; COLOR: #808080; PADDING-TOP: 2px; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: Verdana, Arial, sans-serif; BACKGROUND-COLOR: #f0f0ff">JavaZoo.com © 2006. Code Language:java.</div>
						<ol>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">package</span> net.<span style="COLOR: #006600">hulihutu</span>.<span style="COLOR: #006600">pages</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #a1a100">import org.hibernate.HibernateException;</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #a1a100">import org.hibernate.Query;</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #a1a100">import org.hibernate.ScrollableResults;</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #a1a100">import java.util.List;</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">/**</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">  * Hibernate分页信息</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">  */</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="FONT-WEIGHT: bold; COLOR: #000000">class</span> PageNavigation <span style="FONT-WEIGHT: bold; COLOR: #000000">implements</span> Page <span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">private</span>
												<a style="COLOR: #000060" href="http://www.google.com/search?hl=en&amp;q=allinurl%3AList+java.sun.com&amp;bntI=I%27m%20Feeling%20Lucky">
														<span style="FONT-WEIGHT: bold; COLOR: #aaaadd">List</span>
												</a> elements;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">private</span>
												<span style="COLOR: #993333">int</span> pageSize;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">private</span>
												<span style="COLOR: #993333">int</span> pageNumber;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">private</span>
												<span style="COLOR: #993333">int</span> totalElements = <span style="COLOR: #cc66cc">0</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">/**</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   * 构建PageNavigation对象，完成Hibernate的Query数据的分页处理</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   *</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   * @param query           Hibernate的Query对象</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   * @param pageNumber 当前页编码，从1开始，如果传的值为Integer.MAX_VALUE表示获取最后一页。</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   *                                     如果你不知道最后一页编码，传Integer.MAX_VALUE即可。如果当前页超过总页数，也表示最后一页。</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   *                                     这两种情况将重新更改当前页的页码，为最后一页编码。</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   * @param pageSize     每一页显示的条目数</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   */</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span> PageNavigation<span style="COLOR: #66cc66">(</span>Query query, <span style="COLOR: #993333">int</span> pageNumber, <span style="COLOR: #993333">int</span> pageSize<span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageNumber</span> = pageNumber;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageSize</span> = pageSize;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">try</span>
												<span style="COLOR: #66cc66">{</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">      ScrollableResults scrollableResults = query.<span style="COLOR: #006600">scroll</span><span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">//get the total elements number</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">      scrollableResults.<span style="COLOR: #006600">last</span><span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">totalElements</span> = scrollableResults.<span style="COLOR: #006600">getRowNumber</span><span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #b1b100">if</span>
												<span style="COLOR: #66cc66">(</span>
												<a style="COLOR: #000060" href="http://www.google.com/search?hl=en&amp;q=allinurl%3AInteger+java.sun.com&amp;bntI=I%27m%20Feeling%20Lucky">
														<span style="FONT-WEIGHT: bold; COLOR: #aaaadd">Integer</span>
												</a>.<span style="COLOR: #006600">MAX_VALUE</span> == <span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageNumber</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">          || <span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageNumber</span> &gt; getLastPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #808080; FONT-STYLE: italic">//last page</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">{</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageNumber</span> = getLastPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">      elements = query.<span style="COLOR: #006600">setFirstResult</span><span style="COLOR: #66cc66">(</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">(</span>
												<span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageNumber</span> - <span style="COLOR: #cc66cc">1</span><span style="COLOR: #66cc66">)</span> * <span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageSize</span><span style="COLOR: #66cc66">)</span>.<span style="COLOR: #006600">setMaxResults</span><span style="COLOR: #66cc66">(</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageSize</span> + <span style="COLOR: #cc66cc">1</span><span style="COLOR: #66cc66">)</span>.<span style="COLOR: #006600">list</span><span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
												<span style="FONT-WEIGHT: bold; COLOR: #000000">catch</span>
												<span style="COLOR: #66cc66">(</span>HibernateException e<span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">throw</span>
												<span style="FONT-WEIGHT: bold; COLOR: #000000">new</span>
												<a style="COLOR: #000060" href="http://www.google.com/search?hl=en&amp;q=allinurl%3ARuntimeException+java.sun.com&amp;bntI=I%27m%20Feeling%20Lucky">
														<span style="FONT-WEIGHT: bold; COLOR: #aaaadd">RuntimeException</span>
												</a>
												<span style="COLOR: #66cc66">(</span>e<span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">boolean</span> getIsFirstPage<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> == <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">boolean</span> getIsLastPage<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> &gt;= getLastPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">boolean</span> getHasNextPage<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getLastPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> &gt; getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">boolean</span> getHasPreviousPage<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> &gt; <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getLastPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> totalElements % <span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageSize</span> == <span style="COLOR: #cc66cc">0</span> ? totalElements</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">        / <span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageSize</span> : totalElements / <span style="FONT-WEIGHT: bold; COLOR: #000000">this</span>.<span style="COLOR: #006600">pageSize</span> + <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">/**</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   * 返回List类型数据</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   *</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   * @return     List数据源</span>
										</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #808080; FONT-STYLE: italic">   */</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<a style="COLOR: #000060" href="http://www.google.com/search?hl=en&amp;q=allinurl%3AList+java.sun.com&amp;bntI=I%27m%20Feeling%20Lucky">
														<span style="FONT-WEIGHT: bold; COLOR: #aaaadd">List</span>
												</a> getElements<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> elements;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getTotalNumberOfElements<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> totalElements;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getThisPageFirstElementNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span>
												<span style="COLOR: #66cc66">(</span>getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> - <span style="COLOR: #cc66cc">1</span><span style="COLOR: #66cc66">)</span> * getPageSize<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> + <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getThisPageLastElementNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #993333">int</span> fullPage = getThisPageFirstElementNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> + getPageSize<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> - <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getTotalNumberOfElements<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> &lt; fullPage ? getTotalNumberOfElements<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">        : fullPage;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getNextPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> + <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getPreviousPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span> - <span style="COLOR: #cc66cc">1</span>;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getPageSize<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> pageSize;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">public</span>
												<span style="COLOR: #993333">int</span> getThisPageNumber<span style="COLOR: #66cc66">(</span><span style="COLOR: #66cc66">)</span><span style="COLOR: #66cc66">{</span></div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="FONT-WEIGHT: bold; COLOR: #000000">return</span> pageNumber;</div>
								</li>
								<li style="FONT-WEIGHT: bold; COLOR: #006060">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020">
												<span style="COLOR: #66cc66">}</span>
										</div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
								<li style="FONT: 10px Verdana, Courier, monospace; COLOR: #003030">
										<div style="FONT: 10px Verdana, Courier, monospace; COLOR: #000020"> </div>
								</li>
						</ol>
						<div style="PADDING-RIGHT: 2px; BORDER-TOP: #d0d0d0 1px solid; PADDING-LEFT: 2px; FONT-SIZE: 10px; PADDING-BOTTOM: 2px; COLOR: #808080; PADDING-TOP: 2px; FONT-FAMILY: Verdana, Arial, sans-serif; BACKGROUND-COLOR: #f0f0ff">Parsed in 0.862 seconds,  using GeSHi 1.0.7.12</div>
				</pre>
				<p>
				</p>
				<p>分页后的文章列表参见附件，右下角为分页连接。</p>
				<p>目前Jsp页面中完全不含有 java 类，但是看到很多程序使用的自定义tld来处理分页，打算以后对这部分内容进行重构。</p>
				<p>附件4为 articleListAction 。给浏览器返回的是 pageNagivation 类 ^_^ </p>
				<p> </p>
		</div>
		<div class="attach">图片附件(缩略图):<br /><a href="http://www.hulihutu.net/attachment.php?id=52" target="_blank"><img height="158" alt="大小: 203.11 K&#xD;尺寸: 400 x 158&#xD;浏览: 4 次&#xD;点击打开新窗口浏览全图" src="http://www.hulihutu.net/attachments/date_200608/thumb_1fe68fb47a7fcd9b3c221bb5e0e20c0a.jpg" width="400" border="0" /></a></div>
		<div class="attach">图片附件(缩略图):<br /><a href="http://www.hulihutu.net/attachment.php?id=53" target="_blank"><img height="122" alt="大小: 155.75 K&#xD;尺寸: 400 x 122&#xD;浏览: 2 次&#xD;点击打开新窗口浏览全图" src="http://www.hulihutu.net/attachments/date_200608/thumb_d25bdd12230a8b0cb671f61e546430a5.jpg" width="400" border="0" /></a></div>
		<div class="attach">图片附件(缩略图):<br /><a href="http://www.hulihutu.net/attachment.php?id=54" target="_blank"><img height="133" alt="大小: 177.13 K&#xD;尺寸: 400 x 133&#xD;浏览: 3 次&#xD;点击打开新窗口浏览全图" src="http://www.hulihutu.net/attachments/date_200608/thumb_e393211e03b02eae01ffd9f653377af9.jpg" width="400" border="0" /></a></div>
		<div class="attach">图片附件(缩略图):<br /><a href="http://www.hulihutu.net/attachment.php?id=55" target="_blank"><img height="48" alt="大小: 46.68 K&#xD;尺寸: 400 x 48&#xD;浏览: 2 次&#xD;点击打开新窗口浏览全图" src="http://www.hulihutu.net/attachments/date_200608/thumb_3bada83657186ebb2e6e68dd63340bf4.jpg" width="400" border="0" /></a></div>
<img src ="http://www.blogjava.net/lvlinghui/aggbug/73329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-03 21:10 <a href="http://www.blogjava.net/lvlinghui/articles/73329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用 AppFuse 的七个理由</title><link>http://www.blogjava.net/lvlinghui/articles/73323.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Tue, 03 Oct 2006 12:52:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/73323.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/73323.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/73323.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/73323.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/73323.html</trackback:ping><description><![CDATA[
		<p>AppFuse 是一个开放源码的项目和应用程序，它使用了在 Java 平台上构建的开放源码工具来帮助我们快速而高效地开发 Web 应用程序。我最初开发它是为了减少在为客户构建新 Web 应用程序时所花费的那些不必要的时间。从核心上来说，AppFuse 是一个项目骨架，类似于通过向导创建新 Web 项目时 IDE 所创建的东西。当我们使用 AppFuse 创建一个项目时，它会提示我们将使用开放源码框架，然后才创建项目。它使用 Ant 来驱动测试、代码生成、编译和部署。它提供了目录和包结构，以及开发基于 Java 语言的 Web 应用程序所需要的库。</p>
		<p>与大部分 “new project” 向导不同，AppFuse 创建的项目从最开始就包含很多类和文件。这些文件用来实现特性，不过它们同时也会在您开发应用程序时被用作示例。通过使用 AppFuse 启动新项目，我们通常可以减少一到两周的开发时间。我们不用担心如何将开放源码框架配置在一起，因为这都已经完成了。我们的项目都已提前配置来与数据库进行交互，它会部署到应用服务器上，并对用户进行认证。我们不必实现安全特性，因为这都早已集成了。</p>
		<p>当我最初开发 AppFuse 时，它只支持 Struts 和 Hibernate。经过几年的努力，我发现了比 Struts 更好的 Web 框架，因此我还添加了为这些 Web 框架使用的选项。现在，AppFuse 可以支持 Hibernate 或 iBATIS 作为持久性框架。对于 Web 框架来说，我们可以使用 JavaServer Faces（JSF）、Spring MVC、Struts、Tapestry 或 WebWork。</p>
		<p>AppFuse 提供了很多应用程序需要的一些特性，包括：</p>
		<ul>
				<li>认证和授权 
</li>
				<li>用户管理 
</li>
				<li>Remember Me（这会保存您的登录信息，这样就不用每次都再进行登录了） 
</li>
				<li>密码提醒 
</li>
				<li>登记和注册 
</li>
				<li>SSL 转换 
</li>
				<li>E-mail 
</li>
				<li>URL 重写 
</li>
				<li>皮肤 
</li>
				<li>页面修饰 
</li>
				<li>模板化布局 
</li>
				<li>文件上载 </li>
		</ul>
		<p>这种 “开箱即用” 的功能是 AppFuse 与其他 <em>CRUD 代</em> 框架的区别之一（CRUD 取自<em>创建、检索、更新</em> 和<em>删除</em> 几个操作的英文首字母），包括 Ruby on Rails、Trails 和 Grails。上面提到的这些框架，以及 AppFuse，都让我们可以从数据库表或现有的模型对象中生成主页/细节页。</p>
		<p>图 1 阐述了一个典型 AppFuse 应用程序的概念设计：</p>
		<br />
		<a name="fig1">
				<strong>图 1. 典型的 AppFuse 应用程序</strong>
		</a>
		<br />
		<img height="547" alt="典型的 AppFuse 应用程序" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/appfuse_application.gif" width="572" />
		<br />
		<p>清单 1 给出了我们在创建 <em>devworks</em> 项目时所使用的命令行交互操作，同时还给出了所生成的结果。这个项目使用了 WebWork 作为自己的 Web 框架（请参考下面 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a> 一节给出的链接）。</p>
		<br />
		<a name="listing1">
				<strong>清单 1. 使用 AppFuse 创建新项目</strong>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">alotta:~/dev/appfuse mraible$ ant new
Buildfile: build.xml

clean:
     [echo] Cleaning build and distribution directories

init:

new:
     [echo] 
     [echo] +-------------------------------------------------------------+
     [echo] |    -- Welcome to the AppFuse New Application Wizard! --     |
     [echo] |                                                             |
     [echo] | To create a new application, please answer the following    |
     [echo] | questions.                                                  |
     [echo] +-------------------------------------------------------------+

    [input] What would you like to name your application [myapp]?
devworks
    [input] What would you like to name your database [mydb]?
devworks
    [input] What package name would you like to use [org.appfuse]?
com.ibm
    [input] What web framework would you like to use [webwork,tapestry,spring,js
f,struts]?
webwork
     [echo] Creating new application named 'devworks'...
     [copy] Copying 359 files to /Users/mraible/Work/devworks
     [copy] Copying 181 files to /Users/mraible/Work/devworks/extras
     [copy] Copying 1 file to /Users/mraible/Work/devworks
     [copy] Copying 1 file to /Users/mraible/Work/devworks

install:
     [echo] Copying WebWork JARs to ../../lib
     [copy] Copying 6 files to /Users/mraible/Work/devworks/lib
     [echo] Adding WebWork entries to ../../lib.properties
     [echo] Adding WebWork classpath entries
     [echo] Removing Struts-specific JARs
   [delete] Deleting directory /Users/mraible/Work/devworks/lib/struts-1.2.9
   [delete] Deleting directory /Users/mraible/Work/devworks/lib/strutstest-2.1.3
     [echo] Deleting struts_form.xdt for XDoclet
   [delete] Deleting directory /Users/mraible/Work/devworks/metadata/templates
     [echo] Deleting Struts merge-files in metadata/web
   [delete] Deleting 7 files from /Users/mraible/Work/devworks/metadata/web
     [echo] Deleting unused Tag Libraries and Utilities
   [delete] Deleting 2 files from /Users/mraible/Work/devworks/src/web/org/appfu
se/webapp
     [echo] Modifying appgen for WebWork
     [copy] Copying 12 files to /Users/mraible/Work/devworks/extras/appgen
     [echo] Replacing source and test files
   [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/
webapp/form
   [delete] Deleting directory /Users/mraible/Work/devworks/src/web/org/appfuse/
webapp/action
     [copy] Copying 13 files to /Users/mraible/Work/devworks/src
   [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse
/webapp/form
   [delete] Deleting directory /Users/mraible/Work/devworks/test/web/org/appfuse
/webapp/action
     [copy] Copying 5 files to /Users/mraible/Work/devworks/test
     [echo] Replacing web files (images, scripts, JSPs, etc.)
   [delete] Deleting 1 files from /Users/mraible/Work/devworks/web/scripts
     [copy] Copying 34 files to /Users/mraible/Work/devworks/web
   [delete] Deleting: /Users/mraible/Work/devworks/web/WEB-INF/validator-rules-c
ustom.xml
     [echo] Modifying Eclipse .classpath file
     [echo] Refactoring build.xml
     [echo] ----------------------------------------------
     [echo] NOTE: It's recommended you delete extras/webwork as you shouldn't ne
ed it anymore.
     [echo] ----------------------------------------------
     [echo] Repackaging info written to rename.log
     [echo] 
     [echo] +-------------------------------------------------------------+
     [echo] |           -- Application created successfully! --           |
     [echo] |                                                             |
     [echo] | Now you should be able to cd to your application and run:   |
     [echo] | &gt; ant setup test-all                                        |
     [echo] +-------------------------------------------------------------+

BUILD SUCCESSFUL
Total time: 15 seconds</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidebar1">
																				<strong>为什么使用 WebWork？</strong>
																		</a>
																		<br />Struts 社区最近在热情地拥抱 WebWork，这种结合导致为 Java 平台提供了一个非常优秀的新 Web 框架：Struts 2。当然，Spring MVC 是一个非常优秀的基于请求的框架，但是它不能像 Struts 2 一样支持 JSF。基于内容的框架（例如 JSF 和 Tapestry）也都很好，但是我发现 WebWork 更为直观，更容易使用（更多有关 Structs 2 和 JSF 的内容请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>）。 </td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>在创建一个新项目之后，我们就得到了一个类似于图 2 所示的目录结构。Eclipse 和 Intellij IDEA 项目文件都是作为这个过程的一部分创建的。</p>
		<br />
		<a name="fig2">
				<strong>图 2. 项目的目录结构</strong>
		</a>
		<br />
		<img height="366" alt="项目的目录结构" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/project_directory_structure.jpg" width="173" />
		<br />
		<p>这个目录结构与 Sun 为 Java 2 Platform Enterprise Edition（J2EE）Web 应用程序推荐的目录结构非常类似。在 2.0 版本的 AppFuse 中，这个结构会变化成适合 Apache Maven 项目的标准目录结构（有关这两个目录介绍的内容，请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a> 中的链接）。AppFuse 还会从 Ant 迁移到 Maven 2 上，从而获得相关下载的能力和对生成 IDE 项目文件的支持。目前基于 Ant 的系统要求提交者维护项目文件，而 Maven 2 可以通过简单地使用项目的 pom.xml 文件生成 IDEA、Eclipse 和 NetBeans 项目文件。（这个文件位于您项目的根目录中，是使用 Maven 构建应用程序所需要的主要组件）。它与利用 Ant 所使用的 build.xml 文件非常类似。）</p>
		<p>现在我们对 AppFuse 是什么已经有一点概念了，在本文剩下的部分中，我们将介绍使用 AppFuse 的 7 点理由。即使您选择不使用 AppFuse 来开始自己的项目，也会看到 AppFuse 可以为您提供很多样板代码，这些代码可以在基于 Java 语言的 Web 应用程序中使用。由于它是基于 Apache 许可证的，因此非常欢迎您在自己的应用程序中重用这些代码。</p>
		<p>
				<a name="1">
						<span class="atitle">
								<strong>
										<font size="4">理由 1：测试</font>
								</strong>
						</span>
				</a>
		</p>
		<p>测试是在软件开发项目中很少被给予足够信任的一个环节。注意我并不是说在软件开发的一些刊物中没有得到足够的信任！很多文章和案例研究都给出了测试优先的开发方式和足够的测试覆盖面以提高软件的质量。然而，测试通常都被看作是一件只会延长项目开发时间的事情。实际上，如果我们使用测试优先的方法在编写代码之前就开始撰写测试用例，我相信我们可以发现这实际上会<em>加速</em> 开发速度。另外，测试优先也可以使维护和重用<em>更加</em> 容易。如果我们不编写代码来测试自己的代码，那么就需要手工对应用程序进行测试 —— 这通常效率都不高。自动化才是关键。</p>
		<p>当我们首次开始使用 AppFuse 时，我们可能需要阅读这个项目 Web 站点上提供的快速入门指南和教程（请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a> 中的链接）。这些教程的编写就是为了您可以首先编写测试用例；它们直到编写接口和/或实现之后才能编译。如果您有些方面与我一样，就会在开始编写代码之前就已经编写好测试用例了；这是真正可以加速编写代码的惟一方式。如果您首先编写了代码的实现，通过某种方式验证它可以工作，那么您可能会对自己说，“哦，看起来不错 —— 谁需要测试呢？我还有更多的代码需要编写！”这种情况不幸的一面是您通常都会做<em>一些事情</em> 来测试自己的代码；您简单地跳过了可以自动化进行测试的地方。</p>
		<p>AppFuse 的文档展示了如何测试应用程序的<em>所有</em> 层次。它从数据库层开始入手，使用了 DbUnit（请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>）在运行测试之前提前使用数据来填充自己的数据库。在数据访问（DAO）层，它使用了 Spring 的 <code><font face="Courier" size="2">AbstractTransactionalDataSourceSpringContextTests</font></code> 类（是的，这的确是一个类的名字！）来允许简单地加载 Spring 上下文文件。另外，这个类对每个 <code><font face="Courier" size="2">testXXX()</font></code> 方法封装了一个事务，并当测试方法存在时进行回滚。这种特性使得测试 DAO 逻辑变得非常简单，并且不会对数据库中的数据造成影响。</p>
		<p>在服务层，jMock （请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>）用来编写那些可以消除 DAO 依赖的<em>真正</em> 单元测试。这允许进行验证业务逻辑正确的快速测试；我们不用担心底层的持久性逻辑。</p>
		<table cellspacing="0" cellpadding="0" width="40%" align="right" border="0">
				<tbody>
						<tr>
								<td width="10">
										<img height="1" alt="" src="http://www.ibm.com/i/c.gif" width="10" />
								</td>
								<td>
										<table cellspacing="0" cellpadding="5" width="100%" border="1">
												<tbody>
														<tr>
																<td bgcolor="#eeeeee">
																		<a name="sidebar2">
																				<strong>HtmlUnit 支持</strong>
																		</a>
																		<br />HtmlUnit 团队在 1.8 发行版中已经完成了相当多的工作来确保包可以与流行的 Ajax 框架（Prototype 和 Scriptaculous）很好地工作。 </td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<p>在 Web 层，测试会验证操作（Struts/WebWork）、控件（Spring MVC）、页面（Tapestry）和管理 bean（JSF）如我们所期望的一样进行工作。Spring 的 spring-mock.jar 可以非常有用地用来测试所有这些框架，因为它包含了一个 Servlet API 的仿真实现。如果没有这个有用的库，那么测试 AppFuse 的 Web 框架就会变得非常困难。</p>
		<p>UI 通常是开发 Web 应用程序过程中最为困难的一部分。它也是顾客最经常抱怨的地方 —— 这既是由于它并不是非常完美，也是由于它的工作方式与我们期望的并不一样。另外，没有什么会比在客户面前作演示的过程中看到看到异常堆栈更糟糕的了！您的应用程序可能会非常可怕，但是客户可能会要求您做到十分完美。永远不要让这种事情发生。Canoo WebTest 可以对 UI 进行测试。它使用了 HtmlUnit 来遍历测试 UI，验证所有的元素都存在，并可以填充表单的域，甚至可以验证一个假想的启用 Ajax 的 UI 与我们预期的工作方式一样。（有关 WebTest 和 HTMLUnit 的链接请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>。）</p>
		<p>为了进一步简化 Web 的测试，Cargo（请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>）对 Tomcat 的启动和停止（分别在运行 WebTest 测试之前和之后）进行了自动化。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="2">
						<span class="atitle">
								<strong>
										<font size="4">理由 2：集成</font>
								</strong>
						</span>
				</a>
		</p>
		<p>正如我在本文简介中提到的一样，很多开放源码库都已经预先集成到 AppFuse 中了。它们可以分为以下几类： </p>
		<ul>
				<li>
						<strong>编译、报告和代码生成：</strong>Ant、Ant Contrib Tasks、Checkstyle、EMMA、Java2Html、PMD 和 Rename Packages 
</li>
				<li>
						<strong>测试框架：</strong>DbUnit、Dumbster、jMock、JUnit 和 Canoo WebTest 
</li>
				<li>
						<strong>数据库驱动程序：</strong>MySQL 和 PostgreSQL 
</li>
				<li>
						<strong>持久性框架：</strong>Hibernate 和 iBATIS 
</li>
				<li>
						<strong>IoC 框架：</strong>Spring 
</li>
				<li>
						<strong>Web 框架：</strong>JSF、Spring MVC、Struts、Tapestry 和 WebWork 
</li>
				<li>
						<strong>Web 服务：</strong>XFire 
</li>
				<li>
						<strong>Web 工具：</strong>Clickstream、Display Tag、DWR、JSTL、SiteMesh、Struts Menu 和 URL Rewrite Filter 
</li>
				<li>
						<strong>Security：</strong>Acegi Security 
</li>
				<li>
						<strong>JavaScript 和 CSS：</strong>Scriptaculous、Prototype 和 Mike Stenhouse 的 CSS Framework </li>
		</ul>
		<p>除了这些库之外，AppFuse 还使用 Log4j 来记录日志，使用 Velocity 来构建 e-mail 和菜单模板。Tomcat 可以支持最新的开发，我们可以使用 1.4 或 5 版本的 Java 平台来编译或构建程序。我们应该可以将 AppFuse 部署到任何 J2EE 1.3 兼容的应用服务器上；这已经经过了测试，我们知道它在所有主要版本的 J2EE 服务器和所有主要的 servlet 容器上都可以很好地工作。</p>
		<p>图 3 给出了上面创建的 <em>devworks</em> 项目的 lib 目录。这个目录中的 lib.properties 文件控制了每个依赖性的版本号，这意味着我们可以简单地通过把这些包的新版本放到这个目录中并执行诸如 <code><font face="Courier" size="2">ant test-all -Dspring.version=2.0</font></code> 之类的命令来测试这些包的新版本。</p>
		<br />
		<a name="fig3">
				<strong>图 3. 项目依赖性</strong>
		</a>
		<br />
		<img height="598" alt="AppFuse 项目依赖性" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/project_lib_directory.jpg" width="197" />
		<br />
		<p>预先集成这些开放源码库可以在项目之初极大地提高生产效率。尽管我们可以找到很多文档介绍如何集成这些库，但是定制工作示例并简单地使用它来开发应用程序要更加简单。</p>
		<p>除了可以简化 Web 应用程序的开发之外，AppFuse 让我们还可以将 Web 服务简单地集成到自己的项目中。尽管 XFire 也在 AppFuse 下载中一起提供了，不过如果我们希望，也可以自己集成 Apache Axis（请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a> 中有关 Axis 集成的教程）。另外，Spring 框架和 XFire 可以一起将服务层作为 Web 服务非常简单地呈现出来，这就为我们提供了开发面向服务架构的能力。</p>
		<p>另外，AppFuse 并不会将我们限定到任何特定的 API 上。它只是简单地对可用的最佳开放源码解决方案重新进行打包和预先集成。AppFuse 中的代码可以处理这种集成，并实现了 AppFuse 的基本安全性和可用性特性。只要可能，就会减少代码，以便向 AppFuse 的依赖框架添加一个特性。例如，AppFuse 自带的 Remember Me 和 SSL 切换特性最近就因为类似的特性而从 Acegi Security 中删除了。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="3">
						<span class="atitle">
								<strong>
										<font size="4">理由 3：自动化</font>
								</strong>
						</span>
				</a>
		</p>
		<p>Ant 使得简化了从编译到构建再到部署的自动化过程。Ant 是 AppFuse 中的一等公民，这主要是因为我发现在命令行中执行操作比从 IDE 中更加简单。我们可以使用 Ant 实现编译、测试、部署和执行任何代码生成的任务。</p>
		<p>尽管这种能力对于有些人来说非常重要，但是它并不适用于所有的人。很多 AppFuse 用户目前都使用 Eclipse 或 Intellij IDEA 来构建和测试自己的项目。在这些 IDE 中运行 Ant 的确可以工作，但是这样做的效率通常都不如使用 IDE 内置的 JUnit 支持来运行测试效率高。</p>
		<p>幸运的是，AppFuse 支持在 IDE 中运行测试，不过管理这种特性对于 AppFuse 开发人员来说就变得非常困难了。最大的痛苦在于 XDoclet 用来生成 Hibernate 映射文件和 Web 框架所使用的一些工件（例如 ActionForms 和 Struts 使用的 struts-config.xml）。IDE 并不知道需要生成的代码，除非我们配置使用 Ant 来编译它们，或者安装了一些可以认识 XDoclet 的插件。</p>
		<p>这种对知识的缺乏是 AppFuse 2.0 切换到 JDK 5 和 Maven 2 上的主要原因。JDK 5、注释和 Struts 2 将让我们可以摆脱 XDoclet。Maven 2 将使用这些生成的文件和动态类路径来生成 IDE 项目文件，这样对项目的管理就可以进行简化。目前基于 Ant 的编译系统已经为不同的层次生成了一些工件（包括 dao.jar、service.jar 和 webapp.war），因此切换到 Maven 的模型上应该是一个非常自然的调整。</p>
		<p>除了 Ant 之外（它对于编译、测试、部署和报告具有丰富的支持），对于 CruiseControl 的支持也构建到了 AppFuse 中。CruiseControl 是一个 Continuous Integration 应用程序，让我们可以在源代码仓库中代码发生变化时自动运行所有的测试。extras/cruisecontrol 目录包含了我们为基于 AppFuse 的项目快速、简单地设置 Continuous Integration 时所需要的文件。</p>
		<p>设置 Continuous Integration 是软件开发周期中我们首先要做的事情之一。它不但激发程序员去编写测试用例，而且还通过 “You broke the build!” 游戏促进了团队之间的合作和融合。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="4">
						<span class="atitle">
								<strong>
										<font size="4">理由 4：安全特性和可扩展性</font>
								</strong>
						</span>
				</a>
		</p>
		<p>AppFuse 最初是作为我为 Apress 编写的书籍 <em>Pro JSP</em> 中示例应用程序的一部分开发的。这个示例应用程序展示了很多安全特性和用于简化 Struts 开发的特性。这个应用程序中的很多安全特性在 J2EE 的安全框图中都不存在。使用容器管理认证（CMA）的认证方法非常简单，但是 Remember Me、密码提示、SSL 切换、登记和用户管理等功能却都不存在。另外，基于角色的保护方法功能在非 EJB 环境中也是不可能的。</p>
		<p>最初，AppFuse 使用自己的代码和用于 CMA 的解决方案完全实现了这些特性。我在 2004 年年初开始学习 Spring 时就听说过有关 Acegi Security 的知识。我对 Acegi 所需要的 XML 的行数（175）与 web.xml 中所需要的 CMA 的行数（20）进行了比较，很快就决定丢弃 Acegi 了，因为它太过复杂了。</p>
		<p>一年半之后 —— 在为另外一本书 <em>Spring Live</em> 中编写了一章有关使用 Acegi Security 的内容之后 —— 我就改变了自己的想法。Acegi <em>的确</em>（目前仍然）需要很多 XML，但是一旦我们理解了这一点，它实际上是相当简单的。当我们最终作出改变，使用 Acegi Security 的特性来全部取代 AppFuse 的特性之后，我们最终删除了大量的代码。类之上的类都已经没有了，“Acegi handles that now” 中消失的部分现在全部进入了 CVS 的 Attic 中了。</p>
		<p>Acegi Security 是 J2EE 安全模型中曾经出现过的最好模型。它让我们可以实现很多有用的特性，这些特性在 Servlet API 的安全模型中都不存在：认证、授权、角色保护方法、Remember Me、密码加密、SSL 切换、用户切换和注销。它让我们还可以将用户证书存储到 XML 文件、数据库、LDAP 或单点登录系统（例如 Yale 的 Central Authentication Service (CAS) 或者 SiteMinder）中。</p>
		<p>AppFuse 对很多与安全性相关的特性的实现从一开始都是非常优秀的。现在 AppFuse 使用了 Acegi Security，这些特性 —— 以及更多特性 —— 都非常容易实现。Acegi 有很多地方都可以进行扩充：这是它使用巨大的 XML 配置文件的原因。正如我们已经通过去年的课程对 Acegi 进行集成一样，我们已经发现对很多 bean 的定义进行定制可以更加紧密地与 AppFuse 建立联系。</p>
		<p>Spring IoC 容器和 Acegi Security 所提供的简单开发、容易测试的代码和松耦合特性的组合是 AppFuse 是这么好的一种开发平台的主要原因。这些框架都是不可插入的，允许生成干净的可测试代码。AppFuse 集成了很多开放源码项目，依赖注入允许对应用程序层进行简单的集成。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="5">
						<span class="atitle">
								<strong>
										<font size="4">理由 5：使用 AppGen 生成代码</font>
								</strong>
						</span>
				</a>
		</p>
		<p>有些人会将代码生成称为<em>代码气味的散播（code smell）</em>。在他们的观点中，如果我们需要生成代码，那么很可能就会做一些错事。我倾向于这种确定自己代码使用的模式和自动化生成代码的能力应该称为<em>代码香味的弥漫（code perfume）</em>。如果我们正在编写类似的 DAO、管理器、操作或控件，并且不想为它们生成代码，那么这就需要根据代码的气味来生成代码。当然，当语言可以为我们提供可以简化任务的特性时，一切都是那么美好；不过代码生成通常都是一个必需 —— 通常其生产率也非常高 —— 的任务。</p>
		<p>AppFuse 中提供了一个基于 Ant 和 XDoclet 的代码生成工具，名叫 <em>AppGen</em>。默认情况下，常见的 DAO 和管理器都可以允许我们对任何普通老式 Java 对象（POJO）进行 CRUD 操作，但是在 Web 层上这样做有些困难。AppGen 有几个特性可以用来执行以下任务：</p>
		<ul>
				<li>（使用 Middlegen 和 Hibernate 工具）从数据库表中生成 POJO 
</li>
				<li>从 POJO 生成 UI 
</li>
				<li>为 DAO、管理器、操作/控制器和 UI 生成测试 </li>
		</ul>
		<p>在运行 AppGen 时，您会看到提示说 AppGen 要从数据库表或 POJO 中生成代码。如果在命令行中执行 <code><font face="Courier" size="2">ant install-detailed</font></code>，AppGen 就会安装 POJO 特定的 DAO、管理器以及它们的测试。运行 <code><font face="Courier" size="2">ant install</font></code> 会导致 Web 层的类重用通用的 DAO 和默认存在的管理器。</p>
		<p>为了阐述 AppGen 是如何工作的，我们在 <em>devworks</em> MySQL 数据库中创建了如清单 2 所示的表：</p>
		<br />
		<a name="listing2">
				<strong>清单 2. 创建一个名为 cat 的数据库表</strong>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">    create table cat (
      cat_id int(8) auto_increment,
      color varchar(20) not null,
      name varchar(20) not null,
      created_date datetime not null,
      primary key (cat_id)
    ) type=InnoDB;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在 extras/appgen 目录中，运行 <code><font face="Courier" size="2">ant install-detailed</font></code>。这个命令的输出结果对于本文来说实在太长了，不过我们在清单 3 中给出了第一部分的内容：</p>
		<br />
		<a name="listing3">
				<strong>清单 3. 运行 AppGen 的 install-detailed 目标</strong>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">$ ant install-detailed
Buildfile: build.xml

init:
    [mkdir] Created dir: /Users/mraible/Work/devworks/extras/appgen/build
     [echo] 
     [echo] +-------------------------------------------------------+
     [echo] |             -- Welcome to the AppGen! --              |
     [echo] |                                                       |
     [echo] | Use the "install" target to use the generic DAO and   |
     [echo] | Manager, or use "install-detailed" to general a DAO   |
     [echo] | and Manager specifically for your model object.       |
     [echo] +-------------------------------------------------------+

    [input] Would you like to generate code from a table or POJO? (table,pojo)
table
    [input] What is the name of your table (i.e. person)?
cat
    [input] What is the name, if any, of the module for your table (i.e. organization)?

     [echo] Running Middlegen to generate POJO...
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>要对 cat 表使用这个新生成的代码，我们需要修改 src/dao/com/ibm/dao/hibernate/applicationContext-hibernate.xml，来为 Hibernate 添加 Cat.hbm.xml 映射文件。清单 3 给出了我们修改后的 <code><font face="Courier" size="2">sessionFactory</font></code> bean 的样子：</p>
		<br />
		<a name="listing4">
				<strong>清单 4. 将 Cat.hbm.xml 添加到 sessionFactory bean 中</strong>
		</a>
		<br />
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">    &lt;bean id="sessionFactory" class="..."&gt;
    &lt;property name="dataSource" ref="dataSource"/&gt;
    &lt;property name="mappingResources"&gt;
        &lt;list&gt;
            &lt;value&gt;com/ibm/model/Role.hbm.xml&lt;/value&gt;
            &lt;value&gt;com/ibm/model/User.hbm.xml&lt;/value&gt;
            &lt;value&gt;com/ibm/model/Cat.hbm.xml&lt;/value&gt;
        &lt;/list&gt;
    &lt;/property&gt;
    ...
&lt;/bean&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在运行 <code><font face="Courier" size="2">ant setup deploy</font></code> 之后，我们就应该可以在部署的应用程序中对 cat 表执行 CRUD 操作了：</p>
		<br />
		<a name="fig4">
				<strong>图 4. Cat 列表</strong>
		</a>
		<br />
		<img height="379" alt="所生成的主屏幕" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/cat_list.jpg" width="572" />
		<br />
		<br />
		<a name="fig5">
				<strong>图 5. Cat 表单</strong>
		</a>
		<br />
		<img height="379" alt="所生成的详细屏幕" src="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/cat_detail.jpg" width="572" />
		<br />
		<p>我们在上面的屏幕快照中看到的记录都是作为代码生成的一部分创建的，因此现在就有测试数据了。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="6">
						<span class="atitle">
								<strong>
										<font size="4">理由 6：文档</font>
								</strong>
						</span>
				</a>
		</p>
		<p>我们可以找到 AppFuse 各个风味的教程，并且它们都以 6 种不同的语言给出了：中文、德语、英语、韩语、葡萄牙语和西班牙语。使用<em>风味（flavor）</em> 一词，我的意思是不同框架的组合，例如 Spring MVC 加上 iBATIS、Spring MVC 加上 Hibernate 或 JSF 加上 Hibernate。使用这 5 种 Web 框架和两种持久框架，可以有好几种组合。有关它们的翻译，AppFuse 为自己的默认特性提供了 8 种翻译。可用语言包括中文、荷兰语、德语、英语、法语、意大利语、葡萄牙语和西班牙语。</p>
		<p>除了核心教程之外，还添加了很多教程（请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>） 来介绍与各种数据库、应用服务器和其他开放源码技术（包括 JasperReports、Lucene、Eclipse、Drools、Axis 和 DWR）的集成。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="7">
						<span class="atitle">
								<strong>
										<font size="4">理由 7：社区</font>
								</strong>
						</span>
				</a>
		</p>
		<p>Apache 软件基金会对于开放源码有一个有趣的看法。它对围绕开放源码项目开发一个开放源码社区最感兴趣。它的成员相信如果社区非常强大，那么产生高质量的代码就是一个自然的过程。下面的内容引自 Apache 主页：</p>
		<blockquote>“我们认为自己不仅仅是一组共享服务器的项目，而且是一个开发人员和用户的社区。” </blockquote>
		<p>AppFuse 社区从 2003 年作为 SourceForge 上的一个项目（是 struts.sf.net 的一部分）启动以来，已经获得了极大的增长。通过在 2004 年 3 月转换到 java.net 上之后，它已经成为这里一个非常流行的项目，从 2005 年 1 月到 3 月成为访问量最多的一个项目。目前它仍然是一个非常流行的项目（有关 java.net 项目统计信息的链接，请参看 <a href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#resources"><font color="#996699">参考资料</font></a>），不过在这个站点上它正在让位于 Sun 赞助的很多项目。</p>
		<p>在 2004 年年末，Nathan Anderson 成为继我之后第一个提交者。此后有很多人都加入了进来，包括 Ben Gill、David Carter、Mika G?ckel、Sanjiv Jivan 和 Thomas Gaudin。很多现有的提交者都已经通过各种方式作出了自己的贡献，他们都帮助 AppFuse 社区成为一个迅速变化并且非常有趣的地方。</p>
		<p>邮件列表非常友好，我们试图维护这样一条承诺 “没有问题是没有人理会的问题”。我们的邮件列表归档文件中惟一一条 “RTFM” 是从用户那里发出的，而不是从开发者那里发出的。我们绝对信奉 Apache 开放源码社区的哲学。引用我最好的朋友 Bruce Snyder 的一句话，“我们为代码而来，为人们而留下”。目前，大部分开发者都是用户，我们通常都喜欢有一段美妙的时间。另外，大部分文档都是由社区编写的；因此，这个社区的知识是非常渊博的。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="8">
						<span class="atitle">
								<strong>
										<font size="4">结束语</font>
								</strong>
						</span>
				</a>
		</p>
		<p>我们应该尝试使用 AppFuse 进行开发，这是因为它允许我们简单地进行测试、集成、自动化，并可以安全地生成 Web 应用程序。其文档非常丰富，社区也非常友好。随着其支撑框架越来越好，AppFuse 也将不断改进。</p>
		<p>从 AppFuse 2.0 开始，我们计划迁移到 JDK 5（仍然支持部署到 1.4）和 Maven 2 上去。这些工具可以简化使用 AppFuse 的开发、安装和升级。我们计划充分利用 Maven 2 的功能来处理相关依赖性。我们将碰到诸如 appfuse-hibernate-2.0.jar 和 appfuse-jsf-2.0.jar 之类的工件。这些工件都可以在 pom.xml 文件中进行引用，它们负责提取其他相关依赖性。除了在自己的项目中使用 AppFuse 基类之外，我们还可以像普通的框架一样在 JAR 中对这些类简单地进行扩展，这应该会大大简化它的升级过程，并鼓励更多用户将自己希望的改进提交到这个项目中。</p>
		<p>如果没有其他问题，使用 AppFuse 可以让您始终处于 Java Web 开发的技术前沿上 —— 就像我们一样！</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-appfuse/index.html#main">
																				<strong>
																						<font face="Verdana" color="#996699">回页首</font>
																				</strong>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="resources">
						<span class="atitle">
								<strong>
										<font size="4">参考资料 </font>
								</strong>
						</span>
				</a>
		</p>
		<strong>学习</strong>
		<br />
		<ul>
				<li>您可以参阅本文在 developerWorks 全球站点上的 <a href="http://www.ibm.com/developerworks/java/library/j-appfuse/index.html?S_TACT=105AGX52&amp;S_CMP=cn-a-j" target="_blank"><font color="#5c81a7">英文原文</font></a> 。<br /><br /></li>
				<li>
						<a href="http://appfuse.org/">
								<font color="#5c81a7">AppFuse</font>
						</a>：该项目的主页。 <br /><br /></li>
				<li>
						<a href="http://appfuse.org/demos.html">
								<font color="#5c81a7">AppFuse Demos</font>
						</a>：查看演示和视频。 <br /><br /></li>
				<li>
						<a href="http://jroller.com/page/mrdon?entry=unification_struts_action_and_jsf">
								<font color="#996699">Struts 2 和 JSF</font>
						</a>：了解为什么要将这些技术放到一起工作。 <br /><br /></li>
				<li>
						<a href="http://java.sun.com/blueprints/code/projectconventions.html">
								<font color="#5c81a7">Sun 的 J2EE 项目目录结构指南</font>
						</a>：AppFuse 非常接近于这些指南。 <br /><br /></li>
				<li>
						<a href="http://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html">
								<font color="#5c81a7">Maven 的 Standard Directory Layout</font>
						</a>：AppFuse 2.0 将转换到这个目录结构上。 <br /><br /></li>
				<li>
						<a href="http://appfuse.org/wiki/QuickStart.html">
								<font color="#5c81a7">AppFuse 快速入门指南</font>
						</a>：快速入门并使用 AppFuse。 <br /><br /></li>
				<li>
						<a href="http://appfuse.org/wiki/Articles.html">
								<font color="#5c81a7">AppFuse 教程</font>
						</a>：深入学习更多有关使用 AppFuse 的知识。 <br /><br /></li>
				<li>
						<a href="http://raibledesigns.com/wiki/AppFuseAxis.html">
								<font color="#5c81a7">Apache Axis 集成</font>
						</a>：如何将 Apache Axis 集成到自己的 AppFuse 项目中。 <br /><br /></li>
				<li>Java.net 项目状态：请查看 2005 年 <a href="http://community.java.net/projects/toparchive.csp?year=2005&amp;month=January"><font color="#5c81a7">1 月</font></a>、<a href="http://community.java.net/projects/toparchive.csp?year=2005&amp;month=February"><font color="#5c81a7">2 月</font></a> 和 <a href="http://community.java.net/projects/toparchive.csp?year=2005&amp;month=March"><font color="#5c81a7">3 月</font></a> 的动态。还可以查看 <a href="http://community.java.net/projects/top.csp"><font color="#5c81a7">java.net 上的最佳项目 </font></a>。 <br /><br /></li>
		</ul>
		<br />
		<strong>获得产品和技术</strong>
		<br />
		<ul>
				<li>
						<a href="https://appfuse.dev.java.net/servlets/ProjectDocumentList">
								<font color="#5c81a7">AppFuse on java.net</font>
						</a>：下载不同风味的 AppFuse。 <br /><br /></li>
				<li>
						<a href="http://opensymphony.com/webwork">
								<font color="#5c81a7">WebWork</font>
						</a>：了解这个易于使用的 Web 框架。 <br /><br /></li>
				<li>
						<a href="http://www.dbunit.org/">
								<font color="#5c81a7">DbUnit</font>
						</a>：查看更多有关 JUnit 扩展的内容。 <br /><br /></li>
				<li>
						<a href="http://www.jmock.org/">
								<font color="#5c81a7">jMock</font>
						</a>：创建动态仿真对象来简化真正的单元测试。 <br /><br /></li>
				<li>
						<a href="http://webtest.canoo.com/">
								<font color="#5c81a7">Canoo WebTest</font>
						</a>：自动化 Web 应用程序的 UI 测试。 <br /><br /></li>
				<li>
						<a href="http://htmlunit.sf.net/">
								<font color="#5c81a7">HtmlUnit</font>
						</a>：WebTest 的优秀 JavaScript 支持背后的基础。 <br /><br /></li>
				<li>
						<a href="http://cargo.codehaus.org/">
								<font color="#5c81a7">Cargo</font>
						</a>：自动启动和停止容器。 <br /><br /></li>
				<li>
						<a href="http://greenbox.dev.java.net/">
								<font color="#5c81a7">Greenbox</font>
						</a>：一种代码生成框架。 <br /><br /></li>
		</ul>
		<br />
		<strong>讨论</strong>
		<br />
		<ul>
				<li>
						<a href="http://www.nabble.com/AppFuse-f2369.html">
								<font color="#5c81a7">AppFuse 论坛</font>
						</a>：与同行开发人员交流技巧。 </li>
		</ul>
		<p>Matt Raible 居住在美国科罗拉多州的丹佛，他在那里是 Spring 和 Web 框架对 <a href="http://virtuas.com/"><font color="#5c81a7">Virtuas Open Source Solutions</font></a> 的实践先驱。他在开放源码领域具有丰富的经验，是这个领域的专家。他在这个领域中既是用户，又是一名开发人员。Matt 是 <a href="http://sourcebeat.com/"><font color="#5c81a7">SourceBeat Publishing</font></a> 上 <em><a href="http://springlive.com/"><font color="#5c81a7">Spring Live</font></a></em> 的作者。他还为 Apress 的书籍 <em><a href="http://www.apress.com/book/bookDisplay.html?bID=256"><font color="#5c81a7">Pro JSP Third Edition</font></a></em> 作出了很大的贡献。他是很多开放源码会议的积极倡导者，包括 ApacheCon、MySQL User's Conference 和 OSCON，同时他还是 <a href="http://raibledesigns.com/"><font color="#5c81a7">http://raibledesigns.com</font></a> 上一名非常活跃的博客。Raible 的大部分生活都被计算机所包围了，尽管他是在连电都没有的 Montana 长大的。当不工作的时候时，他总是试图让妻子 Julie 成为世界上最幸福的女人，或者与他们的孩子 Abbie 和 Jack 一起玩耍。</p>
<img src ="http://www.blogjava.net/lvlinghui/aggbug/73323.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-03 20:52 <a href="http://www.blogjava.net/lvlinghui/articles/73323.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Spring、Hibernate、Struts的一些错误总结</title><link>http://www.blogjava.net/lvlinghui/articles/73321.html</link><dc:creator>马尔代夫</dc:creator><author>马尔代夫</author><pubDate>Tue, 03 Oct 2006 12:23:00 GMT</pubDate><guid>http://www.blogjava.net/lvlinghui/articles/73321.html</guid><wfw:comment>http://www.blogjava.net/lvlinghui/comments/73321.html</wfw:comment><comments>http://www.blogjava.net/lvlinghui/articles/73321.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lvlinghui/comments/commentRss/73321.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lvlinghui/services/trackbacks/73321.html</trackback:ping><description><![CDATA[
		<p>
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">
						<font color="#000000">
								<font size="1">本文系转载，原作者：</font>
								<a href="/crazycy/archive/2006/07/07/57214.html">
										<font size="1">http://www.blogjava.net/crazycy/archive/2006/07/07/57214.html</font>
								</a>
						</font>
				</span>
		</p>
		<p>
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">1.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span>
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">错误：</span>
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">java.lang.NullPointerException</span>
		</p>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">原因：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">发现</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">dao</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">实例、</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">manage</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">实例等需要注入的东西没有被注入</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">解决：这个时候，你应该查看日志文件；默认是应用服务器的</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">log</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">文件，比如</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">Tomcat</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">就是</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">[Tomcat</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">安装目录</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">]/logs</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">；你会发现提示你：</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: red; LINE-HEIGHT: 150%">可能是：</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sf' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is org.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xml</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">org.hibernate.HibernateException: could not configure from URL: file:src/hibernate.cfg.xml</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">……………………….</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">Caused by: java.io.FileNotFoundException: src\hibernate.cfg.xml</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: red; LINE-HEIGHT: 150%">可能是：</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Initialization of bean failed; nested exception is org.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not found</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">org.hibernate.MappingException: Resource: com/mcc/coupon/model/UserRole.hbm.xml not found</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">然后你就知道原因是因为配置文件的解析出了错误，这个通过</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">Web</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">页面是看不出来的。</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">更多的是持久化影射文件出的错误；导致了没有被解析；当然你需要的功能就无法使用了。</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"> </div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"> </div>
		<div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%"> <span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">2.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">错误：</span></div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">StandardWrapperValve[action]: Servlet.service() for servlet action threw exception<br />javax.servlet.jsp.JspException: Cannot retrieve mapping for action /settlementTypeManage</span>
				<br />
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">或者：</span>
		</div>
		<div>
				<strong>    type</strong> Status report</div>
		<div>
				<strong>    message</strong>
				<u>Servlet action is not available</u>
		</div>
		<div>
				<strong>    description</strong>
				<u>The requested resource (Servlet action is not available) is not available.</u>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">
						<br />原因：</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">同</span>
				<span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">1</span>
		</div>
		<div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"> </div>
		<div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">3.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span>
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">错误</span>
		</div>
		<div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception</span>
		</div>
		<div style="LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">java.lang.ClassNotFoundException: org.apache.struts.taglib.bean.CookieTei</span>
		</div>
		<pre>界面错误具体描述：<br />org.apache.jasper.JasperException: Failed to load or instantiate TagExtraInfo class: org.apache.struts.taglib.bean.CookieTei</pre>
		<div style="LINE-HEIGHT: 150%">
				<br />
		</div>
		<div style="LINE-HEIGHT: 150%">
				<span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">    原因与解决：</span>
		</div>
		<div style="LINE-HEIGHT: 150%">  <span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">&lt;</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方案一</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">&gt;</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">你的“</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">html:</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">”开头的标签没有放在一个</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">&lt;html:form&gt;</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">中</span></div>     <span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">&lt;</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方案</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">二</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">&gt;</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">重新启动你的应用服务器，自动就没有这个问题了<br /><br /><br /></span><div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">4.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">错误：</span></div><div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">Exception in thread "main" org.hibernate.exception.SQLGrammarException: Could not execute JDBC batch update</span></div><div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">原因与解决：</span></div><span style="FONT-SIZE: 10pt; COLOR: black">    因为</span><span style="FONT-SIZE: 10pt; COLOR: black">Hibernate Tools</span><span style="FONT-SIZE: 10pt; COLOR: black">（或者</span><span style="FONT-SIZE: 10pt; COLOR: black">Eclipse</span><span style="FONT-SIZE: 10pt; COLOR: black">本身的</span><span style="FONT-SIZE: 10pt; COLOR: black">Database Explorer</span><span style="FONT-SIZE: 10pt; COLOR: black">）生成</span><span style="FONT-SIZE: 10pt; COLOR: black">*.hbn.xml</span><span style="FONT-SIZE: 10pt; COLOR: black">工具中包含有</span><span style="FONT-SIZE: 10pt; COLOR: black">catalog="***"</span><span style="FONT-SIZE: 10pt; COLOR: black">（</span><span style="FONT-SIZE: 10pt; COLOR: black">*表示数据库</span><span style="FONT-SIZE: 10pt; COLOR: black">名称）这样的属性,将该属性删除就可以了<br /><br /><br /><br /><br /></span><div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">5.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">错误：</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations)</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">原因与</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">解决：</span><br /><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方法</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">1 </span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">删除</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">Set</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方的</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">cascade<br /></span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方法</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">2 </span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">解决关联关系后，再删除</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%"><br /></span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方法</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">3 </span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">在</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">many-to-one</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">方增加</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">cascade </span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">但值不能是</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">none</span><br /><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">最后一招：<br />检查一下</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">hashCode equals</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">是否使用了</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">id</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">作为唯一标示的选项了；我用</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">uuid.hex</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">时是没有问题的；但是用了</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">native</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">，就不行了，怎么办？删除啊！</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">这个错误可以参见我的blog文章：</span><br /><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%"><a href="/crazycy/archive/2006/06/24/54939.html">http://www.blogjava.net/crazycy/archive/2006/06/24/54939.html</a></span></div><div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">6.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">错误：</span></div><div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%"><strong>exception</strong> javax.servlet.ServletException: BeanUtils.populat</div><div style="TEXT-INDENT: 24.1pt"><strong>root cause</strong></div><div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%">java.lang.IllegalArgumentException:Cannot invoke ***Form.set*** - argument type mismatch</div><div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">原因</span></div><div><span style="FONT-SIZE: 10pt; COLOR: black">      </span><span style="FONT-SIZE: 10pt; COLOR: black">这个问题很奇怪的说，为啥说奇怪呢？</span></div><div><span style="FONT-SIZE: 10pt; COLOR: black">      </span><span style="FONT-SIZE: 10pt; COLOR: black">先说问题的原因：问题发生如下两种情况：</span></div><div style="MARGIN-LEFT: 42pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 10pt; COLOR: black"><img height="11" alt="*" src="file:///C:/DOCUME%7E1/crazycy/LOCALS%7E1/Temp/msohtml1/01/clip_image001.gif" width="11" /><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">         </span></span><span style="FONT-SIZE: 10pt; COLOR: black">Form</span><span style="FONT-SIZE: 10pt; COLOR: black">中是</span><span style="FONT-SIZE: 10pt; COLOR: black">Date</span><span style="FONT-SIZE: 10pt; COLOR: black">类型</span></div><div style="MARGIN-LEFT: 42pt; TEXT-INDENT: -21pt"><span style="FONT-SIZE: 10pt; COLOR: black"><img height="11" alt="*" src="file:///C:/DOCUME%7E1/crazycy/LOCALS%7E1/Temp/msohtml1/01/clip_image001.gif" width="11" /><span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">         </span></span><span style="FONT-SIZE: 10pt; COLOR: black">上传文件时</span></div><div style="MARGIN-LEFT: 21pt"><span style="FONT-SIZE: 10pt; COLOR: black">为什么说奇怪呢？主要针对</span><span style="FONT-SIZE: 10pt; COLOR: black">Form</span><span style="FONT-SIZE: 10pt; COLOR: black">是日期型的来说的；因为我做过</span><span style="FONT-SIZE: 10pt; COLOR: black">N</span><span style="FONT-SIZE: 10pt; COLOR: black">多系统</span><span style="FONT-SIZE: 10pt; COLOR: black">Form</span><span style="FONT-SIZE: 10pt; COLOR: black">中都是用</span><span style="FONT-SIZE: 10pt; COLOR: black">java.util.Date</span><span style="FONT-SIZE: 10pt; COLOR: black">，界面使用</span><span style="FONT-SIZE: 10pt; COLOR: black">&lt;html:text property=”date”/&gt;;</span><span style="FONT-SIZE: 10pt; COLOR: black">都是没有问题的。所以第一次遇到这个错误时，捣鼓了一个下午。</span></div><div style="TEXT-INDENT: 18pt"><span style="FONT-SIZE: 10pt; COLOR: blue">解决：</span></div><div style="TEXT-INDENT: 18pt"><span style="FONT-SIZE: 10pt; COLOR: black">第一个问题：你把</span><span style="FONT-SIZE: 10pt; COLOR: black">Date</span><span style="FONT-SIZE: 10pt; COLOR: black">换成</span><span style="FONT-SIZE: 10pt; COLOR: black">String</span><span style="FONT-SIZE: 10pt; COLOR: black">；在</span><span style="FONT-SIZE: 10pt; COLOR: black">Action</span><span style="FONT-SIZE: 10pt; COLOR: black">中进行转换；当然转换要借助于</span><span style="FONT-SIZE: 10pt; COLOR: black">SimpleDateFormate</span><span style="FONT-SIZE: 10pt; COLOR: black">方法喽</span></div><div style="TEXT-INDENT: 18pt"><span style="FONT-SIZE: 10pt; COLOR: black">第二个问题：记得在</span><span style="FONT-SIZE: 10pt; COLOR: black">form</span><span style="FONT-SIZE: 10pt; COLOR: black">中增加</span><span style="FONT-SIZE: 10pt">enctype="multipart/form-data" </span><span style="FONT-SIZE: 10pt">呵呵</span></div><br /><div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">7.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">问题：</span></div><div style="TEXT-INDENT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">今天用</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">Tomcat5.5.12</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">，发现原来很好用的系统不能用了，反复测试发现页面中不能包含</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%"> taglib</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">，否则会出现以下提示：</span></div><div style="LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">HTTP Status 500 -type Exception report</span></div><div style="LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">Message  </span></div><div style="LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">description The server encountered an internal error () that prevented it from fulfilling this request.</span></div><div style="LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">exception</span></div><div style="LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">org.apache.jasper.JasperException: /index.jsp(1,1) Unable to read TLD "META-INF/tlds/struts-bean.tld" from JAR file "file:*****/WEB-INF/lib/struts.jar":</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">原因：</span></div><div style="TEXT-INDENT: 20pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">更新了工程用的</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">lib</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">文件夹下的</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">jar</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">，发布时也发布了</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">servlet.jar</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">和</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">jsp-api.jar</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">。</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">解决：</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">把</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">jsp-api.jar</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">删除就解决这个问题了。</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><br /></div><div style="MARGIN-LEFT: 18pt; TEXT-INDENT: -18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">8.<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">      </span></span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">问题：</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">Tomcat5.0.20</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">中差错可以通过</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">[Tomcat</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">安装目录</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">]/logs</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">下的</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">localhost_log.2006-07-14.txt</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">类似的文件看具体的错误日志，但是在</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">5.5</span><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">中就找不到了</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">原因与解决：</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">我把</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">[Tomcat</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">安装目录</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">]/bin</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">下的</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">tomcat5w.exe</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">的</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">logging</span><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">标签捣鼓了一会，然后重起就有了。</span></div><div style="MARGIN-LEFT: 18pt; LINE-HEIGHT: 150%"><span style="FONT-SIZE: 10pt; COLOR: black; LINE-HEIGHT: 150%">原因具体说不准，用非安装版也有这个问题。<br /></span></div><div style="TEXT-INDENT: 18pt"><font size="2"><font color="#000000"><span style="FONT-SIZE: 10pt; COLOR: blue; LINE-HEIGHT: 150%">最终解决方案：<br />   <a href="http://tomcat.apache.org/tomcat-5.5-doc/logging.html">http://tomcat.apache.org/tomcat-5.5-doc/logging.html</a><br /></span></font></font></div><img src ="http://www.blogjava.net/lvlinghui/aggbug/73321.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lvlinghui/" target="_blank">马尔代夫</a> 2006-10-03 20:23 <a href="http://www.blogjava.net/lvlinghui/articles/73321.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>