??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲乱亚洲乱妇无码麻豆,色综合久久精品亚洲国产,亚洲av片在线观看http://www.tkk7.com/limq/rainmanzh-cnFri, 09 May 2025 14:23:33 GMTFri, 09 May 2025 14:23:33 GMT60MUI 上拉加蝲 完整实例http://www.tkk7.com/limq/archive/2018/04/24/433177.htmllimqlimqTue, 24 Apr 2018 07:29:00 GMThttp://www.tkk7.com/limq/archive/2018/04/24/433177.htmlhttp://www.tkk7.com/limq/comments/433177.htmlhttp://www.tkk7.com/limq/archive/2018/04/24/433177.html#Feedback0http://www.tkk7.com/limq/comments/commentRss/433177.htmlhttp://www.tkk7.com/limq/services/trackbacks/433177.html阅读全文

limq 2018-04-24 15:29 发表评论
]]>
动态表单及动态徏表实现原?/title><link>http://www.tkk7.com/limq/archive/2009/09/19/295690.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Sat, 19 Sep 2009 13:12:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2009/09/19/295690.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/295690.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2009/09/19/295690.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/295690.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/295690.html</trackback:ping><description><![CDATA[     摘要:   <a href='http://www.tkk7.com/limq/archive/2009/09/19/295690.html'>阅读全文</a><img src ="http://www.tkk7.com/limq/aggbug/295690.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2009-09-19 21:12 <a href="http://www.tkk7.com/limq/archive/2009/09/19/295690.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>重构—利用反合q函?/title><link>http://www.tkk7.com/limq/archive/2009/02/17/255027.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Tue, 17 Feb 2009 01:49:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2009/02/17/255027.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/255027.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2009/02/17/255027.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/255027.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/255027.html</trackback:ping><description><![CDATA[     摘要:     先看下重构前的测试用例: public class TestLogin extends TestCase{     private ButtonManagerIbatis buttonManagerIbatis;   &n...  <a href='http://www.tkk7.com/limq/archive/2009/02/17/255027.html'>阅读全文</a><img src ="http://www.tkk7.com/limq/aggbug/255027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2009-02-17 09:49 <a href="http://www.tkk7.com/limq/archive/2009/02/17/255027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>转蝲- |页弹出对话?/title><link>http://www.tkk7.com/limq/archive/2008/01/27/178009.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Sun, 27 Jan 2008 05:28:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2008/01/27/178009.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/178009.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2008/01/27/178009.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/178009.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/178009.html</trackback:ping><description><![CDATA[如何利用|页弹出各种形式的窗口,我想大家大多都是知道些的Q但那种多种多样的弹出式H口是怎么搞出来的Q我们今天就来学习一下: <p align="left">  <strong>1.弹启一个全屏窗?/strong></p> <p align="left"><html><br /> <body onload="window.open('http://www.pconline.com.cn','example01','fullscreen');">;<br /> <b>www.e3i5.com</b><br /> </body><br /> </html></p> <p align="left">  <strong>2.弹启一个被F11化后的窗?/strong></p> <p align="left"><html><br /> <body onload="window.open(''http://www.pconline.com.cn','example02','channelmode');">;<br /> <b>www.e3i5.com</b><br /> </body><br /> </html></p> <p align="left">  <strong>3.弹启一个带有收藏链接工h的窗?/strong></p> <p align="left"><html><br /> <body onload="window.open('http://www.pconline.com.cn','example03','width=400,height=300,directories');"><br /> <b>www.e3i5.com</b><br /> </body><br /> </html></p> <p align="left">  <strong>4.|页对话?/strong></p> <p align="left"><html><br /> <SCRIPT LANGUAGE="javascript"><br /> <!--<br /> showModalDialog('http://www.pconline.com.cn','example04','dialogWidth:400px;dialogHeight:300px;<br /> dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes')<br /> //--><br /> </SCRIPT><br /> <b>www.e3i5.com</b><br /> </body><br /> </html></p> <p align="left"><html><br /> <SCRIPT LANGUAGE="javascript"><br /> <!--<br /> showModelessDialog('http://www.pconline.com.cn','example05','dialogWidth:400px;dialogHeight:300px;<br /> dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes')<br /> //--><br /> </SCRIPT><br /> <b>http://www.pconline.com.cn</b><br /> </body><br /> </html></p> <p align="left">  showModalDialog()或是showModelessDialog() 来调用网对话框Q至于showModalDialog()与showModelessDialog()的区别,在于showModalDialog()打开的窗口(U模式窗口)Q置在父H口上,必须关闭才能讉K父窗?量用Q以免招人反?QshowModelessDialog()Q简U无模式H口Q,打开后不必关闭也可访问父H口打开的窗口?</p> <p align="left">dialogHeight: iHeight 讄对话框窗口的高度?<br /> dialogWidth: iWidth 讄对话框窗口的宽度?  <br /> dialogLeft: iXPos 讄对话框窗口相对于桌面左上角的left位置?<br /> dialogTop: iYPos 讄对话框窗口相对于桌面左上角的top位置?<br /> center: {yes | no | 1 | 0 } 指定是否对话框在桌面上居中Q默认值是“yes”?br /> help: {yes | no | 1 | 0 } 指定对话框窗口中是否昄上下文敏感的帮助图标。默认值是“yes”?  <br /> resizable: {yes | no | 1 | 0 } 指定是否对话框窗口大可变。默认值是“no”?<br /> status: {yes | no | 1 | 0 } 指定对话框窗口是否显C状态栏。对于非模式对话框窗口,默认值是“yes”Q对于模式对话框H口Q默认值是 “no”?/p> <img src ="http://www.tkk7.com/limq/aggbug/178009.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2008-01-27 13:28 <a href="http://www.tkk7.com/limq/archive/2008/01/27/178009.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>log4j使用q阶http://www.tkk7.com/limq/archive/2006/04/10/40341.htmllimqlimqMon, 10 Apr 2006 15:11:00 GMThttp://www.tkk7.com/limq/archive/2006/04/10/40341.htmlhttp://www.tkk7.com/limq/comments/40341.htmlhttp://www.tkk7.com/limq/archive/2006/04/10/40341.html#Feedback3http://www.tkk7.com/limq/comments/commentRss/40341.htmlhttp://www.tkk7.com/limq/services/trackbacks/40341.html
二 动态配|log4j
1 配置外部配置文g来配|的基本步骤
1.1 一个运用配|文件的实例
Log4j之所以能成功的原因之一是它的灵zL。但如果只是单的调用BasicConfigurator.configure()来进行配|工作,那么所有的配置都是在函C写死的,以后修改配置p修改原代码,q就不能体现出log4j的灵zL了Q所以基本上不会通过BasicConfigurator.configure()来进行配|工作的?br />Z增加软g的灵zL,最常用的做法就是用配|文Ӟ如web.xml之于J2EEQstruts-config.xml之于struts一Plog4j也提供了让我们把配置信息从程序{Ud配置文g中的Ҏ。Log4j提供了两U方式的配置文gQXML文g和Java的property配置文g。通过把配|信息{Ud外部文g中,当我们要修改配置信息Ӟ可以直接修攚w|文件而不用去修改代码了,下面Q我们就来完成一个通过配置文g来实现log4j的实例?br />?-aQ?br />package TestLog4j;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Priority; public class TestLog4j 
{
static Logger logger = Logger.getLogger(TestLog4j.class.getName());
public TestLog4j(){}

public static void main(String[] args)
{
//通过BasicConfiguratorcL初始?br />//BasicConfigurator.configure();
//Q?Q通过配置文g来初始化
PropertyConfigurator.configure("F:\\nepalon\\log4j.properties");

logger.debug("Start of the main() in TestLog4j"); //代码Q?Q?br />logger.info("Just testing a log message with priority set to INFO");
logger.warn("Just testing a log message with priority set to WARN");
logger.error("Just testing a log message with priority set to ERROR");
logger.fatal("Just testing a log message with priority set to FATAL");
logger.log(Priority.WARN, "Testing a log message use a alternate form");
logger.debug(TestLog4j.class.getName()); //代码Q?Q?br />}
}
在这个例子中Q我们用PropertyConfigurator.configure("F:\\nepalon\\log4j.properties")代替BasicConfigurator.configure()q行配置。PropertyConfigurator.configure()函数的参数可以是一个properties文g所在\径的String对象Q可以是一个properties文g所在\径的URL对象Q也可以是一个properties对象。通过PropertyConfigurator.configure()可以通过指定的properties文g来配|信息。如果要用XML文gq行信息配置Q可以在代码中调用DOMConfigurator()函数来进行配|工作。在q里Q我们只以properties文g来完成例子。接着Q我们来看一下log4j.properties文g中都有些什么东西:
?-bQ?br />log4j.rootLogger = DEBUG, A1
log4j.appender.A1 = org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout = org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n
q行q个实例Q运行结果ؓ
0 [main] DEBUG TestLog4j.TestLog4j - Start of the main() in TestLog4j
20 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
20 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
20 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
20 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
180 [main] WARN TestLog4j.TestLog4j - Testing a log message use a alternate form
180 [main] DEBUG TestLog4j.TestLog4j - TestLog4j.TestLog4j
下面Q我们分析一下这个配|文件?br />1) ׃每一个LoggerҎ都有一个别,文g的第一行就是定义了一个Logger及其U别。在q里定义了一个根记录器(root loggerQ,q涉及到记录器的层次问题Q在些暂时不深入讨论Q在后面的章节再q行讨论?br />2) W二行定义了一个名为A1的输出流Q这个流是控制収ͼ所以通过Logger对象打印的信息会在控制台输出?br />3) W三行定义了打印信息的布局。在q里我们用PatternLayout作ؓ此记录器的布局QPatternLayout允许你以灉|的格式来打印信息?br />4) W四行指定的打印信息的具体格式,从结果可知,q个实例的打印格式ؓQ当前打印语句所使用的时闾b[日志所在的U程] 打印的别 当前日志所在的cȝ全名 日志信息?br />现在我们来修改一下这个记录器的别,把第一行的DEBUG改ؓINFOQ再q行E序Q结果将变ؓQ?br />0 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
10 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
10 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
10 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
10 [main] WARN TestLog4j.TestLog4j - Testing a log message use a alternate form
׃q个Logger的别变为INFOQ而代码(2Q是调用debug()函数来输出日志信息时只能当记录器U别为DEBUG时才输出信息Q所以代码(2Q将不输Z息?br />1.2 实例原理
1.2.1 初始化配|信?br />如果要通过JAVA的properties文g来配|信息,那么在代码中p通过PropertyConfigurator.configure()函数从properties文g中加载配|信息,q个函数有三U参数Ş式:一个properties文g所在\径的String对象Q可以是一个properties文g所在\径的URL对象Q也可以是一个properties对象。如果要用XML文g来配|信息,则可用类型的
DOMConfigurator()函数来从一个XML文g中加载配|信息?br />1.2.2 输出端Appender
在上面的例子中,我们都是单的把日志信息输出到控制C。其实在log4j中还可以把日志信息输出到其它的输出端Q对于同一个日志信息,我们q可以让它同时输出到多个输出端中Q如同时在控制台和文件中q行打印。一个输出端是一个appender。要在配|文件中定义一个appender有三步:
1) 在定义一个记录器的同时定义出该记录器的输出端appender。在?的配|文件的W一句log4j.rootLogger = DEBUG, A1中,我们定义了一个根记录器,它的U别为DEBUGQ它有一个appender名ؓA1。定义根记录器的格式为log4j.rootLogger = [ level ], appendName1, appendName2, ...appendNameN。同一个记录器可有多个输出端?br />2) 定义appender的输出目的地。定义一个appender的输出目的地的格式ؓlog4j.appender.appenderName = fully.qualified.name.of.appender.class。log4j提供了以下几U常用的输出目的圎ͼ
? org.apache.log4j.ConsoleAppenderQ将日志信息输出到控制台
? org.apache.log4j.FileAppenderQ将日志信息输出C个文?br />? org.apache.log4j.DailyRollingFileAppenderQ将日志信息输出C个,q且每天输出C个新的日志文?br />? org.apache.log4j.RollingFileAppenderQ将日志信息输出C个文Ӟ通过指定文g的的寸Q当文g大小到达指定寸的时候会自动把文件改名,如名为example.log的文件会改名为example.log.1Q同时生一个新的example.log文g。如果新的文件再ơ达到指定尺寸,又会自动把文件改名ؓexample.log.2Q同时生一个example.log文g。依此类推,直到example.log. MaxBackupIndexQMaxBackupIndex的值可在配|文件中定义?br />? org.apache.log4j.WriterAppenderQ将日志信息以流格式发送到L指定的地斏V?br />? org.apache.log4j.jdbc.JDBCAppenderQ通过JDBC把日志信息输出到数据库中?br />在例2中,log4j.appender.A1 = org.apache.log4j.ConsoleAppender定义了名为A1的appender的输出目的地为控制台Q所以日志信息将输出到控制台?br />3) 定义与所选的输出目的地相关的参数Q定义格式ؓQ?br />log4j.appender.appenderName.optionName1 = value1
......
log4j.appender.appenderName.optionNameN = valueN
其中一个最常用的参数layout在下面介绍?br />1.2.3 输出格式Q布局Qlayout
通过appender可以控制输出的目的地Q而如果要控制输出的格式,可通过log4j的layoutlg来实现。通过配置文g定义一个appender的输出格式,也通常需要两个步骤:
1) 定义appender的布局模式。定义一个appender的布局模式的格式ؓlog4j.appender.appenderName.layout = fully.qualified.name.of.layout.class。Log4j提供的布局模式有以下几U:
? org.apache.log4j.HTMLLayoutQ以HTML表格形式布局
? org.apache.log4j.PatternLayoutQ可以灵zd指定布局模式
? org.apache.log4j.SimpleLayoutQ包含日志信息的U别和信息字W串
在例2 中log4j.appender.A1.layout = org.apache.log4j.PatternLayout定义了名为A1的appender的布局模式为PatternLayout?br />2) 定义与所选的布局模式相关的设|信息,定义格式为:
log4j.appender.appenderName.layout.optionName1 = value1
......
log4j.appender.appenderName.layout.optionNameN = valueN
选择了不同的布局模式可能会有不同的设|信息。实?所选的布局模式PatternLayout的一个PatternLayout为ConversionPattern Q通过定义q个PatternLayout的|我们可以指定输出信息的输出格式。在?的配|文件中的定义如下log4j.appender.A1.layout.ConversionPattern = %-4r [%t] %-5p %c %x - %m%n。在下面Q我们将介绍布局模式PatternLayout的参数ConversionPattern的各个g表的含义?br />1.2.4 ConversionPattern参数的格式含?br />格式名 含?br />%c 输出日志信息所属的cȝ全名
%d 输出日志旉点的日期或时_默认格式为ISO8601Q也可以在其后指定格式,比如Q?d{yyy-MM-dd HH:mm:ss }Q输出类|2002-10-18- 22Q?0Q?8
%f 输出日志信息所属的cȝcd
%l 输出日志事g的发生位|,卌出日志信息的语句处于它所在的cȝW几?br />%m 输出代码中指定的信息Q如log(message)中的message
%n 输出一个回车换行符QWindowsq_?\r\n"QUnixq_?\n"
%p 输出优先U,即DEBUGQINFOQWARNQERRORQFATAL。如果是调用debug()输出的,则ؓDEBUGQ依此类?br />%r 输出自应用启动到输出该日志信息所耗费的毫U数
%t 输出产生该日志事件的U程?br />1.3 定义多个输出目的地的实例
从上面的实例原理中我们已l知道,同一个日志信息可以同时输出到多个输出目的圎ͼ在这个例子中Q我们将实现一个把日志信息同时输出到控制器、一个文件中的实例和数据库中。这个实例的Java代码我们沿用?中的代码Q我们只需修改配置文g卛_。这也体Clog4j的灵zL?br />?-aQ?br />create table log4j(
logID int primary key identity,
message varchar(1024),
priority varchar(10),
milliseconds int,
category varchar(256),
thread varchar(100),
NDC varchar(256),
createDate datetime,
location varchar(256),
caller varchar(100),
method varchar(100),
filename varchar(100),
line int
)
?-bQ?br />#1 定义了两个输出端
log4j.rootLogger = INFO, A1, A2,A3

#2 定义A1输出到控制器
log4j.appender.A1 = org.apache.log4j.ConsoleAppender
#3 定义A1的布局模式为PatternLayout
log4j.appender.A1.layout = org.apache.log4j.PatternLayout
#4 定义A1的输出格?br />log4j.appender.A1.layout.ConversionPattern = %-4r [%t] %-5p %c - %m%n

#5 定义A2输出到文?br />log4j.appender.A2 = org.apache.log4j.RollingFileAppender
#6 定义A2要输出到哪一个文?br />log4j.appender.A2.File = F:\\nepalon\\classes\\example3.log
#7 定义A2的输出文件的最大长?br />log4j.appender.A2.MaxFileSize = 1KB
#8 定义A2的备份文件数
log4j.appender.A2.MaxBackupIndex = 3
#9 定义A2的布局模式为PatternLayout
log4j.appender.A2.layout = org.apache.log4j.PatternLayout
#10 定义A2的输出格?br />log4j.appender.A2.layout.ConversionPattern = %d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n

#11区 定义A3输出到数据库
log4j.appender.A3 = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.A3.BufferSize = 40
log4j.appender.A3.Driver = com.microsoft.jdbc.sqlserver.SQLServerDriver
log4j.appender.A3.URL = jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=nepalon
log4j.appender.A3.User = sa
log4j.appender.A3.Password = 
log4j.appender.A3.layout = org.apache.log4j.PatternLayout
log4j.appender.A3.layout.ConversionPattern = INSERT INTO log4j (createDate, thread, priority, category, message) values(getdate(), '%t', '%-5p', '%c', '%m')
配置文g中的6??行显CZ输出端ؓRollingFileAppender的特有参数及其运用的Ҏ?1区显CZ输出端ؓJDBCAppender的特有参数及其运用方法。在q着重讲解一???行的作用?行指定日志信息输出到哪个文gQ?行指定日志文件的最大长度,最后要详细介绍8行。第8行的参数是设|备份文件的个数的参敎ͼ在这里我们设|ؓ3Q表C最多有3个备份文Ӟ具体作用为:
1) 当example3.log文g的大超qKӞ把文g改名为example3.log.1Q同时生成一个新的example3.log文g
2) 当example3.log文g的大再ơ超q?KQ又把文件改名ؓexample3.log.1。但׃此时example3.log.1已存在,则先把example3.log.1更名为example3.log.2Q再把example3.log文g改名为example3.log.1
3) 同理Q当example3.log文g的大再ơ超q?KQ先把example3.log.2文g更名为example3.log.3Q把example3.log.1文g更名为example3.log.2Q再把example3.log文g改名为example3.log.1
4) 当example3.log文g的大再ơ超q?KQ先把example3.log.2文g更名为example3.log.3Q旧的example3.log.3文g被覆盖Q把example3.log.1文g更名为example3.log.2Q旧的example3.log.2文g被覆盖;最后把example3.log文g改名为example3.log.1q覆盖掉旧的example3.log.1文g?br />q行l果分Z部分
在控制器中:
0 [main] INFO TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
11 [main] WARN TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
21 [main] ERROR TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR 21 [main] FATAL TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
21 [main] WARN TestLog4j.TestLog4j - Testing a log message use a alternate form
在文件example3.log中:
2003-12-18 04:23:02:INFO main TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
2003-12-18 04:23:02:WARN main TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
2003-12-18 04:23:02:ERROR main TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
2003-12-18 04:23:02:FATAL main TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
2003-12-18 04:23:02:WARN main TestLog4j.TestLog4j - Testing a log message use a alternate form
1.4 配置log4j的ȝ
q个教程到这里,关于配置log4j的配|文件的基本原理已经讲完了,而且通过?我们已经可以完成基本的日志工作了。现在,我们做一个ȝ。配|一个配|文件的基本步骤如下Q?br />1) 定义一个Logger。在定义Logger时指定该Logger的别其输出目的地。定义Logger的格式ؓ
log4j.rootLogger = [ level ], appendName1, appendName2, ...appendNameN?br />2) 定义appender的输出目的地。定义一个appender的输出目的地的格式ؓ
log4j.appender.appenderName = fully.qualified.name.of.appender.class?br />log4j提供的输出端有ConsoleAppender、FileAppender 、DailyRollingFileAppender、RollingFileAppender和WriterAppender?br />3) 定义appender的除布局模式外的其它相关参数Q如?中第6??定义了A2的相兛_数。定义格式ؓ
log4j.appender.appenderName.optionName1 = value1
......
log4j.appender.appenderName.optionNameN = valueN
如果除了布局模式外不需要定义别的参敎ͼ可蟩q这一步(如例3中的A1Q?br />4) 定义appender的布局模式。定义一个appender的布局模式的格式ؓ
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class?br />布局模式其实也是步骤3Q中的一个部分,只是布局模式参数是每一个appender必须定义的参数。Log4j提供的布局模式有HTMLLayout、PatternLayout和SimpleLayout?br />5) 定义与所选的布局模式相关的设|信息,定义格式?br />og4j.appender.appenderName.layout.optionName1 = value1
......
log4j.appender.appenderName.layout.optionNameN = valueN
2 记录器的层次Logger hierarchy
2.1 何ؓ记录器的层次hierarchy
首先Q我们先看一下何为层ơ,以我们最熟悉的承ؓ例,下面是一张类?br />
在这个承体pMQ类B是类C的父c,cA是类C的祖先类Q类D是类C的子cR这些类之间构成一U层ơ关pR在q些h层次关系的类中,子类都可l承它的父类的特征,如类B的对象能调用cA中的非private实例变量和函敎ͼ而类C׃l承自类BQ所以类B的对象可以同时调用类A和类B中的非private实例变量和函数?br />在log4j中,处于不同层次中的Logger也具有象c这Ll承关系?br />2.2 记录器的层次
如果一个应用中包含了上千个c,那么也几乎需要上千个Logger实例。如何对q上千个Logger实例q行方便地配|,是一个很重要的问题。Log4J采用了一U树状的l承层次巧妙地解决了q个问题。在Log4J中Logger是具有层ơ关pȝ。它有一个共同的根,位于最上层Q其它Logger遵@cM包的层次。下面我们将q行介绍?br />2.2.1 根记录器root logger
p一个Java中的ObjectcMPlog4j中的logger层次中有一个称之ؓ根记录器的记录器Q其它所有的记录器都l承自这个根记录器。根记录器有两个特征Q?br />1) 根记录器L存在。就像Java中的ObjectcMP因ؓ用log4j输出日志信息是通过记录器来实现的,所以只要你应用了log4jQ根记录器就肯定存在的?br />2) 根记录器没有名称Q所以不能通过名称来取得根记录器。但在LoggercM提供了getRootLogger()的方法来取得根记录器?br />2.2.2 记录器的层次
Logger遵@cM包的层次。如
static Logger rootLog = Logger.getRootLogger();
static Logger log1 = Logger.getLogger("test4j");
static Logger log2 = Logger.getLogger("test4j.test4j2");
static Logger log3 = Logger.getLogger("test4j.test4j2.test4j2");
那么rootLog是log2的祖先子记录器,log1是log2的父子记录器Qlog3是log2的子记录器。记录器象Java中的cȝ承一P子记录器可以l承父记录器的设|信息,也可以可以覆写相应的信息?br />首先先看一下记录器层次中的l承有什么用处。假讄序中的每个包都具有一些基本的日志信息Q而包中的不同包可能会有些额外的日志信息要输出Q这U情况就可以象处理Java中的cMPq用Logger中的层次关系来达到目的。假设有个名为A的包Q我包下的所有类都要把日志信息输出到控制CQA.B包除了输出到控制台外q要输出到文件中QA.C包除了输出到控制Cq要输出到HTML文档中。这h们就可以通过定义一个父记录器AQ它负责把日志信息输出到控制CQ定义一个A的子记录器A.BQ它负责把日志信息输出到文g中;定义一个A的子记录器A.CQ它负责把日志信息输出到HTML文档中?br />记录器遵循的是类似包的层ơ,q样做ؓ我们带来了大大的方便。LoggercM的getLogger()Ҏ可以取得Logger对象Q这个方法有三种参数形式String、Class和URLQ其实不论是用哪一U,最l都是通过记录器的名字来取得记录器对象的。如果要取得一个名为A.B的记录器对象Q我们可以Logger.getLogger("A.B")。但从上面的例子中,我们都是通过Logger.getLogger(TestLog4j.class.getName())q种Ҏ来取得记录器对象。这是ؓ什么呢Q现在我们假设A.B的包下有一个类BClassQ那么我们调用BClass.class.getName()得到的是q个cȝ全名A.B.BClass。所以当调用Logger.getLogger(BClass.class.getName())Ӟ最理想的情冉|q回名ؓA.B.BClass的记录器对象。但是如果不存在名ؓA.B.BClass的记录器时它会怎样呢?其实通过LoggercȝgetLoggerҎ取得记录器时存在下面两种情况Q?br />1) 如果存在与所要找的名字完全相同的记录器,则返回相应的记录器对象?br />当调用Logger.getLogger(BClass.class.getName())Ӟ如果定义了名为A.B.BClass的记录器Q它p回该记录器的对象?br />2) 但如果找不到Q它会尝试返回在记录器层ơ中与所要找的记录器最接近的记录器对象?br />当调用Logger.getLogger(BClass.class.getName())Ӟ如果没有定义了名为A.B.BClass的记录器Q那会尝试返回名为A.B的记录器的对象;如果又没有定义名为A.B的记录器Q它会尝试返回名为A的记录器的对象;如果也没定义名ؓA的记录器Q它׃q回根记录器的对象,而根记录器是必须存在的,所以你总能得到一个记录器对象?br />好了Q现在我们回到前面的问题Q我们ؓ什么总要通过Logger.getLogger(BClass.class.getName())q种以类全名作ؓ参数来取得记录器对象呢?其实q是Z理方便。因为我们在定义设计Logger时也遵@cM包的规则Q设计器的名称与程序中的类包对应。如上面的假设中我们的程序中有A包,A包下有B包和C包,B包下又有cBClassQ那么我们就可设计器的名ؓA、A.B、A.C、A.B.BClassQ以此类推。那么当我们通过cd名来取得设计器对象时Q总能取到与所要的设计器最接近的设计器对象?br />2.3 如何应用记录器的层次
2.3.1 如果定义及获取不同层ơ的记录?br />M一个记录器的用都有两个步骤:
1) 在配|文件中定义相应的记录器?br />在配|文件中定义记录器的格式有两U?br />? 定义根记录器的格式ؓ
log4j.rootLogger = [ level ], appendName1, appendName2, ...appendNameN
? 定义一个非根记录器的格式ؓ
log4j.logger.loggerName1 = [ level ], appendName1,...appendNameN
......
log4j.logger.loggerNameM = [ level ], appendName1, ...appendNameN
我们可以定义L个非根记录器?br />2) 在代码中调用Loggercȝ取得记录器方法取得相应的记录器对象?br />要取得根记录器对象可通过Logger.getRootLogger()函数Q要取得非根记录器可通过Logger.getLogger()函数?br />理论知道p到这里,U怸得来l觉,下面Q我们来小演练一下?br />?-aQ?br />package TestLog4j;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Priority;
import TestLog4j.TestLog4j2.TestLog4j2;

public class TestLog4j 
{
static Logger logger = Logger.getLogger(TestLog4j.class.getName()); //Q?Q?br />public TestLog4j(){}

public static void main(String[] args)
{
//同时输出到控制台和一个文件的实例q实CLogger的?br />PropertyConfigurator.configure("F:\\nepalon\\log4j2.properties");

logger.debug("Start of the main() in TestLog4j");
logger.info("Just testing a log message with priority set to INFO");
logger.warn("Just testing a log message with priority set to WARN");
logger.error("Just testing a log message with priority set to ERROR");
logger.fatal("Just testing a log message with priority set to FATAL");
logger.log(Priority.WARN, "Testing a log message use a alternate form");
logger.debug(TestLog4j.class.getName());
TestLog4j2 testLog4j2 = new TestLog4j2(); //Q?Q?br />testLog4j2.testLog();
}
}
在类TestLog4j中我们调用了另一个类TestLog4j2Q下面看一下类TestLog4j2的代码?br />?-bQ?br />package TestLog4j.TestLog4j2;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.Priority;

public class TestLog4j2 
{
static Logger logger = Logger.getLogger(TestLog4j2.class.getName()); //Q?Q?br />public TestLog4j2(){}

public void testLog()
{
//同时输出到控制台和一个文件的实例
PropertyConfigurator.configure("F:\\nepalon\\log4j2.properties");
logger.debug("2Start of the main()");
logger.info("2Just testing a log message with priority set to INFO");
logger.warn("2Just testing a log message with priority set to WARN");
logger.error("2Just testing a log message with priority set to ERROR");
logger.fatal("2Just testing a log message with priority set to FATAL");
logger.log(Priority.DEBUG, "Testing a log message use a alternate form");
logger.debug("2End of the main()");
}
}
最后我们来看一下配|文件?br />?-cQ?br />log4j2.properties文g内容
Q??br />#### Use two appenders, one to log to console, another to log to a file
log4j.rootLogger = debug, stdout

#2?br />#Print only messages of priority WARN or higher for your category
log4j.logger.TestLog4j= , R
log4j.logger.TestLog4j.TestLog4j2=WARN

#3?br />#### First appender writes to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

#4?br />#### Second appender writes to a file
log4j.appender.R=org.apache.log4j.RollingFileAppender
log4j.appender.R.File=F:\\nepalon\\classes\\TestLog4j\\example.log

# Control the maximum log file size
log4j.appender.R.MaxFileSize=100KB
# Archive log files (one backup file here)
log4j.appender.R.MaxBackupIndex=1

log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d{yyyy-MM-dd hh:mm:ss}:%p %t %c - %m%n
先看一下运行结果?br />在控制台中的l果为:
DEBUG [main] (?:?) - Start of the main() in TestLog4j
INFO [main] (?:?) - Just testing a log message with priority set to INFO
WARN [main] (?:?) - Just testing a log message with priority set to WARN
ERROR [main] (?:?) - Just testing a log message with priority set to ERROR
FATAL [main] (?:?) - Just testing a log message with priority set to FATAL
WARN [main] (?:?) - Testing a log message use a alternate form
DEBUG [main] (?:?) - TestLog4j.TestLog4j
WARN [main] (?:?) - 2Just testing a log message with priority set to WARN
ERROR [main] (?:?) - 2Just testing a log message with priority set to ERROR
FATAL [main] (?:?) - 2Just testing a log message with priority set to FATAL
输出文g的结果ؓQ?br />2003-12-19 04:19:44:DEBUG main TestLog4j.TestLog4j - Start of the main() in TestLog4j
2003-12-19 04:19:44:INFO main TestLog4j.TestLog4j - Just testing a log message with priority set to INFO
2003-12-19 04:19:44:WARN main TestLog4j.TestLog4j - Just testing a log message with priority set to WARN
2003-12-19 04:19:44:ERROR main TestLog4j.TestLog4j - Just testing a log message with priority set to ERROR
2003-12-19 04:19:44:FATAL main TestLog4j.TestLog4j - Just testing a log message with priority set to FATAL
2003-12-19 04:19:44:WARN main TestLog4j.TestLog4j - Testing a log message use a alternate form
2003-12-19 04:19:44:DEBUG main TestLog4j.TestLog4j - TestLog4j.TestLog4j
2003-12-19 04:19:44:WARN main TestLog4j.TestLog4j2.TestLog4j2 - 2Just testing a log message with priority set to WARN
2003-12-19 04:19:44:ERROR main TestLog4j.TestLog4j2.TestLog4j2 - 2Just testing a log message with priority set to ERROR
2003-12-19 04:19:44:FATAL main TestLog4j.TestLog4j2.TestLog4j2 - 2Just testing a log message with priority set to FATAL

首先Q先来看一下配|文仉有些什么东ѝ?br />1) ?Z定义了一个根记录器。这个根记录器具有DEBUGU别q有一个名UCؓstdout的输出端appender?br />2) 2Z的内Ҏq一节的重点Q也是应用到记录器层ơ的地方Q但其实也只有两句,充分体现了log4j的简单性。在q里Q我们定义了两个名称分别为TestLog4j和TestLog4j.TestLog4j2设计器?br />? 在定义TestLog4j记录器时没有指定U别Q所以它的别承自它的父记录器Q即要记录器Q所以它的别也为DEBUG。在定义TestLog4j记录器时又定义了一个名UCؓR的输出端Q所以它的输出端有两个,一个从根记录器l承而来的名为stdout的输出端Q另一个ؓ在此定义的名为R的输出端。在此需要注意的是,在定义记录器时必d定义记录器的U别Q然后才是记录器的输出端。如果只惛_义输出端而不定义U别Q则虽然U别可以为空Q但逗号分隔W不能省略。如定义TestLog4j记录器的做法?br />? 在定义TestLog4j.TestLog4j2记录器时又指定了它的U别Q由于一个记录器的别只能有一个,所以新指定的别将覆写掉它的父记录器的U别Q这pJava中的多态)。我们没有定义TestLog4j.TestLog4j2记录器的输出端,所以它的输出端从它的父记录器中承而来。它的父记录器ؓestLog4j记录器,所以它和estLog4j记录器一样具有两个名U分别ؓstdout和R的输出端?br />3) 剩下?区和4区分别设|了两个输出端的参数倹{?br />接下来,回到我们的代码,看一下是如何取得记录器,在取记录器时又发生了什么?br />1) ?-a中的代码Q?Q中Q语句Logger.getLogger()中的参数TestLog4j.class.getName()的gؓTestLog4j. TestLog4jQ所以此语句的结果是取得一个名为TestLog4j. TestLog4j的记录器的对象。但在配|文件中q没有定义这L记录器,所以最l将q回与所需的名UTestLog4j. TestLog4j最接近的记录器对象Q即名ؓTestLog4j的记录器的对象?br />2) ?-b中的代码Q?Q的原理与例4-a中的代码Q?Q相|期望取得的是名ؓTestLog4j.TestLog4j2. TestLog4j2的记录器对象Q但最l返回的是TestLog4j.TestLog4j2记录器的对象?br />三 log4j与J2EE的结?br />到目前ؓ止,q篇文章讲的都是如何在application中应用log4jQ而Java现在的应用主是J2EE和J2ME。现在,我们来看一下要如何在J2EE开发中应用log4j。其实在Web application中应用log4j也很单,与在application中应用log4j不同之处是要在所有应用log4j的代码之前对log4jq行初始化。所以,我们在web application中就要把log4j的初始化工作独立出来Q把它放在Servlet中。下面,我们看一个例子?br />?-aQ?br />q行初始化的ServletQ?br />import org.apache.log4j.PropertyConfigurator;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
* log4j.jar的初始化c,参考web.xml
*/
public class Log4jInit extends HttpServlet 
{
public void init() 
{
//通过web.xml来动态取得配|文?br />String prefix = getServletContext().getRealPath("/");
String file = getInitParameter("log4j-init-file");

// 如果没有l出相应的配|文Ӟ则不q行初始?br />if(file != null) 
{
PropertyConfigurator.configure(prefix+file); //Q?Q?br />}
}

public void doGet(HttpServletRequest req, HttpServletResponse res) 
{} 
}
下面来看一下这个Servlet在web.xml中的定义?br />?-bQ?br /><servlet>
<servlet-name>log4j-init</servlet-name>
<servlet-class>TestLog4j.Log4jInit</servlet-class>
<init-param>
<param-name>log4j-init-file</param-name>
<param-value>sort.properties</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
因ؓlog4j的初始化要在所有的log4j调用之前完成Q所以在web.xml文g中,我们一定要把对应的Servlet定义的load-on-startup应设?Q以便在Web容器启动时即装入该Servlet?br />完成了这两个步骤q后Q我们就可以象在application开发中一样在web applicationM地方应用log4j了。下面是在javabean中的应用的一个例子?br />?-cQ?br />import org.apache.log4j.Logger;

public class InfoForm 
{
static Logger logger = Logger.getLogger(InfoForm.class);

protected String title;
protected String content;

public InfoForm() {}

public void setTitle(Object value) 
{
logger.debug("nepalon:title = " + title);
title = value;
}

public String getTitle() 
{
logger.debug("nepalon:title = " + title);
return title;
}

public void setContent(String value) 
{
content = value;
logger.debug("nepalon: content() = " + content);
}

public String getContent() 
{
logger.debug("nepalon: content = \n" + content);
return content;
}
}

limq 2006-04-10 23:11 发表评论
]]>
【Eclipse资料】]常用的Eclipse 3.0插gQ{Q?/title><link>http://www.tkk7.com/limq/archive/2006/04/10/40329.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Mon, 10 Apr 2006 13:43:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2006/04/10/40329.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/40329.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2006/04/10/40329.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/40329.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/40329.html</trackback:ping><description><![CDATA[1.MyEclipse  J2EE开发插Ӟ支持SERVLET/JSP/EJB/数据库操U늭<br /><a href="http://www.myeclipseide.com/"><font color="#4a664d"><u>www.myeclipseide.com</u></font></a><div><font color="#4a664d"></font> </div><div>2.Properties Editor  ~辑java的属性文Ӟq可以自动存盘ؓUnicode格式<br /><a href="http://propedit.sourceforge.jp/index_en.html"><font color="#4a664d"><u>http://propedit.sourceforge.jp/index_en.html</u></font></a></div><div><font color="#4a664d"></font> </div><div>3.Colorer Take  Z癄cd的文件按语法着?br /><a href="http://colorer.sourceforge.net/"><font color="#4a664d"><u>http://colorer.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>4.XMLBuddy ~辑xml文g<br /><a href="http://www.xmlbuddy.com/"><font color="#4a664d"><u>www.xmlbuddy.com</u></font></a></div><div><font color="#4a664d"></font> </div><div>5.Code Folding  加入多种代码折叠功能Q比eclipse自带的更多)<br /><a href="http://www.coffee-bytes.com/servlet/PlatformSupport"><font color="#4a664d"><u>http://www.coffee-bytes.com/servlet/PlatformSupport</u></font></a></div><div><font color="#4a664d"></font> </div><div>6.Easy Explorer  从eclipse中访问选定文g、目录所在的文g?br /><a href="http://easystruts.sourceforge.net/"><font color="#4a664d"><u>http://easystruts.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>7.Fat Jar 打包插gQ可以方便的完成各种打包dQ可以包含外部的包等<br /><a href="http://fjep.sourceforge.net/"><font color="#4a664d"><u>http://fjep.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>8.RegEx Test 试正则表达?br /><a href="http://brosinski.com/stephan/archives/000028.php"><font color="#4a664d"><u>http://brosinski.com/stephan/archives/000028.php</u></font></a></div><div><font color="#4a664d"></font> </div><div>9.JasperAssistant 报表插gQ强Q要qQ?br /><a href="http://www.jasperassistant.com/"><font color="#4a664d"><u>http://www.jasperassistant.com/</u></font></a></div><div><font color="#4a664d"></font> </div><div>10.Jigloo GUI Builder QAQӞ的GQテ~辑插g<br /><a href="http://cloudgarden.com/jigloo/"><font color="#4a664d"><u>http://cloudgarden.com/jigloo/</u></font></a></div><div><font color="#4a664d"></font> </div><div>11.Profiler 性能跟踪、测量工P能跟t、测量Q程?br /><a href="http://sourceforge.net/projects/eclipsecolorer/"><font color="#4a664d"><u>http://sourceforge.net/projects/eclipsecolorer/</u></font></a></div><div><font color="#4a664d"></font> </div><div>12.AdvanQas 提供对if/else{条件语句的提示和快捷帮助(自动更改l构{)<br /><a href="http://eclipsecolorer.sourceforge.net/advanqas/index.html"><font color="#4a664d"><u>http://eclipsecolorer.sourceforge.net/advanqas/index.html</u></font></a></div><div><font color="#4a664d"></font> </div><div>13.Log4E     Log4j插gQ提供各U和Log4j相关的Q务,如ؓҎ、类d一个logger{?br /><a href="http://log4e.jayefem.de/index.php/Main_Page"><font color="#4a664d"><u>http://log4e.jayefem.de/index.php/Main_Page</u></font></a></div><div><font color="#4a664d"></font> </div><div>14.VSSPlugin VSS插g<br /><a href="http://sourceforge.net/projects/vssplugin"><font color="#4a664d"><u>http://sourceforge.net/projects/vssplugin</u></font></a></div><div><font color="#4a664d"></font> </div><div>15.Implementors   提供跌{C个方法的实现c,而不是接中的功能Q实?Q?br /><a href="http://eclipse-tools.sourceforge.net/implementors/"><font color="#4a664d"><u>http://eclipse-tools.sourceforge.net/implementors/</u></font></a></div><div><font color="#4a664d"></font> </div><div>16.Call Hierarchy 昄一个方法的调用层次Q被哪些Ҏ调,调了哪些ҎQ?br /><a href="http://eclipse-tools.sourceforge.net/call-hierarchy/index.html"><font color="#4a664d"><u>http://eclipse-tools.sourceforge.net/call-hierarchy/index.html</u></font></a></div><div><font color="#4a664d"></font> </div><div>17.EclipseTidy 查和格式化HTML/XML文g<br /><a href="http://eclipsetidy.sourceforge.net/"><font color="#4a664d"><u>http://eclipsetidy.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>18.Checkclipse 查代码的风格、写法是否符合规?br /><a href="http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm"><font color="#4a664d"><u>http://www.mvmsoft.de/content/plugins/checkclipse/checkclipse.htm</u></font></a></div><div><font color="#4a664d"></font> </div><div>19.Hibernate Synchronizer Hibernate插gQ自动映等<br /><a href="http://www.binamics.com/hibernatesync/"><font color="#4a664d"><u>http://www.binamics.com/hibernatesync/</u></font></a></div><div><font color="#4a664d"></font> </div><div>20.VeloEclipse  Velocity插g<br /><a href="http://propsorter.sourceforge.net/"><font color="#4a664d"><u>http://propsorter.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>21.EditorList   方便的列出所有打开的Editor<br /><a href="http://editorlist.sourceforge.net/"><font color="#4a664d"><u>http://editorlist.sourceforge.net/</u></font></a></div><div><font color="#4a664d"></font> </div><div>22.MemoryManager 内存占用率的监视<br /><a href="http://cloudgarden.com/memorymanager/"><font color="#4a664d"><u>http://cloudgarden.com/memorymanager/</u></font></a></div><div> </div><div><font color="#ff0000">+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</font></div><div><p><strong><font size="2">plug-in|址Q?/font></strong></p><p><a href="http://www.eclipse-plugins.info/eclipse/index.jsp"><font color="#000080" size="2"><u>http://www.eclipse-plugins.info/eclipse/index.jsp</u></font></a></p><p><a href="http://www.eclipse-workbench.com/jsp/"><font color="#000080" size="2"><u>http://www.eclipse-workbench.com/jsp/</u></font></a></p><p><a href="http://eclipse-plugins.2y.net/eclipse/index.jsp"><font color="#000080" size="2"><u>http://eclipse-plugins.2y.net/eclipse/index.jsp</u></font></a> Q非帔R常著名的插g更新|站Q?</p><p><a href="http://www.crionics.com/products/opensource/eclipse/eclipse.jsp"><font color="#000080" size="2"><u>http://www.crionics.com/products/opensource/eclipse/eclipse.jsp</u></font></a> Q分cL楚) </p><p><a href="http://www.eclipseplugincentral.com/"><font color="#000080" size="2"><u>http://www.eclipseplugincentral.com/</u></font></a></p><p><strong><font size="2">Preferences无法昄新安装的插g的解军_?/font></strong></p><p><font face="宋体" color="#ff0000" size="4">删除C:\eclipse\configuration\org.eclipse.update下的platform.xml文gQ重新启动Eclipse</font></p><p><font face="宋体" color="#ff0000" size="4"></font> </p><p><font face="宋体" color="#ff0000" size="4"><font color="#000000" size="3">perl插g </font><a href="http://e-p-i-c.sf.net/updates"><font color="#000080" size="2"><u>http://e-p-i-c.sf.net/updates</u></font></a><br /><font color="#000000" size="3">C#插g </font><a href="http://www.improve-technologies.com/alpha/updates/site.xml"><font color="#000080" size="2"><u>http://www.improve-technologies.com/alpha/updates/site.xml</u></font></a><br /><font color="#000000" size="3">C插g </font><a href="http://update.eclipse.org/tools/cdt/releases/new"><font color="#000080" size="2"><u>http://update.eclipse.org/tools/cdt/releases/new</u></font></a><br /><font color="#000000" size="3">Hex插g </font><a href="http://ehep.sourceforge.net/update"><font color="#000080" size="2"><u>http://ehep.sourceforge.net/update</u></font></a></font></p><p><font face="宋体" color="#ff0000" size="4"></font> </p><p><font face="宋体" color="#ff0000" size="4"><strong><font color="#000000"><font size="2">Eclipse加速插件KeepResident</font></font></strong></font></p><p><a href="http://suif.stanford.edu/pub/keepresident/"><font color="#000080"><u>http://suif.stanford.edu/pub/keepresident/</u></font></a></p><p><font color="#000080">原理:利用两个 Windows API - SetProcessWorkingSetSize ?VirtualLock (适用?Windows q_)?/font></p><p><font color="#000080">切换时果然快很多?/font></p><p><font color="#000080">官方最D定在 100 MBQ最大?250 MB 左右?/font></p></div><div> </div><div> </div><div> </div><div><font color="#800080">Eclipse插g及电子书列表</font></div><div>    q日整理了一下我的Y件厂商发布记录,扑ֈ了一堆跟Eclipse有关的东东,恩,늛的面q非常的q泛有指导学习的书,有插Ӟ有支持工P自己不敢独nQ便拿出来放在这里,跟大家一块儿讨论一下。这个,要声明一下,我只有Y件记录,q没有保存,所以找不到列表里面的Y件的Q不要跟我要Q我能做的也只是帮助大家L一下而已。所有的软g后面都有链接Q但是每ơ更新列表的时候我的链接都没有拯完全Q不q,前面有链接里面有软g发布的网站信息,到该|站里面自己搜烦p搞到准确的信息?/div><div><br />2004-12-01<br />Apress.The.Definitive.Guide.to.SWT.and.JFace<br />Apress出版的《The.Definitive.Guide.to.SWT.and.JFace》chm格式电子书,Eclipseq_的两个用L面工LQSWT和JFace的java~程指南?br /><a href="http://www.amazon.com/exec/obidos/tg/detai...6889430-0550522"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detai...6889430-0550522</u></font></a><br /><a href="http://images.amazon.com/images/P/15905932...SCMZZZZZZZ_.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/15905932...SCMZZZZZZZ_.jpg</u></font></a></div><div>2004-11-29<br />JasperAssistant.v1.4.2<br />JasperAssistant是一Ƒ֏视化的JasperReports报表设计工具QJasperReports是一个非常流行的开放源码报告引擎。JasperAssistantZEclipse的插件程序结构,通过逼真的图形界面方便的创徏JasperReports报表定义文g?br /><a href="http://www.jasperassistant.com/"><font color="#008000"><u>http://www.jasperassistant.com/</u></font></a><br /><a href="http://www.jasperassistant.com/shots/full.png"><font color="#008000"><u>http://www.jasperassistant.com/shots/full.png</u></font></a></div><div>JVider.for.Eclipse.v1.7e1.Java<br />一ƾؓJavaSwing应用E序设计的GUIBuilder工具。在他的帮助下,你可以很单的Z的Java校应用程序和E序设计囑Ş用户界面?br /><a href="http://www.jvider.com/"><font color="#008000"><u>http://www.jvider.com/</u></font></a><br /><a href="http://www.jvider.com/jviderscreen.png"><font color="#008000"><u>http://www.jvider.com/jviderscreen.png</u></font></a></div><div>2004-11-28</div><div>RMI.Plugin.for.Eclipse.v1.6.1<br />Eclipse开发^台的RMIQ基于Java的分布计框Ӟ插gQ是在JavaSDKq_通过调用RMI~译器自动生成远E对象stubQ桩Q和skeletonQ框Ӟ的简便方法?br /><a href="http://www.genady.net/rmi/"><font color="#008000"><u>http://www.genady.net/rmi/</u></font></a><br /><a href="http://www.genady.net/rmi/v16/screenshots/...rmi-eclipse.png"><font color="#008000"><u>http://www.genady.net/rmi/v16/screenshots/...rmi-eclipse.png</u></font></a></div><div>2004-11-19</div><div>Addison.Wesley.Professional.SWT.The.Standard.Widget.Toolkit.Volume.1.Jun.2004<br />电子书,Eclipsepd之SWT_解QSWT是StandardWidgetToolkitQ是在java中创建图形界面的cd<br /><a href="http://www.amazon.com/exec/obidos/ASIN/032...8151071-6877408"><font color="#008000"><u>http://www.amazon.com/exec/obidos/ASIN/032...8151071-6877408</u></font></a><br /><a href="http://images.amazon.com/images/P/0321256638.01.LZZZZZZZ.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/0321256638.01.LZZZZZZZ.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/22338_AddisonWesley.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/22338_AddisonWesley.html</u></font></a></div><div>2004-11-13</div><div>Omondo.Eclipse.UML.Studio.Edition.v1.1.0<br />OmondoEclipseUML是一Ƒ֏视化的模块设计工P可以完全集成于Eclipse和CVS?br /><a href="http://www.omondo.com/"><font color="#008000"><u>http://www.omondo.com</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/21757_OmondoEclipse.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/21757_OmondoEclipse.html</u></font></a></div><div>Omondo.Eclipse.UML.Studio.Edition.v1.1.0<br />OmondoEclipseUML是一Ƒ֏视化建模工具Q可以与Eclipse和CVS无缝集成?/div><div>2004-10-20</div><div>Oxygen.XML.Editor.v5.0.Eclipse.plugin<br />OxygenXMLeditor是一Ƒ֟于Java的XML~辑器,支持XML,XSL,TXT,XSD,DTD文档Q能自行校验XML,XSL,XSD代码Q提C本错误。Oxygen能自动完成结束标{,代码高亮现实Q支持Unicode?br /><a href="http://www.oxygenxml.com/features/"><font color="#008000"><u>http://www.oxygenxml.com/features/</u></font></a><br /><a href="http://www.oxygenxml.com/img/oxygen-mac.gif"><font color="#008000"><u>http://www.oxygenxml.com/img/oxygen-mac.gif</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/19151_OxygenXMLEdit.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/19151_OxygenXMLEdit.html</u></font></a></div><div>2004-10-19</div><div>Jigloo.GUI.Builder.v3.0.1<br />为EclipseJavaIDE和WebSphereStudio设计的插Ӟ可以用来创徏和管理Swing和SWTGUIcR?br /><a href="http://cloudgarden.com/jigloo/"><font color="#008000"><u>http://cloudgarden.com/jigloo/</u></font></a><br /><a href="http://cloudgarden.com/jigloo/images/screenshot4_sm.jpg"><font color="#008000"><u>http://cloudgarden.com/jigloo/images/screenshot4_sm.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/19038_JiglooGUIBuil.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/19038_JiglooGUIBuil.html</u></font></a></div><div>2004-10-13</div><div>Code.Pro.Studio.3.0.0<br />一ƾؓ那些使用IBMwebspherestuodio和eclipse开发环境的开发者设计的软g。能够让java的开发者有效开速的开发高质量的Y件。这ƾY件可以通过许多重复d来完成Y件的开发,同时能够极大的提高用L面和使开发活动流水线化。此ƾY仉成了CodeProAdisorQCodeProAgilityandCodeProBuild?br /><a href="http://www.instantiations.com/codepro/default.htm"><font color="#008000"><u>http://www.instantiations.com/codepro/default.htm</u></font></a><br /><a href="http://www.instantiations.com/codepro/imag...pstudio3-sm.gif"><font color="#008000"><u>http://www.instantiations.com/codepro/imag...pstudio3-sm.gif</u></font></a></div><div>2004-10-10</div><div>Window.Builder.Pro.2.1.1<br />一Ƒ֟于EclipseSWT技术上的双向javaGui设计软g。具备SWT设计以及Swing设计两个主要功能。该软g会被作ؓ一个插仉嵌入Eclipse以及其他一些兼容的IDEs中(WSSD,WSAD,WSED{等Q。新?.0版本支持Eclipse3.0?br /><a href="http://www.windowbuilderpro.com/"><font color="#008000"><u>http://www.windowbuilderpro.com/</u></font></a><br /><a href="http://www.instantiations.com/swt-designer...ts/designer.gif"><font color="#008000"><u>http://www.instantiations.com/swt-designer...ts/designer.gif</u></font></a></div><div>2004-10-04</div><div>Jigloo.GUI.Builder.v3.0.0<br />Jigloo.GUI.Builder是一个ؓEclipsejave和WebSphereStudio开发的插gQ能够创建出滚动控制和SWTGUI的效果界面?/div><div>Vi.plugin.for.Eclipse3.v1.86<br />ViPlugin可以在vi~辑器上d一个功能条Q这个是用于Eclipse3+的?/div><div>2004-10-03</div><div>Parasoft.JTest.v5.1.71.DC.20040912.WinNT2kXP<br />自动q行JAVA单元试和代码标准检查来帮助开发h员编写克L代码的工兗可分析c,然后生成单元试案例来包括最大的覆盖试Q发现未处理的异常ƈ校验需求?br />-自动的基本错误预Ԍ包括单元试和自动代码标准检?br />-生成q执行单元测试案?br />-提供了进行黑盒测试、模型测试和pȝ试的快速简单的途径<br />-识别q防未处理的运行时异常Q函数错误,内存泄露Q性能问题和安全弱?br />-对群或方案优先作试和报?br />-监控试的覆盖范?br />-自动回归试<br />-支持按比例压~设?br />-查超q?00个来自JAVA专家的编码规?br />-Ҏq反过200个编码规范的错误<br />-允许用户创徏自己的编码规?br />-可在组范围内管理共享测试文?br />-和IBMWebSphere和Eclipse集成<br />-支持BorlandQJBuilderQ?TogetherQControlCenterQ?和Ant</div><div>2004-09-23</div><div>Borland.Together.for.Eclipse.v6.3<br />最佳的E序分析设计工具Q提供实时的协同工作能力?br />·支持所有主要的UML囑Ş<br />充分利用UnifiedModelingLanguage(l一建模语言—UML)搭徏正确的架构,以便满你的业务目标。每一个Y仉目都需要一个蓝图,以保持整个小l向相同的方向前qƈ构徏正确的Y件。通过集成UML能力的方式,Together扩展了开发框Ӟ化了构徏软g的复杂过E?br />·TogetherLiveSource自动q行模型与代码的同步<br />使用同步的模型与代码Q允许进行更加有效的开发小l沟通与协作。同时的同步化让手工更新成ؓq去Q用相同的信息保持开发小l的信息更新。模型处于灵zȝ状态,不会q时Q这是因为开发小l做出的M变化L同时反映在代码与模型之中Q让开发小l更加高效、更加有效?br />·自动文档生成<br />保持开发小l专注于设计与实玎ͼ而不是拟制文档。Together提供了强大的、可以定制的文档生成能力Q其中包括多U文档格式与定制模板的能力。通过自动生成文档的方式,开发者可以集中精力搞软g开发,而小l领导随旉有所需要的信息?br />·支持业界标准的模?br />使用业界领先的模式着手开发工作,改善了架构的质量。Together支持标准的模式,比如GoF与J2EEQƈ且同时也提供了更改现有模式、创建新模式的能力。广泛的模式支持使得开发小l在来的项目中复用模式Q改善所有项目的架构质量?br />·使用审计定软g质量<br />审计为开发小l提供了在Y件开发的初期定质量Q强化企业标准的能力—在软g开发的初期Q开发小l还在编制Y件的代码呢。在分发之前定质量Q开发者可以改善代码的质量Q在代码转交QA组之前Q发现ƈ修复自己的错误。审计变量可以被定制q保存,q样开发小l就能制订代码标准,监视代码出认可规范的问题。审计也被用来改变开发者的个h代码~制风格Q以便符合企业的~码标准?br />·使用度量q行软g开发的量化<br />量度为开发小l提供了量软g目复杂E度、质量与规模的能力。通过量q对信息q行标准查,理人员能够知晓开发小l与开发过E的质量与效率,更好地进行当前与未来目的量化?br />·重构<br />在Together技术之中的大量重构Ҏ验证所有的pȝ变化都被正确C送到整个应用。所得到的结果便是代码不易出错,应用的质量得到改善?br />·Together与Eclipse的集?br />Eclipse是一U开放源代码的业界^収ͼTogether技术与Eclipse的集成ؓEclipse用户提供了一U熟悉的环境Q用来进行Y件开发。在Eclipse环境中,开发者可以利用TogetherEditionforEclipse之中的、领先的建模、设计与质量保证功能Q快速构建高质量的企业应用。通过在Eclipse本地开发用于TogetherEditionforEclipse的用h口,用户可受益于紧密的集成,q利用在同一个工具之中两U技术的优势?br /><a href="http://www.borland.com/together/index.html"><font color="#008000"><u>http://www.borland.com/together/index.html</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/16494_BorlandTogethe.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/16494_BorlandTogethe.html</u></font></a></div><div>2004-08-02</div><div>Clay.Database.Modeling.Pro.for.Eclipse.v1.0.5<br />作ؓ插gq行于Eclipse开发环境的数据库设计工兗通过直观的界面图形化地设计数据库模型。它可以通过逆向设计来根据现存数据库来设计新的数据库模型。更多地Q它q能生成适合你的数据库的SQL(DDL)代码?br /><a href="http://www.azzurri.jp/en/software/clay/index.jsp"><font color="#008000"><u>http://www.azzurri.jp/en/software/clay/index.jsp</u></font></a><br /><a href="http://www.azzurri.jp/en/software/clay/ima...y_eclipse_1.png"><font color="#008000"><u>http://www.azzurri.jp/en/software/clay/ima...y_eclipse_1.png</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/11208_ClayDatabaseM.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/11208_ClayDatabaseM.html</u></font></a></div><div>2004-07-28</div><div>Oxygen.XML.Editor.v4.2.Eclipse.plugin<br />OxygenXMLeditor是一Ƒ֟于Java的XML~辑器,支持XML,XSL,TXT,XSD,DTD文档Q能自行校验XML,XSL,XSD代码Q提C本错误。Oxygen能自动完成结束标{,代码高亮现实Q支持Unicode?br /><a href="http://www.oxygenxml.com/features/"><font color="#008000"><u>http://www.oxygenxml.com/features/</u></font></a><br /><a href="http://www.oxygenxml.com/img/oxygen-mac.gif"><font color="#008000"><u>http://www.oxygenxml.com/img/oxygen-mac.gif</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/10689_OxygenXMLEdit.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/10689_OxygenXMLEdit.html</u></font></a></div><div>2004-07-26</div><div>MC.Press.Eclipse.Step.by.Step<br />MCPress出版的《Eclipse循序渐近?Eclipse:StepbyStep)电子版,Eclipse是一个开放源代码的、基于Java的可扩展开发^台。就其本w而言Q它只是一个框架和一l服务,用于通过插glg构徏开发环境。幸q的是,Eclipse附带了一个标准的插g集,包括Java开发工PJavaDevelopmentToolsQJDTQ。该书包括了Eclipseq_开发的Ҏ面面Q可以手把手帮助你编写完整的可用的程序,q更好的立即各种基本概念<br /><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1583470441/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detail/-/1583470441/</u></font></a><br /><a href="http://images.amazon.com/images/P/15834704...SCMZZZZZZZ_.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/15834704...SCMZZZZZZZ_.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/10486_MCPressEclips.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/10486_MCPressEclips.html</u></font></a></div><div>2004-07-24</div><div>Window.Builder.Pro.v2.0.1<br />一Ƒ֟于EclipseSWT技术上的双向JavaGui设计软g。具备SWT设计以及Swing设计两个主要功能。该软g会被作ؓ一个插仉嵌入Eclipse以及其他一些兼容的IDEs中(WSSD,WSAD,WSED{等Q。新?.0版本支持Eclipse3.0?br /><a href="http://www.windowbuilderpro.com/"><font color="#008000"><u>http://www.windowbuilderpro.com/</u></font></a><br /><a href="http://www.instantiations.com/swt-designer...ts/designer.gif"><font color="#008000"><u>http://www.instantiations.com/swt-designer...ts/designer.gif</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/10310_WindowBuilder.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/10310_WindowBuilder.html</u></font></a></div><div>2004-07-20</div><div>XMLBuddy.PRO.v2.0.11<br />Eclipse插gQ提供XML~辑功能Q支持XML,DTD,XMLSchema,RELAXNG,RELAXNGcompactsyntax,XSLT<br /><a href="http://xmlbuddy.com/"><font color="#008000"><u>http://xmlbuddy.com/</u></font></a><br /><a href="http://xmlbuddy.com/2.0/screen.jpg"><font color="#008000"><u>http://xmlbuddy.com/2.0/screen.jpg</u></font></a><br /><a href="http://0daycheck.eastgame.net/0day/archives/9848_XMLBuddyPROv2.html"><font color="#008000"><u>http://0daycheck.eastgame.net/0day/archives/9848_XMLBuddyPROv2.html</u></font></a></div><div>2004-07-09</div><div>Compuware.DevPartner.Java.Edition.v3.0.3<br />快速高质量的开发javaE序的开发工LQ增强组件和软g的可靠性。可以针对个人定制不同的览数据H口和调试工兗?br />新的3.03版本h如下更新Q?br />-hEclipse插g<br />-可以在系l,开发环境和应用E序之间交互切换<br />-q有其他更新{?/div><div>2004-05-09</div><div>Manning.Publications.Company.Eclipse.in.Action.A.Guide.for.the.Java.Developer<br />电子?Eclipse实践Qjava开发h员指南?br /><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/</u></font></a><br />PE32_PIdp-schmoo2,TopRight,7,-26_SCMZZZZZZZ.jpg">http://images.amazon.com/images/P/1930110960.01.<u>PE32_PIdp-schmoo2,TopRight,7,-26_SCMZZZZZZZ</u>.jpg</div><div>Manning.Publications.Company.Eclipse.in.Action.A.Guide.for.the.Java.Developer<br />电子书《jave开发指南?br /><a href="http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detail/-/1930110960/</u></font></a><br /><a href="http://images.amazon.com/images/P/19301109...SCMZZZZZZZ_.jpg"><font color="#008000"><u>http://images.amazon.com/images/P/19301109...SCMZZZZZZZ_.jpg</u></font></a></div><div>2004-05-06</div><div>SignSoft_intelliBO_v3.6.2<br />一个中间g的应用,不仅仅执行JavaDataObjects标准(JDO)Q现在支持JDO标准1.0.1Q,而且实现的数据访问,所以称作:“intelligentBusinessObjects”。可集成于Eclipse及IBMWebsphereApllicationDeveloperIDE?/div><div>2004-04-27</div><div>OReilly.Eclipse.A.Java.Developers.Guide.eBook<br />《Java开发者指南?/div><div>2004-04-21</div><div>IBM.Redbooks.Eclipse.Development.Using.the.Graphical.Editing.Framework.and.the.Eclipse.Modeling.Framework.eBook<br />电子书,提供l那些具备良好知识基以及丰富l验的用EclipseSDK来开发插件代码的E序?用以校验插g的工作性能?br /><a href="http://publib-b.boulder.ibm.com/Redbooks.n...s/sg246302.html"><font color="#008000"><u>http://publib-b.boulder.ibm.com/Redbooks.n...s/sg246302.html</u></font></a></div><div>IBM.Redbooks.Eclipse.Development.Using.the.Graphical.Editing.Framework.and.the.Eclipse.Modeling.Framework.eBook<br />书名Q《用Graphical.Editing.Framework和Eclipse.Modeling.Frameworkq行Eclipse开发?br />作者:BillMooreetal.<br />出版C:IBMRedbooks<br />格式QCHM<br />分类Q计机/软g开?br />ISBNQ?738453161<br />内容介:<br />一本介l用GraphicalEditingFramework(GEF)和EclipseModelingFramework(EMF).q行Eclipseplugin开发的书?/div><div>2004-04-06</div><div>Rational.XDE.v2003.Developer.Plus.NET.Edition.Retail<br />RationalXDEDeveloper是一个十分完善的可视化设计和开发的环境Q它可以l合Rational支持的集成开发环境(IDEQ来使用Q比如Eclipseplatform,IBMWebSphereStudioApplicationDeveloper,MicrosoftVisualStudio.NET{。RationalXDEDeveloper可以在构Z业应用和WebZ心的解决Ҏ上开发h员提供支持。通过l合使用RationalXDEDeveloper的多U特性(比如Q代码的双向工程Q自动和按需的对代码和模型进行同步,模式引擎支持Q多模型的支持,数据库资逆向工程为数据模型,团队协作Q可选择的过E指南)可以减轻一些被需要的代码开发和设计的工作。这个是VisualStudio.NET版本的License?br /><a href="http://www.rational.com/products/xde/index.jsp"><font color="#008000"><u>http://www.rational.com/products/xde/index.jsp</u></font></a></div><div>2003-12-29</div><div>Addison.Wesley.Contributing.To.Eclipse.Principles.Patterns.And.Plug-Ins.eBook---1<br />讲述在Eclipse(一U正在兴L软g开发环?下进行插件开发的电子图书</div><div>2003-12-28</div><div>Addison.Wesley.Contributing.To.Eclipse.Principles.Patterns.And.Plug-Ins.eBook---2<br />出版QAddison-WesleyPubCoQ作者:ErichGamma,KentBeckQISBNQ?321205758?br />一本关于Eclipse的书。这本书不仅仅教你怎么做而且使你完全理解Eclipse?br /><a href="http://www.amazon.com/exec/obidos/tg/detai...l/-/0321205758/"><font color="#008000"><u>http://www.amazon.com/exec/obidos/tg/detai...l/-/0321205758/</u></font></a></div><div>2003-11-14</div><div>Addison.Wesley.Eclipse.Modeling.Framework.A.Developers.Guide.eBook<br />电子书,EclipseModelingFramework模型构架可以使Java,XML,和UML语言开发者统一h使用令h惊讶的模板快速构建健L应用E序,是一本Y件开发h员指g<br /><a href="http://www.amazon.com/exec/obidos/ASIN/013...1308053-5737658"><font color="#008000"><u>http://www.amazon.com/exec/obidos/ASIN/013...1308053-5737658</u></font></a></div><img src ="http://www.tkk7.com/limq/aggbug/40329.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2006-04-10 21:43 <a href="http://www.tkk7.com/limq/archive/2006/04/10/40329.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Log4J 最佛_践之全能配置文g(转)http://www.tkk7.com/limq/archive/2006/04/10/40328.htmllimqlimqMon, 10 Apr 2006 13:41:00 GMThttp://www.tkk7.com/limq/archive/2006/04/10/40328.htmlhttp://www.tkk7.com/limq/comments/40328.htmlhttp://www.tkk7.com/limq/archive/2006/04/10/40328.html#Feedback0http://www.tkk7.com/limq/comments/commentRss/40328.htmlhttp://www.tkk7.com/limq/services/trackbacks/40328.html


log4j.rootLogger=DEBUG,CONSOLE,A1,im
log4j.addivity.org.apache=true



# 应用于控制台

log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=DEBUG
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n


#应用于文?

log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.File=file.log
log4j.appender.FILE.Append=false
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
# Use this layout for LogFactor 5 analysis



# 应用于文件回?

log4j.appender.ROLLING_FILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLING_FILE.Threshold=ERROR
log4j.appender.ROLLING_FILE.File=rolling.log
log4j.appender.ROLLING_FILE.Append=true
log4j.appender.ROLLING_FILE.MaxFileSize=10KB
log4j.appender.ROLLING_FILE.MaxBackupIndex=1
log4j.appender.ROLLING_FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLING_FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


#应用于socket
log4j.appender.SOCKET=org.apache.log4j.RollingFileAppender
log4j.appender.SOCKET.RemoteHost=localhost
log4j.appender.SOCKET.Port=5001
log4j.appender.SOCKET.LocationInfo=true
# Set up for Log Facter 5
log4j.appender.SOCKET.layout=org.apache.log4j.PatternLayout
log4j.appender.SOCET.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD]%n%c[CATEGORY]%n%m[MESSAGE]%n%n


# Log Factor 5 Appender
log4j.appender.LF5_APPENDER=org.apache.log4j.lf5.LF5Appender
log4j.appender.LF5_APPENDER.MaxNumberOfRecords=2000



# 发送日志给邮g

log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold=FATAL
log4j.appender.MAIL.BufferSize=10
log4j.appender.MAIL.From=web@www.wuset.com
log4j.appender.MAIL.SMTPHost=www.wusetu.com
log4j.appender.MAIL.Subject=Log4J Message
log4j.appender.MAIL.To=web@www.wusetu.com
log4j.appender.MAIL.layout=org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n



# 用于数据?
log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL=jdbc:mysql://localhost:3306/test
log4j.appender.DATABASE.driver=com.mysql.jdbc.Driver
log4j.appender.DATABASE.user=root
log4j.appender.DATABASE.password=
log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n')
log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n


log4j.appender.A1=org.apache.log4j.DailyRollingFileAppender
log4j.appender.A1.File=SampleMessages.log4j
log4j.appender.A1.DatePattern=yyyyMMdd-HH'.log4j'
log4j.appender.A1.layout=org.apache.log4j.xml.XMLLayout

#自定义Appender

log4j.appender.im = net.cybercorlin.util.logger.appender.IMAppender

log4j.appender.im.host = mail.cybercorlin.net
log4j.appender.im.username = username
log4j.appender.im.password = password
log4j.appender.im.recipient = corlin@cybercorlin.net

log4j.appender.im.layout=org.apache.log4j.PatternLayout
log4j.appender.im.layout.ConversionPattern =[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n

limq 2006-04-10 21:41 发表评论
]]>
AcegiQhibernate 动态实现基于角色的权限理 http://www.tkk7.com/limq/archive/2006/01/19/28585.htmllimqlimqWed, 18 Jan 2006 18:16:00 GMThttp://www.tkk7.com/limq/archive/2006/01/19/28585.htmlhttp://www.tkk7.com/limq/comments/28585.htmlhttp://www.tkk7.com/limq/archive/2006/01/19/28585.html#Feedback27http://www.tkk7.com/limq/comments/commentRss/28585.htmlhttp://www.tkk7.com/limq/services/trackbacks/28585.html阅读全文

limq 2006-01-19 02:16 发表评论
]]>
四舍五入保留数后两?/title><link>http://www.tkk7.com/limq/archive/2005/09/21/13694.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Wed, 21 Sep 2005 15:59:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2005/09/21/13694.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/13694.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2005/09/21/13694.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/13694.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/13694.html</trackback:ping><description><![CDATA[<P> </P> <DIV style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><SPAN style="COLOR: #008080"> 1</SPAN> <SPAN style="COLOR: #008000">/**</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080"> 2</SPAN> <SPAN style="COLOR: #008000"> * Contains static utility methods.<BR></SPAN><SPAN style="COLOR: #008080"> 3</SPAN> <SPAN style="COLOR: #008000"> </SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080"> 4</SPAN> <SPAN style="COLOR: #000000"></SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">class</SPAN><SPAN style="COLOR: #000000"> BOUtils {<BR></SPAN><SPAN style="COLOR: #008080"> 5</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080"> 6</SPAN> <SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">public</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">static</SPAN><SPAN style="COLOR: #000000"> Double getRoundedDouble( </SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000"> unroundedValue ){<BR></SPAN><SPAN style="COLOR: #008080"> 7</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> Get the integer portion of the value</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080"> 8</SPAN> <SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000"> intPortion </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> Math.floor( unroundedValue );<BR></SPAN><SPAN style="COLOR: #008080"> 9</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">10</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> Get the unrounded decimal portion</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">11</SPAN> <SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000"> unroundedDecimalPortion </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> ( unroundedValue </SPAN><SPAN style="COLOR: #000000">-</SPAN><SPAN style="COLOR: #000000"> intPortion );<BR></SPAN><SPAN style="COLOR: #008080">12</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">13</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000"> ALERT - This next code interferes with I18N. We eventually need   </SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">14</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000">         to change this not assume only round to 2 decimal places. </SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">15</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">16</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">/*</SPAN><SPAN style="COLOR: #008000"> Multiply the decimal places by 100, which shitfs the decimal point<BR></SPAN><SPAN style="COLOR: #008080">17</SPAN> <SPAN style="COLOR: #008000">    /* two places to the left. Then round it so that we get a round to<BR></SPAN><SPAN style="COLOR: #008080">18</SPAN> <SPAN style="COLOR: #008000">    /* two decimal places. For example, if we started with 17.655 and stripped<BR></SPAN><SPAN style="COLOR: #008080">19</SPAN> <SPAN style="COLOR: #008000">    /* off the int portion, which left .655. After we shift, we are left with<BR></SPAN><SPAN style="COLOR: #008080">20</SPAN> <SPAN style="COLOR: #008000">    /* 65.5. Then a round will gives us 66. We can then put it all back<BR></SPAN><SPAN style="COLOR: #008080">21</SPAN> <SPAN style="COLOR: #008000">    /* together </SPAN><SPAN style="COLOR: #008000">*/</SPAN><SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">22</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000"> roundedDecimalPortion </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> Math.round( unroundedDecimalPortion </SPAN><SPAN style="COLOR: #000000">*</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">100</SPAN><SPAN style="COLOR: #000000"> );<BR></SPAN><SPAN style="COLOR: #008080">23</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">24</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> Shift the decimal point back two places to the right</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">25</SPAN> <SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">    roundedDecimalPortion </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> roundedDecimalPortion </SPAN><SPAN style="COLOR: #000000">/</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #000000">100</SPAN><SPAN style="COLOR: #000000">;<BR></SPAN><SPAN style="COLOR: #008080">26</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">27</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #008000">//</SPAN><SPAN style="COLOR: #008000"> Add the int portion and decimal portions back together</SPAN><SPAN style="COLOR: #008000"><BR></SPAN><SPAN style="COLOR: #008080">28</SPAN> <SPAN style="COLOR: #008000"></SPAN><SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #0000ff">double</SPAN><SPAN style="COLOR: #000000"> total </SPAN><SPAN style="COLOR: #000000">=</SPAN><SPAN style="COLOR: #000000"> intPortion </SPAN><SPAN style="COLOR: #000000">+</SPAN><SPAN style="COLOR: #000000"> roundedDecimalPortion;<BR></SPAN><SPAN style="COLOR: #008080">29</SPAN> <SPAN style="COLOR: #000000"><BR></SPAN><SPAN style="COLOR: #008080">30</SPAN> <SPAN style="COLOR: #000000">    </SPAN><SPAN style="COLOR: #0000ff">return</SPAN><SPAN style="COLOR: #000000"> </SPAN><SPAN style="COLOR: #0000ff">new</SPAN><SPAN style="COLOR: #000000"> Double( total );<BR></SPAN><SPAN style="COLOR: #008080">31</SPAN> <SPAN style="COLOR: #000000">  }<BR></SPAN><SPAN style="COLOR: #008080">32</SPAN> <SPAN style="COLOR: #000000">}</SPAN></DIV><img src ="http://www.tkk7.com/limq/aggbug/13694.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2005-09-21 23:59 <a href="http://www.tkk7.com/limq/archive/2005/09/21/13694.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Jakarta Commons:巧用cdlgQ{Q?/title><link>http://www.tkk7.com/limq/archive/2005/09/21/13611.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Wed, 21 Sep 2005 02:03:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2005/09/21/13611.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/13611.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2005/09/21/13611.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/13611.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/13611.html</trackback:ping><description><![CDATA[Jakarta Commons是Jakarta的子目Q它创徏和维护着许多独立软g包,q些包一般与其他框架或品无养I其中攉了大量小型、实用的lgQ大部分面向服务器端~程?<br /><br />  Commons的包分成两部分:SandboxQCommons代码库。Sandbox是一个测试^収ͼ用来验各U设惟뀁计划。本文介l的lg属于Commons代码库,文章展C各个组件的功能、适用场合Qƈ通过单的例子介绍其用法?<br /><br />  <b>一、概q?/b><br /><br />  可重用性是Jakarta Commons目的灵所在。这些包在设计阶D就已经考虑了可重用性问题。其中一些包Q例如Commons里面用来记录日志的Logging包,最初是为其他项目设计的Q例如Jakarta Struts目Q当Z发现q些包对于其他项目也非常有用Q能够极大地帮助其他目的开发,他们军_些包构造一?公共"的存放位|,q就是Jakarta Commons目?<br /><br />  Z真正提高可重用性,每一个包都必M依赖于其他大型的框架或项目。因此,Commons目的包基本上都是独立的Q不仅是相对于其他项目的独立Q而且相对于Commons内部的大部分其他包独立。虽然存在一些例外的情况Q例如Betwixt包要用到XML APIQ但l大部分只用最基本的APIQ其主要目的是要能够通过单的接口方便地调用?<br /><br />  不过׃崇尚z,许多包的文档变得q于陋,~Zl护和支持,甚至有一部分q有错误的链接,文档也少得可怜。大部分的包需要我们自己去扑և其用法,甚至有时q需要我们自己去分析光用场合。本文将逐一介绍q些包,希望能够帮助你迅速掌握这一U篏了许多h心血的免费代码库?<br /><br />  说明QJakarta Commons?a href="http://commons.apache.org/" target="_blank">Apache Commons</a>是不同的Q后者是Apache Software Foundation的一个顶层项目,前者则是Jakarta目的一个子目Q同是也是本文要讨论的主角。本文后面凡是提到Commons的地斚w是指Jakarta的Commons?<br /><br />  Z便于说明Q本文把Commons目十八个成品的组Ӟ排除了EL、Latka和JexlQ分?c,如下表所C?<br /><br /><br />参?<a href="/sean/archive/2005/08.html">http://www.tkk7.com/sean/archive/2005/08.html</a><br /><br /><center> </center><br /><br />  必须指出的是Q这U分cd是ؓ了方便文章说明,Commons目里面实际上ƈ不存在这U分c,同时q些分类的边界有时也存在一定的重叠?<br /><br />  本文首先介绍Web相关cd其他c里面的lgQ下一文章将涉及XML相关、包装这两类Q最后一文章专门介l属于工L的包?<br /><br />  <b>二、其他类</b><br /><br />  CLI、Discovery、Lang和Collections包归入其他类Q这是因为它们都各自针对某个明确、实用的目标,可谓专而精?<br /><br />  <b>2.1 CLI</b><br /><br />  ?概况QCLI即Command Line InterfaceQ也是"命o行接?Q它为JavaE序讉K和解析命令行参数提供了一U统一的接口?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/cli/index.html" target="_blank">主页</a>Q?a href="http://www.apache.org/dist/jakarta/commons/discovery/binaries/commons-discovery-0.2.zip" target="_blank">二进?/a>Q?a href="http://www.apache.org/dist/jakarta/commons/discovery/source/commons-discovery-0.2-src.zip" target="_blank">源代?/a><br /><br />  ?何时适用Q当你需要以一U一致的、统一的方式访问命令行参数之时?<br /><br />  ?CZ应用QCLIDemo.java。CLASSPATH中必d含commons-cli-1.0.jar?<br /><br />  ?说明Q?<br /><br />  有多次你不得不Z个新的应用程序重新设计新的命令行参数处理方式Q如果能够只用某个单一的接口,l一完成诸如定义输入参数Q是否ؓ强制参数Q数D是字W串Q等{)、根据一pd规则分析参数、确定应用要采用的\径等dQ那该多好!{案在CLI?<br /><br />  在CLI中,每一个想要在命o中指定的参数都是一个Option对象。首先创Z个Options对象Q将各个Option对象加入Options对象Q然后利用CLI提供的方法来解析用户的输入参数。Option对象可以要求用户必须输入某个参数Q例如必d命o行提供文件名字。如果某个参数是必须的,创徏Option对象的时候就要显式地指定?<br /><br />  下面是用CLI的步骤?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// ? // ? 创徏一个OptionsQ? Options options = new Options(); options.addOption("t", false, "current time"); // ? // ?创徏一个解析器Q分析输入: CommandLineParser parser = new BasicParser(); CommandLine cmd; try { cmd = parser.parse(options, args); } catch (ParseException pe) { usage(options); return; } // ? // ?最后就可以Ҏ用户的输入,采取相应的操作: if (cmd.hasOption("n")) { System.err.println("Nice to meet you: " + cmd.getOptionValue('n')); }</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  q就是用CLI的完整过E了。当ӞCLIq提供了其他高选项Q例如控制格式和解析q程{,但基本的使用思\仍是一致的。请参见本文最后提供的CZE序?<br /><br />  <b>2.2 Discovery</b><br /><br />  ?概况QDiscoverylg是发现模式(Discovery PatternQ的一个实玎ͼ它的目标是按照一U统一的方式定位和实例化类以及其他资源?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/discovery/" target="_blank">主页</a>Q?a href="http://www.apache.org/dist/jakarta/commons/discovery/binaries/commons-discovery-0.2.zip" target="_blank">二进?/a>Q?a href="http://www.apache.org/dist/jakarta/commons/discovery/source/commons-discovery-0.2-src.zip" target="_blank">源代?/a>?<br /><br />  ?何时适用Q当你想用最佳的法在JavaE序中查找Java接口的各U实C时?<br /><br />  ?应用实例QDiscoveryDemo.javaQMyInterface.javaQMyImpl1.javaQMyImpl2.javaQMyInterface。要求CLASSPATH中必d含commons-discovery.jar和commons-logging.jar?<br /><br />  ?说明Q?<br /><br />  Discovery的意思就?发现"Q它试图用最佳的法查找某个接口的所有已知的实现。在使用服务的场合,当我们想要查找某个服务的所有已知的提供者时QDiscoverylg其有用?<br /><br />  考虑一下这U情形:我们为某个特别复杂的d~写了一个接口,所有该接口的实现都用各不相同的方式来完成这个复杂Q务,最l用户可以根据需要来选择完成d的具体方式。那么,在这U情形下Q最l用户应该用什么办法来扑և接口的所有可用实玎ͼ卛_能的完成d的方式)呢? <br /><br />  上面描述的情形就是所谓的服务-服务提供者体pR服务的功能由接口描qͼ服务提供者则提供具体的实现。现在的问题是最l用戯用某U办法来Lpȝ中已l安装了哪些服务提供者。在q种情Ş下,Discoverylg很有用了,它不仅可以用来查N些实C特定接口的类Q而且q可以用来查找资源,例如囄或其他文件等。在执行q些操作ӞDiscovery遵从Sun的服务提供者体pL定义的规则?<br /><br />  ׃q个原因Q用Discoverylg实带来许多方便。请读者参阅本文后面示例程序中的接口MyInterface.java和两个实现类MyImpl1.java、MyImple2.javaQ了解下面例子的l节。在使用Discovery的时候要提供MyInterface文gQ把它放入META-INF/services目录Q注意该文g的名字对应接口的完整限定名称QFully Qualified NameQ,如果接口属于某个包,该文件的名字也必ȝ应地改变?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// ? // ?创徏一个类装入器的实例? ClassLoaders loaders = ClassLoaders.getAppLoaders(MyInterface.class, getClass(), false); // ? // ?用DiscoverClass的实例来查找实现cR? DiscoverClass discover = new DiscoverClass(loaders); // ? // ?查找实现了指定接口的c: Class implClass = discover.find(MyInterface.class); System.err.println("Implementing Provider: " + implClass.getName());</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  q行上面的代码,可以得到在MyInterface文g中注册的cR再ơ提醒,如果你的实现是封装在包里面的Q在q里注册的名字也应该作相应地修改Q如果该文g没有攑֜正确的位|,或者指定名字的实现cM能找到或实例化,E序抛出DiscoverExceptionQ表C找不到W合条g的实现。下面是MyInterface文g内容的一个例子:MyImpl2 # Implementation 2?<br /><br />  当然Q实现类的注册办法ƈ非只有这么一U,否则的话Discovery的实用性就要大打折扣了Q实际上Q按照Discovery内部的类查找机制Q按照这U方法注册的cd是Discovery最后找到的cR另一U常用的注册Ҏ是通过pȝ属性或用户定义的属性来传递实现类的名字,例如Q放弃META-INF/services目录下的文gQ改为执行java -DMyInterface=MyImpl1 DiscoveryDemo命o来运行示例程序,q里的系l属性是接口的名字,值是该接口的提供者,q行的结果是完全一L?<br /><br />  Discoveryq可以用来创建服务提供者的(singleton)实例q调用其ҎQ语法如下:((MyInterface)discover.newInstance(MyInterface.class)).myMethod();。注意在q个例子中,我们q不知道到底哪一个服务提供者实CmyMethodQ甚x们根本不必关心这一炏V具体的情Ş与运行这D代码的方式以及q行环境中已l注册了什么服务提供者有养I在不同的环境下运行,实际得到的服务提供者可能不同?<br /><br />  <b>2.3 Lang</b><br /><br />  ?概况QLang是java.lang的一个扩展包Q增加了许多操作String的功能,另外q支持C风格的枚N?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/lang.html" target="_blank">主页</a>Q?a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-lang/v1.0.1/commons-lang-1.0.1.zip" target="_blank">二进?/a>Q?a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-lang/v1.0.1/commons-lang-1.0.1-src.zip" target="_blank">源代?/a>?<br /><br />  ?何时适用Q当java.lang包提供的Ҏ未能满需要,惌更多的功能来处理String、数值和System属性时Q还有,当你惌使用C风格的枚N时?<br /><br />  ?CZ应用QLangDemo.javaQMortgage.javaQOnTV.java。CLASSPATH中必d含commons-lang.jar?<br /><br />  ?说明Q?<br /><br />  q个包提供了许多Z方便目的而提供的ҎQ它们中的大多数是静态的Q简化了日常~码工作。StringUtilscL其中的一个代表,它得开发者能够超标准的java.lang.String包来处理字符丌Ӏ用这些方法很单,通常只要在调用静态方法时提供适当的参数就可以了。例如,如果要将某个单词的首字符改ؓ大写Q只需调用QStringUtils.capitalise("name")Q调用的输出l果是Name。请览StringUtils API文档了解其他静态方法,也许你会扑ֈ一些可以直接拿来用的代码。本文提供的CZE序C了其中一些方法的使用?<br /><br />  另一个值得注意的类是RandomStringUtilsQ它提供了生成随机字W串的方法,用来创徏随机密码实在太方便了?<br /><br />  NumberUtilscL供了处理数值数据的ҎQ许多方法值得一用,例如L最大、最数的方法,String转换成数值的ҎQ等{。NumberRange和CharRangecd别提供了创徏和操作数D围、字W范围的Ҏ?<br /><br />  Builder包里的类提供了一些特D的ҎQ可用来构造类的toString、hashCode、compareTo和equalsҎQ其基本思\是构造出cȝ高质量的toString、hashCode、compareTo和equalsҎQ从而免M用户自己定义q些Ҏ之劳Q只要调用一下Builder包里面的Ҏ可以了。例如,我们可以用ToStringBuilder来构造出cȝtoString描述Q如下例所C: <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>public class Mortgage { private float rate; private int years; .... public String toString() { return new ToStringBuilder(this). append("rate", this.rate). append("years", this.years). toString(); } }</ccid_code></pre></td></tr></tbody></table><span id="dzpx9jv" class="myp11"><font id="zoom">  使用q类Ҏ有什么好处呢Q显Ӟ它得我们有可能通过一U统一的方式处理所有数据类型。所有BuilderҎ的用法都和上例相伹{?<br /><br />  Java没有C风格的枚NQؓ此,lang包提供了一个类型安全的EnumcdQ填补了I白。EnumcL抽象的,如果你要创徏枚D量,p扩展EnumcR下面的例子清楚地说明了Enum的用法?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>import org.apache.commons.lang.enum.Enum; import java.util.Map; import java.util.List; import java.util.Iterator; public final class OnTV extends Enum { public static final OnTV IDOL= new OnTV("Idol"); public static final OnTV SURVIVOR = new OnTV("Survivor"); public static final OnTV SEINFELD = new OnTV("Seinfeld"); private OnTV(String show) { super(show); } public static OnTV getEnum(String show){ return (OnTV) getEnum(OnTV.class, show); } public static Map getEnumMap() { return getEnumMap(OnTV.class); } public static List getEnumList() { return getEnumList(OnTV.class); } public static Iterator iterator() { return iterator(OnTV.class); } }</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  以后我们可以按照下面的方式使用枚D变量QOnTV.getEnum("Idol")。该调用从前面创建的枚D数据cdq回Idol。这个例子比较简单,实际上Enumc还提供了许多有用的ҎQ请参见本文后面提供的完整实例?<br /><br />  <b>2.4 Collections</b><br /><br />  ?概况Q扩展了Java Collection框架Q增M新的数据l构、P代机制和比较操作W?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/collections.html" target="_blank">主页</a>Q?a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-collections/v2.1/commons-collections-2.1.zip" target="_blank">二进?/a>Q?a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-collections/v2.1/commons-collections-2.1-src.zip" target="_blank">源代?/a>?<br /><br />  ?何时适用Q几乎所有需要操作数据结构的重要Java开发项目都可以使用Collections API。和Java的标准实现相比,Collections API有着诸多优势?<br /><br />  ?CZ应用QCollectionsDemo.java。要求CLASSPATH中包含commons-collections.jar?<br /><br />  ?说明Q?<br /><br />  要在有限的文章篇q之内详地介绍 Collections API实在是太困难了,不过q里仍将늛大多数最重要的类Q希望能够引起你的兴,认真了解一下其余的cRCollections本n的文档也提供了许多资料ƈ解释了每一个类的用法?<br /><br />  Bag接口扩展标准的Java CollectionQ允许生成计数器来跟tBag里面的所有元素。当你想要跟t进出某个集合的元素的LӞBag是非常有用的。由于Bag本n是一个接口,所以实际用的应该是实C该接口的c,例如HashBag或TreeBag--从这些类的名字也可以看出QHashBag实现的是一个HashMap的BagQ而TreeBag实现的是TreeMap的Bag。Bag接口中两个最重要的方法是QgetCount(Object o)Q用来返回Bag里面特定对象的出现次敎ͼuniqueSet()Q返回所有唯一元素?<br /><br />  Buffer接口允许按照预定义的ơ序删除集合中的对象Q删除次序可以是LIFOQLast In First OutQ后q先出)Q或FIFOQFirst In First OutQ先q先出)Q另外还可以是自定义的次序。下面来看看如何实现一个BufferQ按照自然次序删除元素?<br /><br />  BinaryHeapcdCBuffer接口Q能够按照自然次序删除元素。如果要颠倒次序,则必M入一个falseQ告诉Heap采用自然ơ序的逆序?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>BinaryHeap heap = new BinaryHeap(); // ? // 元素加入该Heap heap.add(new Integer(-1)); heap.add(new Integer(-10)); heap.add(new Integer(0)); heap.add(new Integer(-3)); heap.add(new Integer(5)); //? // 删除一个元? heap.remove();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  调用该Heap的removeQ按照自然次序,元素集合中的-10被删除。如果我们要求按照逆序排序Q则被删除的是5?<br /><br />  FastArrayList、FastHashMap和FastTreeMapc能够按照两U模式操作,越了与它们对应的标准Collection。第一U模式是"慢模?Q类的修Ҏ作(d、删除元素)是同步的。与此相对,另一U模式是"快模?Q对q些cȝ讉K假定为只L作,因此不需要同步,速度较快。在快模式中Q结构性的改动通过下列方式完成Q首先克隆现有的c,修改克隆得到的类Q最后用克隆得到的类替换原有的类。FastArrayList、FastHashMap和FastTreeMapcȝ别适合于那U初始化之后大部分操作都是只L作的多线E环境?<br /><br />  iterators包ؓ各种集合和对象提供标准Java Collection包没有提供的q代器。本文的CZ应用C了ArrayIteratorQ通过q代方式讉KArray的内宏Viterators包里面各UP代器的用法基本上与标准Javaq代器一栗?<br /><br />  最后,comparators包提供了一些实用的比较W。所谓比较符其实也是一个类Q它定义的是如何比较两个属于同一cȝ对象Q决定它们的排序ơ序。例如,在前面提到的BuffercMQ我们可以定义自q比较W,用自定义的比较符来决定元素的排序ơ序Q而不是采用元素的自然排序ơ序。下面来看看具体的实现经q?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// ? // ?创徏一个BinaryHeapc,但这一ơ参C // 指定NullComparator。NullComparator比较 // null与其他对象,ҎnullsAreHigh标记? // 判断null值比其他对象大还是小Q如? // nullsAreHigh的值是falseQ则认ؓnull要比 // 其他对象? BinaryHeap heap2 = new BinaryHeap (new NullComparator(false)); // ? // ?一些数据(包括几个null|加入heapQ? heap2.add(null); heap2.add(new Integer("6")); heap2.add(new Integer("-6")); heap2.add(null); // ? // ?最后删除一个元素,Bag包含的null减? // 一个,因ؓnull要比其他对象? heap2.remove();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  有关其他cCommonslg的介l就到这里结束。如果你想了解更多细节信息,请参见API文档Q最好再看看q些包的源代码?<br /><br />  <b>三、Webc?/b><br /><br />  Webcȝlg用来执行与Web相关的Q务?<br /><br />  <b>3.1 FileUpload</b><br /><br />  ?概况Q一个可以直接用的文g上蝲lg?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/fileupload/index.html" target="_blank">主页</a>。由于这个组件尚未正式发布,今年二月发布的Beta版又有许多BUGQ所以徏议从<a href="http://cvs.apache.org/builds/jakarta-commons/nightly/commons-fileupload/" target="_blank">nightly builds</a>下蝲最新的版本?<br /><br />  ?何时适用Q当你想要在Java服务器环境中加入一个易用、高性能的文件上载组件之时?<br /><br />  ?CZ应用Qfileuploaddemo.jspQfileuploaddemo.htmQ和msg.jsp。要求服务器端应用目录的WEB-INF/lib下面有commons-fileupload-1.0-dev.jar?<br /><br />  ?说明Q?<br /><br />  FileUploadlg解决了常见的文g上蝲问题。它提供了一个易用的接口来管理上载到服务器的文gQ可用于JSP和Servlet之中。FileUploadlg遵从RFC1867Q它分析输入hQ向应用E序提供一pd上蝲到服务器的文件。上载的文g可以保留在内存中Q也可以攑օ一个时位|(允许配置一个表C文件大的参数Q如果上载的文g过了该参数指定的大,则把文g写入一个时位|)。另外还有一些参数可供配|,包括可接受的最大文件、时文件的位置{?<br /><br />  下面介绍一下用FileUploadlg的步骤?<br /><br />  首先创徏一个HTML面。注意,凡是要上载文件的表单都必设|enctype属性,且属性的值必Lmultipart/form-dataQ同时请求方法必LPOST。下面的表单除了上蝲两个文gQ另外还有一个普通的文本输入框: <br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code><form name="myform" action="fileuploaddemo.jsp" method="post" enctype="multipart/form-data"> 输入你的名字:<br /><input size="15" name="name" /><br /> 囑Ş:<br /><input type="file" name="myimage" /><br /> 文g:<br /><input type="file" name="myfile" /><br /><br /><input type="submit" value="Submit your files" name="Submit" /></form></ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  接下来创建JSP面?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// ? // ?查输入请求是否ؓmultipart的表单数据? boolean isMultipart = FileUpload. isMultipartContent(request); // ? // ?h创徏一个句柄,通过它来解析h。执? // 解析后,所有的表单目都保存在一个List中? DiskFileUpload upload = new DiskFileUpload(); // 通过句柄解析hQ解析得到的目保存在一个List? List items = upload.parseRequest(request); // ? // ?通过循环依次获得List里面的文仉目。要区分表示 // 文g的项目和普通的表单输入目Q用isFormField() // Ҏ。根据处理请求的要求Q我们可以保存上载的? // Ӟ或者一个字节一个字节地处理文g内容Q或者打 // 开文g的输入流? Iterator itr = items.iterator(); while(itr.hasNext()) { FileItem item = (FileItem) itr.next(); // 查当前的目是普通的表单元素Q还是一个上载的文g if(item.isFormField()) { // 获得表单域的名字 String fieldName = item.getFieldName(); // 如果表单域的名字是name? if(fieldName.equals("name")) request.setAttribute("msg", "Thank You: " + item.getString()); } else { // 该项目是一个上载的文gQ把它保存到盘? // 注意item.getName() // 会返回上载文件在客户端的完整路径名称Q这g是一个BUG? // 册个问题,q里使用了fullFile.getName()? File fullFile = new File(item.getName()); File savedFile = new File (getServletContext().getRealPath("/"), fullFile.getName()); item.write(savedFile); } }</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  我们可以通过上蝲句柄的upload.setSizeMax来限制上载文件的大小。当上蝲文g的大超q允许的值时Q程序将遇到异常。在上面的例子中Q文件大的限制值是-1Q表C允怸载Q意大的文g?<br /><br />  q有其他一些略有变化的使用形式Q正如前面所指出的,我们可以在上载的文g上打开一个输入流Q或者让它们ȝ在内存中直至I间占用辑ֈ一定的限制|或者在判断文gcd的基上,以String或Byte数组的Ş式获取其内容Q或者直接删除文件。这一切都只要使用FileItemcL供的Ҏ可以方便地做到QDefaultFileItem是FileItem的一个实玎ͼ?/font></span><span id="t71x7fz" class="myp11"><font id="zoom">  <b>3.2 HttpClient</b><br /><br />  ?概况Q这个API扩展了java.net包,提供了模拟浏览器的功能?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/httpclient/index.html" target="_blank">主页</a>Q?a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-httpclient/v2.0/commons-httpclient-2.0-beta1.zip" target="_blank">二进?/a>Q?a href="http://jakarta.apache.org/builds/jakarta-commons/release/commons-httpclient/v2.0/commons-httpclient-2.0-beta1-src.zip" target="_blank">源代?/a>?<br /><br />  ?何时适用Q当你要构造Web览器的功能Q当你的应用需要一U高效的办法q行HTTP/HTTPS通信时?<br /><br />  ?CZ应用QHttpClientDemo.java。要求CLASSPATH中有commons-httpclient.jarQcommon-logging.jar。要求用JDK 1.4或更高版本?<br /><br />  ?说明Q?<br /><br />  HttpClient扩展和增Z标准java.net包,是一个内容广泛的代码库,功能极其丰富Q能够构造出各种使用HTTP协议的分布式应用Q或者也可以嵌入到现有应用,为应用增加访问HTTP协议的能力。在CommonsE_版中QHttpClient的文档似乎要比其他包更完善一些,而且q带有几个实例。下面我们通过一个简单的例子来了解如何提取一个Web面QHttpClient文档中也有一个类似的例子Q我们将扩充那个例子使其支持SSL。注意本例需要JDK 1.4支持Q因为它要用到Java Secure Socket Connection库,而这个库只有JDK 1.4及更高的版本才提供?<br /><br />  ?首先定一个可以通过HTTPS下蝲的页面,本例使用的是https://www.paypal.com/。同时确?JAVA_HOME%/jre/lib/security/java.security文g包含了下面这行代码:security.provider.2=com.sun.net.ssl.internal.ssl.Provider?<br /><br />  除了q些讄之外QHTTPSq接的处理方式没有其他特别的地方--臛_对于本例来说如此。不q,如果q程|站使用的根证书不被你用的Java认可Q则首先必须导入它的证书?<br /><br />  ?创徏一个HttpClient的实例。HttpClientcd以看成是应用的主驱动E序Q所有针对网l的功能都依赖于它。HttpClientc需要一个Connection Manager来管理连接。HttpConnectionManager允许我们创徏自己的连接管理器Q或者,我们也可以直接用内建的SimpleHttpConnectionManager或MultiThreadedHttpConnectionManagercR如果在创徏HttpClient时没有指定连接管理器QHttpClient默认使用SimpleHttpConnectionManager?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// 创徏一个HttpClient的实? HttpClient client = new HttpClient();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  ?创徏一个HttpMethod的实例,即确定与q程服务器的通信要采用哪U传输方式,HTTP允许采用的传输方式包括:GETQPOSTQPUTQDELETEQHEADQOPTIONSQ以及TRACE。这些传输方式分别作Z个独立的cd玎ͼ但所有这些类都实现HttpMethod接口。在本例中,我们使用的是GetMethodQ创建GetMethod实例时在参数中指定我们想要GET的URL?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// 创徏一个HttpMethod的实? HttpMethod method = new GetMethod(url);</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  ?执行HttpMethod定义的提取操作。执行完毕后QexecuteMethodҎ返回远E服务器报告的状态代码。注意executeMethod属于HttpClientQ而不是HttpMethod?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// 执行HttpMethod定义的提取操? statusCode = client.executeMethod(method);</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  ?d服务器返回的应答。如果前面的q接操作p|Q程序将遇到HttpException或IOExceptionQ其中IOException一般意味着|络出错Ql尝试也不太可能获得成功。服务器q回的应{可以按照多U方式读取,例如作ؓ一个字节数l,作ؓ一个输入流Q或者作Z个String。获得服务器q回的应{后Q我们就可以按照自己的需要Q意处|它了?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>byte[] responseBody = method.getResponseBody();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  ?最后要做的是释放q接?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>method.releaseConnection();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  以上只是非常单地介绍了一下HttpClient库,HttpClient实际的功能要比本文介l的丰富得多Q不仅健壮而且高效Q请参阅API文档了解详情?<br /><br />  <b>3.3 Net</b><br /><br />  ?概况Q一个用于操作Internet基础协议的底层API?<br /><br />  ?官方资源Q?a href="http://jakarta.apache.org/commons/net/" target="_blank">主页</a>Q?a href="http://apache.planetmirror.com/dist/jakarta/commons/net/binaries/" target="_blank">二进?/a>Q?a href="http://apache.planetmirror.com.au/dist/jakarta/commons/net/source/" target="_blank">源代?/a>?<br /><br />  ?何时适用Q当你想要访问各UInternet底层协议之时QFingerQWhoisQTFTPQTelnetQPOP3QFTPQNNTPQ以及SMTPQ?<br /><br />  ?CZ应用QNetDemo.java。要求CLASSPATH中包含commons-net-1.0.0.jar?<br /><br />  ?说明Q?<br /><br />  Net包是一个强大、专业的cdQ类库里的类最初属于一个叫做NetComponents的商业品?<br /><br />  Net包不仅支持对各种低层ơ协议的讉KQ而且q提供了一个高层的抽象。大多数情况下,Net包提供的抽象已能满一般需要,它得开发者不再需要直接面对各U协议的SocketU的低层命o。用高层抽象ƈ不减Q何功能,Net API在这斚w做得很出Ԍ既提供了_的功能,又不至于在特色方面作q多的妥协?<br /><br />  SocketClient是支持所有协议的基础c,它是一个抽象类Q聚合了各种协议都需要的公用功能。各U不同协议的使用q程其实很相|首先利用connectҎ建立一个指向远E服务器的连接,执行必要的操作,最后终止与服务器的q接。下面通过实例介绍具体的用步骤?<br /><br /><ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="540" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" bgcolor="#e6e6e6"><pre><ccid_code>// ? // ?创徏一个客L。我们将用NNTPClient //  从新L务器下蝲新闻l清单? client = new NNTPClient(); // ? // ?利用前面创徏的客Lq接到新L务器? //  q里选用的是一个新ȝ较少的服务器? client.connect("aurelia.deine.net"); // ? // ?提取新闻l清单。下面的命o返回一? //  NewsGroupInfo对象的数l。如果指定的? //  务器上不包含新闻l,q回的数l将是空的, //  如果遇到了错误,则返回值是null? list = client.listNewsgroups(); //... // ?最后终止与服务器的q接? if (client.isConnected()) client.disconnect();</ccid_code></pre></td></tr></tbody></table></ccid_nobr><br /><br />  必须说明的是QlistNewsgroups命o可能需要较长的旉才能q回Q一斚w是因为网l速度的媄响,另外也可能是׃新闻l清单往往是很庞大的。NewsGroupInfo对象包含有关新闻l的详细信息Qƈ提供了一些操作新ȝ的命令,比如提取文章L、最后发布的文章、发布文章的权限Q等{?<br /><br />  其他客户端,例如FingerClient、POP3Client、TelnetClient{,用法也差不多?<br /><br />  l束语:有关Web相关cd其他cȝ介绍到此结束。在下一文章中Q我们将探讨XMLcd包装c,最后一文章则介绍工具cR?<br /><br />  希望读者有兴趣试试本文提供的程序实例。很多时候Jakarta Commonslh以؜q感觉Q希望本文你加׃对Jakarta Commons了解Q或者至引起了你对Commons子项目以及它提供的各U实用API和库的兴?<br /><br />请从q里下蝲本文代码Q?a href="http://developer.ccidnet.com/pub/html/developer/code/download/jakartacommons1code.zip" target="_blank">JakartaCommons1_code.zip</a><br /></font></span></ccid_nobr><img src ="http://www.tkk7.com/limq/aggbug/13611.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2005-09-21 10:03 <a href="http://www.tkk7.com/limq/archive/2005/09/21/13611.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>StrutsQSpringQHibernate开发实?/title><link>http://www.tkk7.com/limq/archive/2005/09/20/13565.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Tue, 20 Sep 2005 12:47:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2005/09/20/13565.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/13565.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2005/09/20/13565.html#Feedback</comments><slash:comments>67</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/13565.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/13565.html</trackback:ping><description><![CDATA[     摘要: 一 介绍 本文q不想介lStrutsQSpringQHibernate的原理系l架构等Q本文地目的是通过一个较复杂地实例介l如何整合StrutsQSpringQHibernateQ网上现有的例子虽然也能辑ֈ目的Q但功能都比较单一Q复杂的例子时会有意想不到的ȝ。本文对读者假讑ַl具备了以上框架的基知识。以及那些已l了解StrutsQSpringQHibernate的基本概念,但是q没有亲w在?..  <a href='http://www.tkk7.com/limq/archive/2005/09/20/13565.html'>阅读全文</a><img src ="http://www.tkk7.com/limq/aggbug/13565.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.tkk7.com/limq/" target="_blank">limq</a> 2005-09-20 20:47 <a href="http://www.tkk7.com/limq/archive/2005/09/20/13565.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>条g查询(Criteria Query)http://www.tkk7.com/limq/archive/2005/09/20/13564.htmllimqlimqTue, 20 Sep 2005 12:42:00 GMThttp://www.tkk7.com/limq/archive/2005/09/20/13564.htmlhttp://www.tkk7.com/limq/comments/13564.htmlhttp://www.tkk7.com/limq/archive/2005/09/20/13564.html#Feedback1http://www.tkk7.com/limq/comments/commentRss/13564.htmlhttp://www.tkk7.com/limq/services/trackbacks/13564.html现在Hibernate也支持一U直观的、可扩展的条件查询API。目前ؓ止,q个APIq没有更成熟的HQL查询那么强大Q也没有那么多查询能力。特别要指出Q条件查询也不支持投影(projectionQ或l计函数QaggregationQ?

12.1. 创徏一?TT class=literal>Criteria实例

net.sf.hibernate.Criteriaq个接口代表对一个特定的持久化类的查询?TT class=literal>Session是用来制?TT class=literal>Criteria实例的工厂?

Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();

12.2. ~小l果集范?/H2>

一个查询条?Criterion)?TT class=literal>net.sf.hibernate.expression.Criterion接口的一个实例。类net.sf.hibernate.expression.Expression定义了获得一些内|的Criterioncd?

List cats = sess.createCriteria(Cat.class)
.add( Expression.like("name", "Fritz%") )
.add( Expression.between("weight", minWeight, maxWeight) )
.list();

表达式(ExpressionsQ可以按照逻辑分组.

List cats = sess.createCriteria(Cat.class)
.add( Expression.like("name", "Fritz%") )
.add( Expression.or(
Expression.eq( "age", new Integer(0) ),
Expression.isNull("age")
) )
.list();
List cats = sess.createCriteria(Cat.class)
.add( Expression.in( "name", new String[] { "Fritz", "Izi", "Pk" } ) )
.add( Expression.disjunction()
.add( Expression.isNull("age") )
.add( Expression.eq("age", new Integer(0) ) )
.add( Expression.eq("age", new Integer(1) ) )
.add( Expression.eq("age", new Integer(2) ) )
) )
.list();

有很多预制的条gcdQ?TT class=literal>Expression的子c)。有一个特别有用,可以让你直接嵌入SQL?

List cats = sess.createCriteria(Cat.class)
.add( Expression.sql("lower($alias.name) like lower(?)", "Fritz%", Hibernate.STRING) )
.list();

其中?TT class=literal>{alias}是一个占位符Q它会被所查询实体的行别名所替代?原文:The {alias} placeholder with be replaced by the row alias of the queried entity.)

12.3. 对结果排?/H2>

可以使用net.sf.hibernate.expression.Order对结果集排序.

List cats = sess.createCriteria(Cat.class)
.add( Expression.like("name", "F%")
.addOrder( Order.asc("name") )
.addOrder( Order.desc("age") )
.setMaxResults(50)
.list();

12.4. 兌QAssociationsQ?/H2>

你可以在兌之间使用createCriteria()Q很Ҏ地在存在关系的实体之间指定约束?

List cats = sess.createCriteria(Cat.class)
.add( Expression.like("name", "F%")
.createCriteria("kittens")
.add( Expression.like("name", "F%")
.list();

注意Q第二个createCriteria()q回一?TT class=literal>Criteria的新实例Q指?TT class=literal>kittens集合cȝ元素?

下面的替代Ş式在特定情况下有用?

List cats = sess.createCriteria(Cat.class)
.createAlias("kittens", "kt")
.createAlias("mate", "mt")
.add( Expression.eqProperty("kt.name", "mt.name") )
.list();

Q?TT class=literal>createAlias()Qƈ不会创徏一?TT class=literal>Criteria的新实例。)

h意,前面两个查询?TT class=literal>Cat实例所持有的kittens集合c?SPAN class=emphasis>q没?/EM>通过criteria预先qoQ如果你希望只返回满x件的kittens,你必M?TT class=literal>returnMaps()?

List cats = sess.createCriteria(Cat.class)
.createCriteria("kittens", "kt")
.add( Expression.eq("name", "F%") )
.returnMaps()
.list();
Iterator iter = cats.iterator();
while ( iter.hasNext() ) {
Map map = (Map) iter.next();
Cat cat = (Cat) map.get(Criteria.ROOT_ALIAS);
Cat kitten = (Cat) map.get("kt");
}

12.5. 动态关联对象获取(Dynamic association fetchingQ?/H2>

可以在运行时通过setFetchMode()来改变关联对象自动获取的{略?

List cats = sess.createCriteria(Cat.class)
.add( Expression.like("name", "Fritz%") )
.setFetchMode("mate", FetchMode.EAGER)
.setFetchMode("kittens", FetchMode.EAGER)
.list();

q个查询会通过外连?outer join)同时获得 mate?TT class=literal>kittens?

12.6. ҎCZ查询QExample queriesQ?/H2>

net.sf.hibernate.expression.Examplecd怽从指定的实例创造查询条件?

Cat cat = new Cat();
cat.setSex('F');
cat.setColor(Color.BLACK);
List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.list();

版本属性,表示W属性和兌都会被忽略。默认情况下Qnull值的属性也被排除在外?

You can adjust how the Example is applied. 你可以调?TT class=literal>CZ(Example)如何应用?

Example example = Example.create(cat)
.excludeZeroes() //exclude zero valued properties
.excludeProperty("color") //exclude the property named "color"
.ignoreCase() //perform case insensitive string comparisons
.enableLike(); //use like for string comparisons
List results = session.createCriteria(Cat.class)
.add(example)
.list();

你甚臛_以用CZ对关联对象徏立criteria?

List results = session.createCriteria(Cat.class)
.add( Example.create(cat) )
.createCriteria("mate")
.add( Example.create( cat.getMate() ) )
.list();


limq 2005-09-20 20:42 发表评论
]]>
Spring Framework标记库初学者指?转)http://www.tkk7.com/limq/archive/2005/03/10/1900.htmllimqlimqThu, 10 Mar 2005 06:08:00 GMThttp://www.tkk7.com/limq/archive/2005/03/10/1900.htmlhttp://www.tkk7.com/limq/comments/1900.htmlhttp://www.tkk7.com/limq/archive/2005/03/10/1900.html#Feedback0http://www.tkk7.com/limq/comments/commentRss/1900.htmlhttp://www.tkk7.com/limq/services/trackbacks/1900.htmlSpring架构要介l:
    Spring是一个服务于所有层面的application framework:提供了bean的配|基QAOP的支持,JDBC的提取框?抽象事务支持Q等{。它有一个非常显著的特点Q在某个层面上如果你不需要Spring的支持,你就可以不用String的classQ只使用它的某一部分的功能。从它的设计理念Q你可以看到String帮助你实C真正的逻辑层和web层的分离?BR>   相对于EJB来说QSpring是一个轻量的J2EE应用开发框架。这里提到的轻量U指的是Spring框架本nQ而不是说Spring只能适用于轻量的应用开发。Spring的轻盈体现在其框架本w的基础l构以及对其他应用工L支持和装配能力,与EJBq种庞然大物相比QSpring使我们把各个技术层ơ之间的风险降低。EJB的内聚性较强,比如数据持久层管理、事务管理、生命周期管理都全部交给了EJB容器中管理,内聚性的白盒特征使我们必L弃一部分可控性而去信Q容器能力。而Spring则是考虑如何“不造轮子”,如何更好的组装这些轮子,让他们更好的转动。比如数据持久层理可以使用hibernateQ日志管理可以用jakartacommonlogging。一个比较恰当的比喻是“我们要钉几个钉子,Z完成q个目的Q锤子生产商生了大大小一pd的锤子,每个锤子都有一套复杂的使用ҎQ用来钉某种特别的钉子,l果令我们头g堪。解决锤子过多的问题Q通过springQ我们可以用几U锤子,但用h象是只有一个锤子”?注:q段话是在网上看见的Q这里引用这个比喻,我个得很生动)关于q个框架也有一些简单的ȝQ“Spring有几个主要的部分QBean+ApplicationContextQ以一U统一的、IoC的方式查找、管理、组装、用系l的lgQ取代一切工厂;持久化框Ӟweb框架。“J2EE框架”是RodJohnson的愿景,他希望Spring为J2EE轻量U解x案提供自底至的全面基础设施支持。?nbsp;
   好了Q上面是关于一个新的Framework的简单介l,据说是未来J2EE发展的方向。以前在论坛上有关于J2EE最佳组合的讨论Q听说这个JSTL+Struts(或webwork)+Spring+Hibernate的组合很被看好(观点不一Q仅供参考,呵呵Q?如果你感兴趣的话Q可以到SpringFramework中文论坛上看看。下面{入本文的正题?BR>

Spring 标记库介l及用法Q?/H3>
    本文重点介lSpring 提供的标记库及其用法Q?BR>当你在项目中用Spring Framework的时候,表现层可以选择Spring Framework自带的标记库。当Ӟq不是你唯一的选择。你可以选择其它标记库或模板替换技术。Spring Framework q没有ؓ应用提供非常丰富的标记库。Spring Framework 提供的标记库仅仅是ؓ了够用就行,它ƈ不是无所不包的。呵呵,q点与Struts丰富的标记库不一栗其实这点符合RodJohnson的出发点Q既“不造轮子”。当ӞSpring Framework标记库有它自w的特点Q可以说是个有益的补充吧?BR>Spring 标记库分cd下:
1。spring:hasBindErrors 
2。spring:bind 
3。spring:transform 
4。spring:message 
5。spring:htmlEscape 
6。spring:theme 
下面我们来具体介l一下用法:
1?B>spring:hasBindErrors 
对应org.springframework.web.servlet.tags.BindErrorsTag标记库处理类?BR>q个标记提供用于l定对象的errorsQ如果这个标记被用到的话Q那么关于这个对象的错误在面上显C出来。用这个标记的前提条g是要先?lt;spring:bind>标记,q且<spring:hasBindErrors>q个标记不能用来表示对象的状态,它仅仅可以绑定对象本w和对象的属性?nbsp;具体用法如下Q?BR>
  1. <spring:hasBindErrors name="priceIncrease">
  2.     <b>Please fix all errors!</b>
  3.   </spring:hasBindErrors>

  通过q个单的例子Q我来具体说一下这个标记的属性吧?BR>  nameQ是要被查的Bean的名字。这个属性是必需要的?BR>  呵呵Q这里是单用法,所以就不介l它包含的errors变量了。具体看p文档。下同?BR>  
2?B>spring:bind 
对应org.springframework.web.servlet.tags.BindTag标记库处理类
q个标记用来为某个bean或bean 的属性赋|通常和form一LQ相当于action的作用。它指明表单要提交到那个cLcȝ属性中厅R?BR>其中path属性是必须的,指明转到的类的\径。D例如下:
  1. <form method="post">
  2.   <table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0" cellpadding="5">
  3.     <tr>
  4.       <td alignment="right" width="20%">Increase (%):</td>
  5.       <spring:bind path="priceIncrease.percentage">
  6.         <td width="20%">
  7.           <input type="text" name="percentage" value="<c:out value="${status.value}"/>">
  8.         </td>
  9.         <td width="60%">
  10.           <font color="red"><c:out value="${status.errorMessage}"/></font>
  11.         </td>
  12.       </spring:bind>
  13.     </tr>
  14.   </table>
  15.   <br>
  16.  ……………………省?
  17. </form>

3?B>spring:transform 
对应org.springframework.web.servlet.tags.TransformTag标记库处理类,q个标记用来转换表单中不与bean中的属性一一对应的那些属性,通常?lt;spring:bind>一起用?lt;spring:transform>标记?lt;spring:bind>使用提供了更好的支持?BR>属性如下:
valueQ必需要的。和当前<spring:bind>标记指向的beancȝ同。就是你要{换的实体cd?BR>varQ不是必需的。这个字W串被用来绑定输出结果到pageQrequest, session或application scope.默认情况输出到jsp中?BR>scopeQ不是必需的。前提条件var必须讄的情况下。它的值可以是pageQrequest, session或application?BR>
4?B>spring:message 对应org.springframework.web.servlet.tags.MessageTag标记库处理类
q个标记用来帮助springframework支持国际化。和JSTL的fmt:message标记cM。当然这个标记可以很好的工作的本地的springframework框架下?BR>属性如下:
codeQ不是必需的。用来查找message,如果没有被用的话,text被使用?BR>textQ不是必需的。假如code不存在的话,默认是text输出。当code和text都没有设|的话,标记输Zؓnull.
varQ不是必需的。这个字W串被用来绑定输出结果到pageQrequest, session或application scope.默认情况输出到jsp中?BR>scopeQ不是必需的。前提条件var必须讄的情况下。它的值可以是pageQrequest, session或application?BR>
5?B>spring:htmlEscape 
对应org.springframework.web.servlet.tags.HtmlEscapeTag标记库处理类
不常用,q里省略
6?B>spring:theme 
对应org.springframework.web.servlet.tags.ThemeTag标记库处理类
不常用,q里省略
哈哈Q学习完q些用法后,让我们来看个具体的例?/B>吧?BR>配置步骤如下Q?BR>目录l构图:
-spirngapp 
  -WEB-INF 
      -classes 
      -lib 
  -src 
  -war
1?/B>spring.tld拯到WEB-INF目录?BR>2?/B>spring.jar拯到WEB-INF\lib包下
举例如下Q?BR>在web.xml中配|好taglib属性,代码如下Q?BR>
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN' 'http://java.sun.com/dtd/web-app_2_3.dtd'>
  3. <web-app>
  4.   <servlet>
  5.     <servlet-name>springapp</servlet-name>
  6.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  7.     <load-on-startup>1</load-on-startup>
  8.   </servlet>
  9.   <servlet-mapping>
  10.     <servlet-name>springapp</servlet-name>
  11.     <url-pattern>*.htm</url-pattern>
  12.   </servlet-mapping>
  13.   <welcome-file-list>
  14.     <welcome-file>
  15.       index.jsp
  16.     </welcome-file>
  17.   </welcome-file-list>
  18.   <taglib>
  19.     <taglib-uri>/spring</taglib-uri>
  20.     <taglib-location>/WEB-INFspring.tld</taglib-location>
  21.   </taglib>
  22. </web-app>

jsp面代码如下Q?BR>
  1. <%@ include file="/WEB-INF/jsp/include.jsp" %>
  2. <%@ taglib prefix="spring" uri="/spring" %>
  3. <html>
  4. <head><title><fmt:message key="title"/></title></head>
  5. <body>
  6. <h1><fmt:message key="priceincrease.heading"/></h1>
  7. <form method="post">
  8.   <table width="95%" bgcolor="f8f8ff" border="0" cellspacing="0" cellpadding="5">
  9.     <tr>
  10.       <td alignment="right" width="20%">Increase (%):</td>
  11.       <spring:bind path="priceIncrease.percentage">
  12.         <td width="20%">
  13.           <input type="text" name="percentage" value="<c:out value="${status.value}"/>">
  14.         </td>
  15.         <td width="60%">
  16.           <font color="red"><c:out value="${status.errorMessage}"/></font>
  17.         </td>
  18.       </spring:bind>
  19.     </tr>
  20.   </table>
  21.   <br>
  22.   <spring:hasBindErrors name="priceIncrease">
  23.     <b>Please fix all errors!</b>
  24.   </spring:hasBindErrors>
  25.   <br><br>
  26.   <input type="submit" alignment="center" value="Execute">
  27. </form>
  28. <a href="<c:url value="hello.htm"/>">Home</a>
  29. </body>
  30. </html>

<spring:bind>标记l常用来l定<input>表单元素以便提交lPriceIncrease.java,其实PriceIncrease.java中就是包含一些getter和setter的方法的cR当用户按下按钮提交的时候,其表单中的值实际上pframework攑ֈ了PriceIncrease.java中?lt;spring:bind>l常和form一起?q个${status.errorMessage}?{status.value}是一个framework定义的特D变量,它们被用来显C错误信息和当前表单中的数据。呵呵,今天到此ؓ止吧Q关于Spring Framework标记库的详细用法Q请参考其文档?BR>参考资料:
http://www.springframework.org/
Spring Framework英文文档
Spring Framework中文论坛


limq 2005-03-10 14:08 发表评论
]]>Java反射机制( ?http://www.tkk7.com/limq/archive/2005/03/09/1865.htmllimqlimqTue, 08 Mar 2005 17:36:00 GMThttp://www.tkk7.com/limq/archive/2005/03/09/1865.htmlhttp://www.tkk7.com/limq/comments/1865.htmlhttp://www.tkk7.com/limq/archive/2005/03/09/1865.html#Feedback1http://www.tkk7.com/limq/comments/commentRss/1865.htmlhttp://www.tkk7.com/limq/services/trackbacks/1865.htmlJava反射机制

摘要
Reflection 是Java被视为动态(或准动态)语言的一个关键性质。这个机制允许程序在q行旉过Reflection APIs取得M一个已知名U的class的内部信息,包括其modifiersQ诸如public, static {等Q、superclassQ例如ObjectQ、实CinterfacesQ例如CloneableQ,也包括fields和methods的所有信息,q可于运行时改变fields内容或唤起methods。本文借由实例Q大面积CReflection APIs?BR>
关于本文Q?BR>读者基Q具备Java 语言基础?BR>本文适用工具QJDK1.5

关键词:
IntrospectionQ内省、内观)
ReflectionQ反)


有时候我们说某个语言h很强的动态性,有时候我们会区分动态和静态的不同技术与作法。我们朗朗上口动态绑定(dynamic bindingQ、动态链接(dynamic linkingQ、动态加载(dynamic loadingQ等。然而“动态”一词其实没有绝对而普遍适用的严格定义,有时候甚臛_对象导向当初被导入编E领域一P一Z把号Q各吹各的调?BR>
一般而言Q开发者社说到动态语aQ大致认同的一个定义是Q“程序运行时Q允许改变程序结构或变量cdQ这U语aUCؓ动态语a”。从q个观点看,PerlQPythonQRuby是动态语aQC++QJavaQC#不是动态语a?BR>
管在这L定义与分cMJava不是动态语aQ它却有着一个非常突出的动态相xӞReflection。这个字的意思是“反、映象、倒媄”,用在Javaw上指的是我们可以于q行时加载、探知、用编译期间完全未知的classes。换句话_JavaE序可以加蝲一个运行时才得知名U的classQ获悉其完整构造(但不包括methods定义Q,q生成其对象实体、或对其fields讑ր{或唤v其methods1。这U“看透class”的能力Qthe ability of the program to examine itselfQ被UCؓintrospectionQ内省、内观、反省)。Reflection和introspection是常被ƈ提的两个术语?BR>
Java如何能够做出上述的动态特性呢Q这是一个深q话题,本文Ҏ只简单介l一些概c整个篇q最主要q是介绍Reflection APIsQ也是让读者知道如何探索class的结构、如何对某个“运行时才获知名U的class”生成一份实体、ؓ其fields讑ր{调用其methods。本文将谈到java.lang.ClassQ以及java.lang.reflect中的Method、Field、Constructor{等classes?BR>
“Class”class
众所周知Java有个Object classQ是所有Java classes的承根源,其内声明了数个应该在所有Java class中被改写的methodsQhashCode()、equals()、clone()、toString()、getClass(){。其中getClass()q回一个Class object?BR>
Class class十分Ҏ。它和一般classes一L承自ObjectQ其实体用以表达JavaE序q行时的classes和interfacesQ也用来表达enum、array、primitive Java typesQboolean, byte, char, short, int, long, float, doubleQ以及关键词void。当一个class被加载,或当加蝲器(class loaderQ的defineClass()被JVM调用QJVM 便自动生一个Class object。如果您惛_由“修改Java标准库源码”来观察Class object的实际生成时机(例如在Class的constructor内添加一个println()Q,不能够!因ؓClassq没有public constructorQ见?Q。本文最后我会拨一块幅带谈谈Java标准库源码的改动办法?BR>
Class是Reflection故事h。针对Q何您x勘的classQ唯有先为它产生一个Class objectQ接下来才能l由后者唤起ؓ数十多个的Reflection APIs。这些APIs在E后的探险活动中一一亮相?BR>
#001 public final
#002 class Class<T> implements java.io.Serializable,
#003 java.lang.reflect.GenericDeclaration,
#004 java.lang.reflect.Type,
#005 java.lang.reflect.AnnotatedElement {
#006 private Class() {}
#007 public String toString() {
#008 return ( isInterface() ? "interface " :
#009 (isPrimitive() ? "" : "class "))
#010 + getName();
#011 }
...
?QClass class片段。注意它的private empty ctorQ意指不允许M人经qE方式生Class object。是的,其object 只能由JVM 产生?BR>
“Class?object的取得途径
Java允许我们从多U管道ؓ一个class生成对应的Class object。图2是一份整理?BR>Class object 诞生道CZ
q用getClass()
注:每个class 都有此函数String str = "abc";
Class c1 = str.getClass();
q用
Class.getSuperclass()2Button b = new Button();
Class c1 = b.getClass();
Class c2 = c1.getSuperclass();
q用static method
Class.forName()
Q最常被使用QClass c1 = Class.forName ("java.lang.String");
Class c2 = Class.forName ("java.awt.Button");
Class c3 = Class.forName ("java.util.LinkedList$Entry");
Class c4 = Class.forName ("I");
Class c5 = Class.forName ("[I");
q用
.class 语法Class c1 = String.class;
Class c2 = java.awt.Button.class;
Class c3 = Main.InnerClass.class;
Class c4 = int.class;
Class c5 = int[].class;
q用
primitive wrapper classes
的TYPE 语法
Class c1 = Boolean.TYPE;
Class c2 = Byte.TYPE;
Class c3 = Character.TYPE;
Class c4 = Short.TYPE;
Class c5 = Integer.TYPE;
Class c6 = Long.TYPE;
Class c7 = Float.TYPE;
Class c8 = Double.TYPE;
Class c9 = Void.TYPE;
?QJava 允许多种道生成Class object?BR>
Java classes l成分析
首先Ҏ以图3的java.util.LinkedListZQ将Java class的定义大卸八块,每一块分别对应图4所C的Reflection API。图5则是“获得class各区块信息”的E序CZ及执行结果,它们都取自本文示例程序的对应片段?BR>
package java.util; //(1)
import java.lang.*; //(2)
public class LinkedList<E> //(3)(4)(5)
extends AbstractSequentialList<E> //(6)
implements List<E>, Queue<E>,
Cloneable, java.io.Serializable //(7)
{
private static class Entry<E> { ?}//(8)
public LinkedList() { ?} //(9)
public LinkedList(Collection<? extends E> c) { ?}
public E getFirst() { ?} //(10)
public E getLast() { ?}
private transient Entry<E> header = ?//(11)
private transient int size = 0;
}
?Q将一个Java class 大卸八块Q每块相应于一个或一lReflection APIsQ图4Q?BR>
Java classes 各成份所对应的Reflection APIs
?的各个Java class成䆾Q分别对应于?的Reflection APIQ其中出现的Package、Method、Constructor、Field{等classesQ都定义于java.lang.reflect?BR>Java class 内部模块Q参见图3QJava class 内部模块说明相应之Reflection APIQ多半ؓClass methods。返回值类?return type)
(1) packageclass隶属哪个packagegetPackage()Package
(2) importclass导入哪些classes无直接对应之API?BR>解决办法见图5-2?BR>(3) modifierclassQ或methods, fieldsQ的属?BR>int getModifiers()
Modifier.toString(int)
Modifier.isInterface(int)int
String
bool
(4) class name or interface nameclass/interface名称getName()String
(5) type parameters参数化类型的名称getTypeParameters() TypeVariable <Class>[]
(6) base classbase classQ只可能一个)getSuperClass()Class
(7) implemented interfaces实现有哪些interfacesgetInterfaces()Class[]

(8) inner classes内部classesgetDeclaredClasses()Class[]
(8') outer class如果我们观察的class 本n是inner classesQ那么相对它׃有个outer class。getDeclaringClass()Class
(9) constructors构造函数getDeclaredConstructors()不论 public 或private 或其它access levelQ皆可获得。另有功能近g取得函数。Constructor[]
(10) methods操作函数getDeclaredMethods()不论 public 或private 或其它access levelQ皆可获得。另有功能近g取得函数。Method[]
(11) fields字段Q成员变量)getDeclaredFields()不论 public 或private 或其它access levelQ皆可获得。另有功能近g取得函数。Field[]
?QJava class大卸八块后(如图3Q,每一块所对应的Reflection API。本表ƈ?BR>Reflection APIs 的全部?BR>
Java Reflection API q用CZ
?C?提过的每一个Reflection APIQ及其执行结果。程序中出现的tName()是个辅助函数Q可其W一自变量所代表的“Java class完整路径字符东y剥除\径部分,留下class名称Q储存到W二自变量所代表的一个hashtabledƈq回Q如果第二自变量为nullQ就不储存而只是返回)?BR>
#001 Class c = null;
#002 c = Class.forName(args[0]);
#003
#004 Package p;
#005 p = c.getPackage();
#006
#007 if (p != null)
#008 System.out.println("package "+p.getName()+";");

执行l果Q例Q:
package java.util;
?-1Q找出class 隶属的package。其中的cl沿用于以下各程序片Dc?BR>
#001 ff = c.getDeclaredFields();
#002 for (int i = 0; i < ff.length; i++)
#003 x = tName(ff[i].getType().getName(), classRef);
#004
#005 cn = c.getDeclaredConstructors();
#006 for (int i = 0; i < cn.length; i++) {
#007 Class cx[] = cn[i].getParameterTypes();
#008 for (int j = 0; j < cx.length; j++)
#009 x = tName(cx[j].getName(), classRef);
#010 }
#011
#012 mm = c.getDeclaredMethods();
#013 for (int i = 0; i < mm.length; i++) {
#014 x = tName(mm[i].getReturnType().getName(), classRef);
#015 Class cx[] = mm[i].getParameterTypes();
#016 for (int j = 0; j < cx.length; j++)
#017 x = tName(cx[j].getName(), classRef);
#018 }
#019 classRef.remove(c.getName()); //不必记录自己Q不需import 自己Q?BR>
执行l果Q例Q:
import java.util.ListIterator;
import java.lang.Object;
import java.util.LinkedList$Entry;
import java.util.Collection;
import java.io.ObjectOutputStream;
import java.io.ObjectInputStream;
?-2Q找出导入的classesQ动作细节详见内文说明?BR>
#001 int mod = c.getModifiers();
#002 System.out.print(Modifier.toString(mod)); //整个modifier
#003
#004 if (Modifier.isInterface(mod))
#005 System.out.print(" "); //关键?"interface" 已含于modifier
#006 else
#007 System.out.print(" class "); //关键?"class"
#008 System.out.print(tName(c.getName(), null)); //class 名称

执行l果Q例Q:
public class LinkedList
?-3Q找出class或interface 的名Uͼ及其属性(modifiersQ?BR>
#001 TypeVariable<Class>[] tv;
#002 tv = c.getTypeParameters(); //warning: unchecked conversion
#003 for (int i = 0; i < tv.length; i++) {
#004 x = tName(tv[i].getName(), null); //例如 E,K,V...
#005 if (i == 0) //W一?BR>#006 System.out.print("<" + x);
#007 else //非第一?BR>#008 System.out.print("," + x);
#009 if (i == tv.length-1) //最后一?BR>#010 System.out.println(">");
#011 }

执行l果Q例Q:
public abstract interface Map<K,V>
?public class LinkedList<E>
?-4Q找出parameterized types 的名U?BR>
#001 Class supClass;
#002 supClass = c.getSuperclass();
#003 if (supClass != null) //如果有super class
#004 System.out.print(" extends" +
#005 tName(supClass.getName(),classRef));

执行l果Q例Q:
public class LinkedList<E>
extends AbstractSequentialList,
?-5Q找出base class。执行结果多Z个不该有的逗号于尾端。此非本处重点,为简化计Q不多做处理?BR>
#001 Class cc[];
#002 Class ctmp;
#003 //扑և所有被实现的interfaces
#004 cc = c.getInterfaces();
#005 if (cc.length != 0)
#006 System.out.print(", \r\n" + " implements "); //关键?BR>#007 for (Class cite : cc) //JDK1.5 新式循环写法
#008 System.out.print(tName(cite.getName(), null)+", ");

执行l果Q例Q:
public class LinkedList<E>
extends AbstractSequentialList,
implements List, Queue, Cloneable, Serializable,
?-6Q找出implemented interfaces。执行结果多Z个不该有的逗号于尾端。此非本处重点,为简化计Q不多做处理?BR>
#001 cc = c.getDeclaredClasses(); //扑ևinner classes
#002 for (Class cite : cc)
#003 System.out.println(tName(cite.getName(), null));
#004
#005 ctmp = c.getDeclaringClass(); //扑ևouter classes
#006 if (ctmp != null)
#007 System.out.println(ctmp.getName());

执行l果Q例Q:
LinkedList$Entry
LinkedList$ListItr
?-7Q找出inner classes 和outer class

#001 Constructor cn[];
#002 cn = c.getDeclaredConstructors();
#003 for (int i = 0; i < cn.length; i++) {
#004 int md = cn[i].getModifiers();
#005 System.out.print(" " + Modifier.toString(md) + " " +
#006 cn[i].getName());
#007 Class cx[] = cn[i].getParameterTypes();
#008 System.out.print("(");
#009 for (int j = 0; j < cx.length; j++) {
#010 System.out.print(tName(cx[j].getName(), null));
#011 if (j < (cx.length - 1)) System.out.print(", ");
#012 }
#013 System.out.print(")");
#014 }

执行l果Q例Q:
public java.util.LinkedList(Collection)
public java.util.LinkedList()
?-8aQ找出所有constructors

#004 System.out.println(cn[i].toGenericString());

执行l果Q例Q:
public java.util.LinkedList(java.util.Collection<? extends E>)
public java.util.LinkedList()
?-8bQ找出所有constructors。本例在for 循环内用toGenericString()Q省事?BR>
#001 Method mm[];
#002 mm = c.getDeclaredMethods();
#003 for (int i = 0; i < mm.length; i++) {
#004 int md = mm[i].getModifiers();
#005 System.out.print(" "+Modifier.toString(md)+" "+
#006 tName(mm[i].getReturnType().getName(), null)+" "+
#007 mm[i].getName());
#008 Class cx[] = mm[i].getParameterTypes();
#009 System.out.print("(");
#010 for (int j = 0; j < cx.length; j++) {
#011 System.out.print(tName(cx[j].getName(), null));
#012 if (j < (cx.length - 1)) System.out.print(", ");
#013 }
#014 System.out.print(")");
#015 }

执行l果Q例Q:
public Object get(int)
public int size()
?-9aQ找出所有methods

#004 System.out.println(mm[i].toGenericString());

public E java.util.LinkedList.get(int)
public int java.util.LinkedList.size()
?-9bQ找出所有methods。本例在for 循环内用toGenericString()Q省事?BR>
#001 Field ff[];
#002 ff = c.getDeclaredFields();
#003 for (int i = 0; i < ff.length; i++) {
#004 int md = ff[i].getModifiers();
#005 System.out.println(" "+Modifier.toString(md)+" "+
#006 tName(ff[i].getType().getName(), null) +" "+
#007 ff[i].getName()+";");
#008 }

执行l果Q例Q:
private transient LinkedList$Entry header;
private transient int size;
?-10aQ找出所有fields

#004 System.out.println("G: " + ff[i].toGenericString());

private transient java.util.LinkedList.java.util.LinkedList$Entry<E> ??
java.util.LinkedList.header
private transient int java.util.LinkedList.size
?-10bQ找出所有fields。本例在for 循环内用toGenericString()Q省事?BR>
扑ևclass参用Q导入)的所有classes
没有直接可用的Reflection API可以为我们找出某个class参用的所有其它classes。要获得q项信息Q必d苦工Q一步一脚印逐一记录。我们必观察所有fields的类型、所有methodsQ包括constructorsQ的参数cd和回q类型,剔除重复Q留下唯一。这正是Z么图5-2E序代码要ؓtName()指定一个hashtableQ而非一个nullQ做为第二自变量的缘故:hashtable可ؓ我们储存元素Q本例ؓ字符ԌQ又保证不重复?BR>
本文讨论xQ几乎可以还原一个class的原貌(唯有methods 和ctors的定义无法取得)。接下来讨论Reflection 的另三个动态性质Q?1) q行时生成instancesQ?2) ?BR>行期唤vmethodsQ?3) q行时改动fields?BR>
q行时生成instances
Ʋ生成对象实体,在Reflection 动态机制中有两U作法,一个针对“无自变量ctor”,
一个针对“带参数ctor”。图6是面对“无自变量ctor”的例子。如果欲调用的是“带参数ctor“就比较ȝ些,?是个例子Q其中不再调用Class的newInstance()Q而是调用Constructor 的newInstance()。图7首先准备一个Class[]做ؓctor的参数类型(本例指定Z个double和一个intQ,然后以此变量调用getConstructor()Q获得一个专属ctor。接下来再准备一个Object[] 做ؓctor实参|本例指定3.14159?25Q,调用上述专属ctor的newInstance()?BR>
#001 Class c = Class.forName("DynTest");
#002 Object obj = null;
#003 obj = c.newInstance(); //不带自变?BR>#004 System.out.println(obj);
?Q动态生成“Class object 所对应之class”的对象实体Q无自变量?BR>
#001 Class c = Class.forName("DynTest");
#002 Class[] pTypes = new Class[] { double.class, int.class };
#003 Constructor ctor = c.getConstructor(pTypes);
#004 //指定parameter listQ便可获得特定之ctor
#005
#006 Object obj = null;
#007 Object[] arg = new Object[] {3.14159, 125}; //自变?BR>#008 obj = ctor.newInstance(arg);
#009 System.out.println(obj);
?Q动态生成“Class object 对应之class”的对象实体Q自变量以Object[]表示?BR>
q行时调用methods
q个动作和上q调用“带参数之ctor”相当类伹{首先准备一个Class[]做ؓctor的参数类型(本例指定其中一个是StringQ另一个是HashtableQ,然后以此变量调用getMethod()Q获得特定的Method object。接下来准备一个Object[]攄自变量,然后调用上述所得之特定Method object的invoke()Q如?。知道ؓ什么烦取Method object时不需指定回返cd吗?因ؓmethod overloading机制要求signatureQv名式Q必d一Q而回q类型ƈ非signature的一个成份。换句话_只要指定了method名称和参数列Q就一定指Z一个独一无二的method?BR>
#001 public String func(String s, Hashtable ht)
#002 {
#003 …System.out.println("func invoked"); return s;
#004 }
#005 public static void main(String args[])
#006 {
#007 Class c = Class.forName("Test");
#008 Class ptypes[] = new Class[2];
#009 ptypes[0] = Class.forName("java.lang.String");
#010 ptypes[1] = Class.forName("java.util.Hashtable");
#011 Method m = c.getMethod("func",ptypes);
#012 Test obj = new Test();
#013 Object args[] = new Object[2];
#014 arg[0] = new String("Hello,world");
#015 arg[1] = null;
#016 Object r = m.invoke(obj, arg);
#017 Integer rval = (String)r;
#018 System.out.println(rval);
#019 }
?Q动态唤起method

q行时变更fields内容
与先前两个动作相比,“变更field内容”轻村֤了,因ؓ它不需要参数和自变量。首先调用Class的getField()q指定field名称。获得特定的Field object之后便可直接调用Field的get()和set()Q如??BR>
#001 public class Test {
#002 public double d;
#003
#004 public static void main(String args[])
#005 {
#006 Class c = Class.forName("Test");
#007 Field f = c.getField("d"); //指定field 名称
#008 Test obj = new Test();
#009 System.out.println("d= " + (Double)f.get(obj));
#010 f.set(obj, 12.34);
#011 System.out.println("d= " + obj.d);
#012 }
#013 }
?Q动态变更field 内容

Java 源码改动办法
先前我曾提到Q原本想借由“改动Java标准库源码”来知Class object的生成,但由于其ctor原始设计为privateQ也是说不可能透过q个道生成Class objectQ而是由class loader负责生成Q,因此“在ctor中打印出某种信息”的企图也就失去了意义?BR>
q里我要谈点题外话:如何修改Java标准库源码ƈ让它反应到我们的应用E序来。假设我想修改java.lang.ClassQ让它在某些情况下打印某U信息。首先必L出标准源码!当你下蝲JDK 套gq安装妥当,你会发现jdk150\src\java\lang 目录Q见?0Q之中有Class.javaQ这是我们此次行动的标准源码。备份后加以修改Q编译获得Class.class。接下来准备?class 搬移到jdk150\jre\lib\endorsedQ见?0Q?BR>
q是一个十分特别的目录Qclass loader优先从该处d内含classes?jar文g——成功的条g?jar内的classes压羃路径必须和Java标准库的路径完全相同。ؓ此,我们可以刚才做出的Class.class先搬C个ؓ此目的而刻意做出来的\java\lang目录中,压羃为foo.zipQQ意命名,唯需夹带路径java\langQ,再将q个foo.zip搬到jdk150\jre\lib\endorsedq改名ؓfoo.jar。此后你的应用程序便会优先用上这里的java.lang.Class。整个过E可写成一个批处理文gQbatch fileQ,如图11Q在DOS Box中用?BR>

?0QJDK1.5 安装后的目录l织。其中的endorsed 是我新徏?BR>
del e:\java\lang\*.class //清理q净
del c:\jdk150\jre\lib\endorsed\foo.jar //清理q净
c:
cd c:\jdk150\src\java\lang
javac -Xlint:unchecked Class.java //~译源码
javac -Xlint:unchecked ClassLoader.java //~译另一个源码(如有必要Q?BR>move *.class e:\java\lang //搬移臛_意制造的目录?BR>e:
cd e:\java\lang //以下压羃至适当目录
pkzipc -add -path=root c:\jdk150\jre\lib\endorsed\foo.jar *.class
cd e:\test //q入试目录
javac -Xlint:unchecked Test.java //~译试E序
java Test //执行试E序
?1Q一个可在DOS Box中用的批处理文Ӟbatch fileQ,用以自动化java.lang.Class
的修改动作。Pkzipc(.exe)是个命o列压~工Padd和path都是其命令?BR>
更多信息
以下是视野所及与本文主题相关的更多讨论。这些信息可以I补因文章幅限制而带来的不Q或带给您更多视野?BR>
?        "Take an in-depth look at the Java Reflection API -- Learn about the new Java 1.1 tools forfinding out information about classes", by Chuck McManis。此文章所附程序代码是本文CZE序的主要依据(本文CZE序C了更多Reflection APIsQƈ采用JDK1.5 新式的for-loop 写法Q?BR>?        "Take a look inside Java classes -- Learn to deduce properties of a Java class from inside aJava program", by Chuck McManis?BR>?        "The basics of Java class loaders -- The fundamentals of this key component of the Javaarchitecture", by Chuck McManis?BR>?        《The Java Tutorial Continued? Sun microsystems. Lesson58-61, "Reflection".

?用过诸如MFCq类所?Application Framework的程序员也许知道QMFC有所谓的dynamic creation。但它ƈ不等同于Java的动态加载或动态L识;所有能够在MFCE序中v作用的classesQ都必须先在~译期被~译器“看见”?BR>
?如果操作对象是ObjectQClass.getSuperClass()会返回null?BR>


limq 2005-03-09 01:36 发表评论
]]>
自定义标{?http://www.tkk7.com/limq/archive/2005/03/03/1669.htmllimqlimqThu, 03 Mar 2005 15:55:00 GMThttp://www.tkk7.com/limq/archive/2005/03/03/1669.htmlhttp://www.tkk7.com/limq/comments/1669.htmlhttp://www.tkk7.com/limq/archive/2005/03/03/1669.html#Feedback3http://www.tkk7.com/limq/comments/commentRss/1669.htmlhttp://www.tkk7.com/limq/services/trackbacks/1669.html
1.  什么是自定义标{?
{:1) 用户自定义的Java语言元素, 实质是运行一个或者两个接口的JavaBean;
   2) 可以非常机密地和JSP的表C逻辑联系在一P又具有和普通JavaBean相同的业务逻辑处理能力;
   2) 当一个JSP面转变为servletӞ光的用戯定义标签转化为操作一个称为标{hander的对?
   3) 可操作默认对象,处理表单数据Q访问数据库以及其它企业服务;                

2.  自定义标{ֺ的特?
{:1) 通过调用面传递参数实现定?
   2) 讉K所有对JSP面可能的对?
   3) 修改调用面生成的响?
   4) 自定义标{N可相互通信;
   5) 在同一个JSP面中通过标签嵌套Q可实现复杂交互?

3.  如何使用自定义标{ֺ
{:1) 声明标签?
   2) 使标{ֺ执行对Web应用E序可用

4.  声明标签?
{:1) 使用taglib指o声明标签?
   2) 语法Q?lt;%@taglib uri="URI" prefix="pre" %>
      注意Qa. uri属性可以是l对的,也可以是相对URLQ该URL指向标记库描q符(TLD)文g;
            b. uri属性也可以是一个ƈ不存在的URLQ该URL为web.xml文g中将标记库描q符(TLD)文g的绝对URL到本地系l的一个映?
   3) 范例Q?lt;%@taglib uri="/WEB-INF/template.tld" prefix="test" %>
            <%@taglib uri="http://java.sun.com/jstl/core" prefix="core" %>      

5.  使标{ֺ执行可用
{:方式一Q在WEB-INF/classes目录下部|标记处理程序类;
   方式二:标记处理程序类打包成jar文gq置于WEB-INF/lib目录?

6.  几种典型的标{?疑问Q可以有带主体而没有属性的标签么?)
{:1) 不带属性和M的简单标{:<mytaglibs:SomeTag/>;
   2) 不带M但有属性的标签Q?lt;mytaglibs:SomeTag user="TonyDeng"/>;
   3) 带有M和属性的标签Q?lt;mytaglibs:SomeTag user="TonyDeng">
                            ...// 标签?
                            </mytaglibs:SomeTag>;
   注意Qa. 属性列于start tag中,它是在标记库描述W?TLD)文g中指定,服务于标记库的自定义行ؓ;
         b. 标签体位于start tag和end tag_可以是Q何合法的JSP内容或者标{?

7.  定义标签
{:1) 开发实现tag的类(tag handler);
   2) ~辑标记库描q符(TLD)文g;
   3) 在web.xml中ؓ标记库描q符(TLD)文g的绝对URL建立一个映?该步骤可?;

8.  标记库描q符(TLD)文g
{:1) 一个描q标记库的XML文g;
   2) 内容开始是整个库的描述Q然后是tag的描q?
   3) 标记库描q符(TLD)文g用于Web Container认tag以及JSP面发展工具;

9.  实现tag的类(tag handler)
{:1) 是一些在引用了标{JSP面执行期间被Web Container调用以求自定义标{ր的对象;
   2) 必须实现Tag, SimpleTag和BodyTag之一;
   3) 可以l承TagSupport和BodyTagSupport之一?

10. 标签库的接口和类的承关p?
{:表现形式一Q?
   a. 接口的承关p:
      ?interface javax.servlet.jsp.tagext.JspTag
         ?interface javax.servlet.jsp.tagext.SimpleTag
         ?interface javax.servlet.jsp.tagext.Tag
            ?interface javax.servlet.jsp.tagext.IterationTag
            ?interface javax.servlet.jsp.tagext.BodyTag
   b. cȝl承关系Q?
      ?class javax.servlet.jsp.tagext.TagSupport (implements javax.servlet.jsp.tagext.IterationTag, java.io.Serializable)
         ?class javax.servlet.jsp.tagext.BodyTagSupport (implements javax.servlet.jsp.tagext.BodyTag)
      ?class javax.servlet.jsp.tagext.SimpleTagSupport (implements javax.servlet.jsp.tagext.SimpleTag)
   表现形式二:
                 (Interface)
                   JspTag
                     ?
             |ˉˉˉˉˉˉˉˉ|    
        (Interface)      (Interface)
            Tag           SimpleTag ←-QSimpleTagSupport
             ?nbsp;                         
             |                            
        (Interface)  
        IterationTag←-QTagSupport
             ?nbsp;               ?
             |                 |
        (Interface)            |
          BodyTag   ←-QBodyTagSupport

2004-10-9      星期?nbsp;     ?nbsp;                                             



11. 一个Tag处理E序cdd现的Ҏ
{:标签处理E序cd            Ҏ
   Simple                      doStartTag, doEndTag, release
   Attributes                  doStartTag, doEndTag, set/getAttribute...release
   Body,No Itrative and        doStartTag, doEndTag, release
   Evaluation  
   Body, Itrative Evaluation   doStartTag, doAterTag, doEndTag, release
   Body, Interaction           doStartTag, doEndTag, release, doInitbody, doAfterBody

12. 单的标签处理E序c?
{:1) 必须实现Tag接口的doStartTag()和doEndTag()Ҏ;
   2) 因ؓ不存在BodyQdoStartTag()Ҏ必须q回SKIP_BODY;
   3) 如其余页面要执行QdoEndTag()Ҏq回EVAL_PAGE, 否则q回SKIP_PAGE;
   4) 对于每一个标{ֱ性,你必d标签处理E序c里定义一个特性以及get和setҎ以一致于JavaBeans体系惯例

13. 带Body的自定义标签
{:1) 必须实现Tag接口的doStartTag()和doEndTag()Ҏ;
   2) 可以实现IterationTag接口的doAfterBody()Ҏ;
   3) 可以实现BodyTag接口的doInitBody和setBodyContentҎ;
   4) doStartTagҎ可以q回SKIP_BODY、EVAL_BODY_INCLUDE、或者EVAL_BODY_BUFFERED(当你想用BodyContent);
   5) doEndTagҎ可以q回SKIP_PAGE或EVAL_PAGE;
   6) doAfterBodyҎ可以q回EVAL_BODY_AGAIN, SKIP_BODY;

14. 定义脚本变量的标{?q代的标{ֺ)
{:1) 定义脚本标签的二个步?
      a. 在标记库描述W?TLD)文g中列明脚本变?
      b. 定义标签扩展信息c?TEI)q且在TLD文g中包括这个类元素(tei-class);
   2) 变量必须在标{֤理程序类中用pageContext.setAttribute()Ҏ讄;
   3) 标签扩展信息c?TEI)必须l承TagExtraInfo以及覆盖getVariableInfo()Ҏ;
   4) 变量的范围可以是AT_BEGIN, NESTED, AT_END(标签扩展信息c?TEI)的VariableInfo中定?之一;

15. 脚本变量的有效?
{:变量     |   有效?nbsp;                   
   ---------------------------------------
   NESTED   | 标签中的参数在starttag到endtag之间是有效的
   AT_BEGIN | 标签中的参数在标{开始到JSP面l束是有效的
   AT_END   | 标签中的参数在标{l束到JSP面l束是有效的

2004-10-10     星期?nbsp;     ?

16.  Tag接口的方?
{:interface javax.servlet.jsp.tagext.Tag
   ------------------------------------------------------
   +EVAL_BODY_INCLUDE:int
   +EVAL_PAGE:int
   +SKIP_BODY:int
   +SKIP_PAGE:int
   ------------------------------------------------------
   +release():void
   +getParent():javax.servlet.jsp.tagext.Tag
   +setParent(javax.servlet.jsp.tagext.Tag):void
   +doEndTag():int
   +doStartTag():int
   +setPageContext(javax.servlet.jsp.PageContext):void

17.  Tag的生命周?
{:1) setPageContext(javax.servlet.jsp.PageContext):void
   2) setParent(javax.servlet.jsp.tagext.Tag):void
   3) //setAttribute:void
   4) doStartTag():int
   5) doEndTag():int
   6) release():void

18.  BodyTag和Tag接口的关p?
{:interface javax.servlet.jsp.tagext.BodyTag      -->     interface javax.servlet.jsp.tagext.Tag
   ------------------------------------------
   +EVAL_BODY_AGAIN:int
   ------------------------------------------
   +doInitBody():void
   +setBodyContent(javax.servlet.jsp.tagext.BodyContext):void
   +doAfterBody():int

19.  BodyTag的处理过E?
{:1) setPageContext(javax.servlet.jsp.PageContext):void
   2) setParent(javax.servlet.jsp.tagext.Tag):void
   3) //setParent()
   4) doStartTag():int
   5) setBodyContent(javax.servlet.jsp.tagext.BodyContent):void
   6) doInitBody():void
   7) doAfterBody():int
   doEndTag():int
   9) release():void

20.  SimpleTag接口的方?
{:javax.servlet.jsp.tagext.SimpleTag
   ------------------------------------------
   +doTag():void
   +getParent():JspTag
   +setJspBody(JspFragment jspBody):void
   +setJspContext(JspContext pc):void
   +setParent(JspTag parent):void

21.  SimpleTage接口的生命周?
{:1) new:
      每次遇到标签Q容器构造一个SimpleTag的实例,q个构造方法没有参数。和U典的标{一PSimpleTag不能~冲Q故不能重用Q每ơ都需要构造新的实例?
   2) setJspContext()、setParent(): 只有q个标签在另一个标{之内时Q才调用setParent()Ҏ;
   3) 讄属性:调用每个属性的setterҎ;
   4) setJspBody();
   5) doTag(): 所有标{逻辑、P代和Body计算Q都在这个方法中;
   6) return

limq 2005-03-03 23:55 发表评论
]]>
Hibernate 入门实例Q{载)http://www.tkk7.com/limq/archive/2005/03/03/1659.htmllimqlimqThu, 03 Mar 2005 09:29:00 GMThttp://www.tkk7.com/limq/archive/2005/03/03/1659.htmlhttp://www.tkk7.com/limq/comments/1659.htmlhttp://www.tkk7.com/limq/archive/2005/03/03/1659.html#Feedback3http://www.tkk7.com/limq/comments/commentRss/1659.htmlhttp://www.tkk7.com/limq/services/trackbacks/1659.htmlJBuilder X
jdk 1.4.2
Mysql 4.0.11 驱动:mm.mysql-2.0.4-bin.jar(org.gjt.mm.mysql.Driver)
Hibernate 2.1

解压Hibernate

打开JBQ新建工E,名ؓQhibernate
加入Hibernate需要的包与MYSQL驱动
步骤:file->new project->name中输入hibernate,directory选择你要存放本工E的路径->next

->required libraries->add->new->name中输入你要设|的hibernate包名

->add->选择你hibernate解压到的目录Q选中该目录下的hibernate2.jar与lib目录下的所有jar包,再把你的MYSQL驱动包也加进?BR>
然后一直按OKQnext?BR>
新徏一个类,名ؓHello_Bean.java,代码如下Q?BR>


package hibernate;

import java.io.Serializable;

/**
* @author geezer
* QQ:9986986 MSN:geezer_hot@hotmail.com
*/

public class Hello_Bean implements Serializable {

private String name;//q里name与address和id的名字可以自己定Q不会有什么媄?但get与setҎ不可以。因为那得跟数据库与配置文g对应?BR>
private String address;

private int id;



public Hello_Bean() {

}

public Hello_Bean(String name, String address) {//构造函?看完本章以后怿你会明白的了
this.name = name;
this.address = address;
}

public String getName() {//此方法名必须与Hello_Bean.hbm.xml文g里的对应的名字一P下面会详l讲
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

public int getId() {//必须的方?BR>return id;
}

public void setId(int id)//必须的方?BR>{
this.id = id;
}


}



完成q一步以后编?BR>
hibernate解压后的目录下的src文g多w的hibernate.properties与log4j.properties文g复制C的工E目录的classes目录?BR>
(例如hibernate\classes\目录?Q?BR>
打开hibernate.properties文gQ找?BR>
## HypersonicSQL

hibernate.dialect net.sf.hibernate.dialect.HSQLDialect
hibernate.connection.driver_class org.hsqldb.jdbcDriver
hibernate.connection.username sa
hibernate.connection.password
hibernate.connection.url jdbc:hsqldb:hsql://localhost
hibernate.connection.url jdbc:hsqldb:test
hibernate.connection.url jdbc:hsqldb:.

改ؓ

## HypersonicSQL

#hibernate.dialect net.sf.hibernate.dialect.HSQLDialect
#hibernate.connection.driver_class org.hsqldb.jdbcDriver
#hibernate.connection.username sa
#hibernate.connection.password
#hibernate.connection.url jdbc:hsqldb:hsql://localhost
#hibernate.connection.url jdbc:hsqldb:test
#hibernate.connection.url jdbc:hsqldb:.

再找?BR>
## MySQL

#hibernate.dialect net.sf.hibernate.dialect.MySQLDialect
#hibernate.connection.driver_class org.gjt.mm.mysql.Driver
#hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql:///test
#hibernate.connection.username root
#hibernate.connection.password

改ؓ


## MySQL

hibernate.dialect net.sf.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class org.gjt.mm.mysql.Driver
hibernate.connection.url jdbc:mysql://localhost:3306/test
hibernate.connection.username root
hibernate.connection.password

上面的URLhZ自己?BR>
完成以后创徏一个空的文Ӟ保存在你工程的类文g同个文g多wQ例如hibernate\classes\hibernate\目录下)Q文件名为:Hello_Bean.hbm.xml

内容如下Q?BR>


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>

<class name="hibernate.Hello_Bean" table="test_hibernate" >

<id name="id" column="id">

<generator class="identity"/>

</id>

<property name="name" type="string" update="true" insert="true" column="name" />
<property name="address" type="string" update="true" insert="true" column="address" />

</class>

</hibernate-mapping>



E微解释一?<class name="hibernate.Hello_Bean" table="test_hibernate" >里的name指你的生成表的类Q?BR>
table则指定你要创建的数据库表的名字,可以自由修改Q没有媄?

<id name="id" column="id">讄主键IDQ这里name的值id跟Hello_Bean.java里的ҎgetId与setId对应Q不用管q个,hibernate会自动调用,配置好就可以了,column的gؓ要生成的字段名,可以自由修改Q没有媄响?BR>
<generator class="identity"/>属性让主键的ID自增Q插入数据的时候自动加1Q?BR>
<property name="name" type="string" update="true" insert="true" column="name" />q里的name?name"跟Hello_Bean.java里的getNameҎ对应Qcolumn生成的字D名
<property name="address" type="string" update="true" insert="true" column="address" />

分别d一个字Dname与addressQ注意这里的type属性类型ؓstring,如果q里的类型与Hello_Bean.java里设|的cd不一样会出错?BR>
修改完以后保存?BR>
最后在JB里新Z个类Q名字ؓHello.javaQ我会一步步解释Q代码如下:



package hibernate;

import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.tool.hbm2ddl.SchemaExport;
import net.sf.hibernate.Session;
import net.sf.hibernate.Query;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.type.LongType;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.ScrollableResults;
import java.util.*;

/**
* @author geezer
* QQ:9986986 MSN:geezer_hot@hotmail.com
*/


public class Hello {


public Hello() {


}

public static void main(String[] args) throws Exception {

Configuration cfg = new Configuration().addClass(Hello_Bean.class);//用Hello_Bean.classcd始化

SessionFactory sessions = cfg.buildSessionFactory();//用buildSessionFactoryҎ得到一个SessionFactory对象

Session session = sessions.openSession();//再用SessionFactory的openSessionҎ得到一个session



new SchemaExport(cfg).create(true, true);//q句意思是创徏表,W一ơ运行以后,是创徏完表以后再把q行加上注释。如果徏表以后不把这一句注释掉的话会删掉以前创建的表再重新Z个?BR>



Hello_Bean my_hibernate = new Hello_Bean();//得到一个Hello_Bean对象

my_hibernate.setName("my_name");//讄Hello_Bean对象的namegؓmy_name,q里其实是说把字符串my_name当作数据库字Dname的?数据库字Dname与Hello_Beanc里的getName,setNameҎ是对应的。Ş成一个映关pR?BR>
my_hibernate.setAddress("my_address");//如上

session.save(my_hibernate);//q句很重要,my_hibernate对象写进数据库(my_hibernate对象里的name与address我们刚刚已经讄了gQ会直接把name,address的值写q数据库去)

session.flush();
session.close();


//上面是一个简单的插入数据与第一ơ运行徏表的介绍Q下面我再介l删除与修改的方?下面的代码我都加了注释,自己需要什么方法(删除Q修改,循环数据库的|把注释L可以了
HSQL比较单,大家看一下例子就应该明白了,q里׃讲了?BR>遍历数据库的Ҏ有三U,分别是Query,find,iterateQQuery和findq回一个List接口Qiterateq回一个IteratorQ具体方法可以查看这些类得知?BR>
//删除数据
/*
int a=session.delete("from Hello_Bean where id=1");//如果没有扑ֈid?的数据那么返?Q如果找到返?,q里的Hello_Bean是我们的Hello_Beanc,他跟数据库表对应Q所以我们在q里是直接用Hello_Bean来代码数据库表的?BR>System.out.println(a);
session.flush();
session.close();

*/

//QueryҎ查询数据
/*
Hello_Bean my_hibernate = null;
Query q = session.createQuery("from Hello_Bean");
// Query q = session.createQuery("from Hello_Bean where name=?");//q里?跟JDBC的PreparedStatementҎ的差不多Q只不过q里的是?开始,jdbc的是1开始?BR>// q.setString(0,"my_name");
// q.setFirstResult(0);//q句话的意思是说查询结果从W几行开始列出数?BR>// q.setMaxResults(3);//q句话的意思是取多条数据Q就跟SQL SERVER的TOPҎ和MYSQL的LIMITҎ一L意思?BR>// ScrollableResults sc=q.scroll();//得到一个ScrollableResults,可滚动的Q如果你的数据库支持游标自由Ud的话可以加上Q也是说可以判断查询结果有没有|或者移动到下一行记录等{?BR>
// if(!sc.next())
// {
// System.out.println("没有扑ֈ你需要的数据");
// }

session.flush();//如果使用了ScrollableResults的话hq行注释?BR>session.close();//如果使用了ScrollableResults的话hq行注释?BR>
List l=q.list();//q回一个List接口Q用来遍历结果集

for(int i=0;i<l.size();i++){
my_hibernate = (Hello_Bean) l.get(i);//从List中取得一个my_hibernate对象
System.out.println(my_hibernate.getName());//调用my_hibernate对象的getNameҎ取得数据库name字段的?BR>
}

*/

//findҎ查询数据
/*
Hello_Bean my_hibernate = null;
List q = session.find("from Hello_Bean");
session.flush();
session.close();

for(int i=0;i<q.size();i++)
{
my_hibernate = (Hello_Bean) q.get(i);
System.out.println(my_hibernate.getName());
}
*/

//iterateҎ查询数据
/*
Hello_Bean my_hibernate = null;
Iterator q = session.iterate("from Hello_Bean");

while(q.hasNext())
{
my_hibernate = (Hello_Bean) q.next();
System.out.println(my_hibernate.getName());
}

*/

//修改数据
/*
Query qq=session.createQuery("from Hello_Bean");

Hello_Bean my_hibernate=(Hello_Bean)session.load(Hello_Bean.class,new Integer(2));
//q里的new Integer(2)意思是修改表中id?的那一行数?必须是一个包装类的对象,如果使用int的话会出错?BR>my_hibernate.setName("geezer");//把id?的那一行数据的name字段值改?geezer"
session.flush();
session.close();

*/

}

}

最后运行就可以了?BR>
如果大家有什么不清楚的,可以下蝲q篇文章的例子看看,q行一下?BR>
下蝲完以后用JB打开hibernate.jpx可以了。用之前把hibernate和MYSQL的驱动加q去Q方法如果不知道再看看本章开头部分?BR>

常见错误Q?BR>Caused by: org.dom4j.DocumentException: Invalid byte 2 of 2-byte UTF-8 sequence. Nested exception: Invalid byte 2 of 2-byte UTF-8 sequence.
如果出现q行错误说明你的xml配置文g有不规范的字W,查下?BR>
net.sf.hibernate.MappingException: Error reading resource: hibernate/Hello_Bean.hbm.xml


如果出现q行错误说明你的hibernate的XML配置文g有错

net.sf.hibernate.MappingException: Resource: hibernate/Hello_Bean.hbm.xml not found


如果出现q行错误说明hibernate的XML配置文g没有扑ֈQ你应该把XML文g攑֜与你的类文g同个目录?本文中是攑֜hibernate\classes\hibernate\目录下,也就是跟Hello_Bean.classcL件一赗?BR>
net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property name in class hibernate.Hello_Bean


如果出现q行错误说明你的xml文g里设|的字段名name的gHello_Bean.javac里的getXXX或setXXXҎ不一致?BR>
net.sf.hibernate.HibernateException: JDBC Driver class not found: org.gjt.mm.mysql.Driver
如果出现q行错误说明你的MYSQL驱动没有加进JB库里或者不在CLASSPATH里?BR>


代码下蝲Q?/FONT>

http://www.tkk7.com/Files/limq/hibernate_demo.rar


我的生活p是抽烟,自从点着火的那一d始就注定了一生一不变的味道Q直到熄灭ؓ止~ 而我的生命就是烟......
==========================
p涂一?A href="http://php.phpx.com/http://www.ht13.com" target=_blank>http://www.ht13.com


limq 2005-03-03 17:29 发表评论
]]>
Servlet 路径 http://www.tkk7.com/limq/archive/2005/03/01/1600.htmllimqlimqTue, 01 Mar 2005 15:29:00 GMThttp://www.tkk7.com/limq/archive/2005/03/01/1600.htmlhttp://www.tkk7.com/limq/comments/1600.htmlhttp://www.tkk7.com/limq/archive/2005/03/01/1600.html#Feedback1http://www.tkk7.com/limq/comments/commentRss/1600.htmlhttp://www.tkk7.com/limq/services/trackbacks/1600.html首先建立一个测试页?path.jsp
<%@ page contentType="text/html; charset=gb2312" language="java" import="java.sql.*" errorPage="" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<title>无标题文?lt;/title>
</head>

<body>
h服务器:
<%= request.getServerName() %><br>
使用协议Q?BR><%= request.getProtocol() %><br>
hҎQ?BR><%= request.getMethod() %><br>
h断口P
<%= request.getServerPort() %><br>
Context路径Q?BR><%= request.getContextPath() %><br>
Servlet路径Q?BR><%= request.getServletPath() %><br>
URI路径Q?BR><%= request.getRequestURI() %><br>
查询字串Q?BR><%= request.getQueryString() %><br>
<br>
使用者主IPQ?BR><%= request.getRemoteAddr() %><br>

<%= request.getRemotePort() %>
</body>
</html>

再用一下方式测?
http://localhost:8080/WebModule1/path.jsp?name=justin&nick=caterpillar

l果?
h服务器: localhost
使用协议Q?HTTP/1.1
hҎQ?GET
h断口P 8080
Context路径Q?/WebModule1
Servlet路径Q?/path.jsp
URI路径Q?/WebModule1/path.jsp
查询字串Q?name=justin&nick=caterpillar

使用者主?CIPQ?127.0.0.1
1490



limq 2005-03-01 23:29 发表评论
]]>
利用 Jsp+Taglib+JavaBean 快速构?动态数据库查询模板http://www.tkk7.com/limq/archive/2005/02/28/1580.htmllimqlimqMon, 28 Feb 2005 14:58:00 GMThttp://www.tkk7.com/limq/archive/2005/02/28/1580.htmlhttp://www.tkk7.com/limq/comments/1580.htmlhttp://www.tkk7.com/limq/archive/2005/02/28/1580.html#Feedback0http://www.tkk7.com/limq/comments/commentRss/1580.htmlhttp://www.tkk7.com/limq/services/trackbacks/1580.html阅读全文

limq 2005-02-28 22:58 发表评论
]]>
JBuilder2005 ?jsp2.0 自定义标{?http://www.tkk7.com/limq/archive/2005/02/20/1350.htmllimqlimqSat, 19 Feb 2005 16:20:00 GMThttp://www.tkk7.com/limq/archive/2005/02/20/1350.htmlhttp://www.tkk7.com/limq/comments/1350.htmlhttp://www.tkk7.com/limq/archive/2005/02/20/1350.html#Feedback1http://www.tkk7.com/limq/comments/commentRss/1350.htmlhttp://www.tkk7.com/limq/services/trackbacks/1350.html要在jb2005下实?/SPAN>jsp2.0首先需要配|?/SPAN>Tomcat5.0以上的版?/SPAN>,其次q要jsp2.0?/SPAN>jar文g,

具体Ҏ请参?/SPAN> 上一文?/SPAN>JBuilder2005 ?/SPAN> jsp2.0 初体?/SPAN>,本文主要讲的?/SPAN>jb2005下自定义标签的开?/SPAN>.

Z能够快速开?/SPAN>,我用了open source ?/SPAN>JSP Tag Wizards v3.0插g,它可以帮助我们快速开?/SPAN>jsp1.1,?/SPAN>jsp2.0的各U标{?/SPAN>.下蝲地址?/SPAN> : http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=21573. 下载来的压~包解压?/SPAN>JBuilder/lib/ext中就可以?/SPAN>.

新徏一?/SPAN>Mytag2的工E?/SPAN>,q里要将我们上一节说?/SPAN>jsp2.0以及JSTL1.1的包dq去.image001.jpg

新徏一?/SPAN>web模块

image002.jpg

建立jsp 标签文g,双击 JPS Tag

image003.jpg

image004.jpg

׃我们q里使用的是SimpleTagSupport 所以勾?/SPAN> Simple tag, 点击 OKimage005.jpg

可以看到JSP Tag Wizards v3.0已经自动为我们生成了Hello.java文g.

q里我将dotag()Ҏ 改ؓ

public void doTag() throws IOException, JspException {

        JspWriter out = getJspContext().getOut();

        /** @todo specify any output value for this tag */

        out.print("Hello JSp2.0 tag");

    }

  然后建立 tld 文g. 如图选择Taglib Descriptor

image006.jpg

接下来我们可以选择要生?/SPAN>tld 文g ?/SPAN> 位置,和名U?/SPAN>, q里我没有改变其默认?/SPAN>.

image007.jpg

一直点?/SPAN> Next > 直到

image008.jpg

q里我们可以选择标签体内容ؓ Empty.   Finish .

image009.jpg

可以看到JSP Tag Wizards v3.0 为我们生成了Mytag2.tld文g,以及相关配置.接下来我们需要将它{Ud Web-Inf/tld ?/SPAN>, 叛_WEB-INF>New>Directory

image010.jpg

image011.jpg

点击 ok.

在将刚才生成?/SPAN> Mytag2.tld文gUd臛_?/SPAN>.

image012.jpg

 

新徏一?/SPAN>jsp文g.

<%@ page contentType="text/html; charset=GB18030" %>

<%@ taglib uri="/WEB-INF/tld/Mytag2.tld"  prefix="mytag"%>

</SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>jsp1</SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>

<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

     

    好了大功告成?/SPAN>,让我们来看看执行l果?/SPAN>

    image013.jpg



    limq 2005-02-20 00:20 发表评论
    ]]>
    JBuilder2005 ?jsp2.0 初体?/title><link>http://www.tkk7.com/limq/archive/2005/02/19/1347.html</link><dc:creator>limq</dc:creator><author>limq</author><pubDate>Sat, 19 Feb 2005 15:38:00 GMT</pubDate><guid>http://www.tkk7.com/limq/archive/2005/02/19/1347.html</guid><wfw:comment>http://www.tkk7.com/limq/comments/1347.html</wfw:comment><comments>http://www.tkk7.com/limq/archive/2005/02/19/1347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.tkk7.com/limq/comments/commentRss/1347.html</wfw:commentRss><trackback:ping>http://www.tkk7.com/limq/services/trackbacks/1347.html</trackback:ping><description><![CDATA[<P><IMG height=1 src="/FreeTextBox/Utility/spacer.gif" width=1></P> <P class=MsoNormal><SPAN lang=EN-US>JBuilder2005 </SPAN><SPAN style="FONT-FAMILY: 宋体">比较前一个版本提供了</SPAN><SPAN lang=EN-US>jsp2.0,</SPAN><SPAN style="FONT-FAMILY: 宋体">以及</SPAN><SPAN lang=EN-US>servlet2.4</SPAN><SPAN style="FONT-FAMILY: 宋体">的支?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">|于</SPAN><SPAN lang=EN-US>jsp2.0</SPAN><SPAN style="FONT-FAMILY: 宋体">规范q里׃多说?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">以下介绍?/SPAN><SPAN lang=EN-US>jb2005</SPAN><SPAN style="FONT-FAMILY: 宋体">中的体会</SPAN><SPAN lang=EN-US>.</SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">一</SPAN> <SPAN style="FONT-FAMILY: 宋体">安装讄</SPAN><SPAN lang=EN-US>Tomcat5.0</SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">我们知道</SPAN><SPAN lang=EN-US>,Jsp2.0</SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US>Tomcat5.0</SPAN><SPAN style="FONT-FAMILY: 宋体">以上的版本所支持?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">所以如果你使用的是</SPAN><SPAN lang=EN-US>jbuilder</SPAN><SPAN style="FONT-FAMILY: 宋体">默认?/SPAN><SPAN lang=EN-US>tomcat4.0</SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US>WEB</SPAN><SPAN style="FONT-FAMILY: 宋体">模块是看不到</SPAN><SPAN lang=EN-US>jsp2.0,</SPAN><SPAN style="FONT-FAMILY: 宋体">以及</SPAN><SPAN lang=EN-US>servlet2.4</SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">所以要首先安装讄</SPAN><SPAN lang=EN-US>Tomcat5.0</SPAN><SPAN style="FONT-FAMILY: 宋体">以上的版?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">然后?/SPAN><SPAN lang=EN-US>Jbuilder</SPAN><SPAN style="FONT-FAMILY: 宋体">中设|如?/SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体"><IMG height=475 alt=image001.jpg src="http://www.tkk7.com/images/blogjava_net/limq/images/image001.jpg" width=554 border=0></SPAN></P><SPAN style="FONT-FAMILY: 宋体"> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">?/SPAN> <SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US> http://jakarta.apache.org</SPAN><SPAN style="FONT-FAMILY: 宋体">下蝲</SPAN> <SPAN lang=EN-US>jakarta-taglibs-standard-current.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">是</SPAN><SPAN lang=EN-US>JSTL1.1</SPAN><SPAN style="FONT-FAMILY: 宋体">的包</SPAN><SPAN lang=EN-US>,(jb</SPAN><SPAN style="FONT-FAMILY: 宋体">中也可以</SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">但是L提示有文件找不到</SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">所以我׃了一个新?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">问题解决?/SPAN><SPAN lang=EN-US>),</SPAN><SPAN style="FONT-FAMILY: 宋体">解压后?/SPAN><SPAN lang=EN-US>jstl.jar, standard.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">复制?/SPAN><SPAN lang=EN-US>JBuilder2005\lib</SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US>,</SPAN><SPAN style="FONT-FAMILY: 宋体">配置如下</SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体"><IMG height=322 alt=image002.jpg src="http://www.tkk7.com/images/blogjava_net/limq/images/image002.jpg" width=553 border=0></SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体"><SPAN style="FONT-FAMILY: 宋体">然后讄</SPAN><SPAN lang=EN-US>jsp-api.jar,</SPAN><SPAN style="FONT-FAMILY: 宋体">我的路径?/SPAN><SPAN lang=EN-US>C:\Program Files\Apache Software Foundation\Tomcat 5.0\common\lib</SPAN></SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体"><SPAN lang=EN-US><IMG height=322 alt=image003.jpg src="http://www.tkk7.com/images/blogjava_net/limq/images/image003.jpg" width=553 border=0></SPAN></SPAN></P><SPAN style="FONT-FAMILY: 宋体"><SPAN lang=EN-US> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">?/SPAN> <SPAN style="FONT-FAMILY: 宋体">新徏立一个程?/SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>File>New Project> name</SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US>jsp2 Next></SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US> Require Libraries </SPAN><SPAN style="FONT-FAMILY: 宋体">中将我们刚才d?/SPAN><SPAN lang=EN-US>jsp2.0</SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US>JTSL1.1</SPAN><SPAN style="FONT-FAMILY: 宋体">选上</SPAN><SPAN lang=EN-US>.>Finish</SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>File>new>Web> WebModule </SPAN><SPAN style="FONT-FAMILY: 宋体">q里</SPAN> <SPAN style="FONT-FAMILY: 宋体">要记得选择</SPAN><SPAN lang=EN-US> servlet2.4,jsp2.0 ,name </SPAN><SPAN style="FONT-FAMILY: 宋体">?/SPAN><SPAN lang=EN-US> jsp2  Next></SPAN><SPAN style="FONT-FAMILY: 宋体">选择</SPAN><SPAN lang=EN-US>JTSL1.1(JTSL1.0)</SPAN><SPAN style="FONT-FAMILY: 宋体">选项</SPAN><SPAN lang=EN-US>.> Finish</SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">?/SPAN> <SPAN style="FONT-FAMILY: 宋体">刚才下载的</SPAN><SPAN lang=EN-US>jakarta-taglibs-standard-current.jar</SPAN><SPAN style="FONT-FAMILY: 宋体">中的</SPAN><SPAN lang=EN-US>tld</SPAN><SPAN style="FONT-FAMILY: 宋体">文g夹复制到</SPAN><SPAN lang=EN-US>WEB-INF</SPAN><SPAN style="FONT-FAMILY: 宋体">?</SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体"><IMG height=338 alt=image004.jpg src="http://www.tkk7.com/images/blogjava_net/limq/images/image004.jpg" width=636 border=0></SPAN></P><SPAN style="FONT-FAMILY: 宋体"> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">?/SPAN> <SPAN style="FONT-FAMILY: 宋体">修改</SPAN><SPAN lang=EN-US>web.xml</SPAN></P> <P class=MsoNormal><SPAN lang=EN-US><?xml version="1.0" encoding="UTF-8"?></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US><web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>  <display-name>Web</display-name></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>  <jsp-config></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    <taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-location>/WEB-INF/tld/c.tld</taglib-location></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    </taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    <taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-uri>http://java.sun.com/jsp/jstl/xml</taglib-uri></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-location>/WEB-INF/tld/x.tld</taglib-location></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    </taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    <taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-uri>http://java.sun.com/jsp/jstl/fmt</taglib-uri></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-location>/WEB-INF/tld/fmt.tld</taglib-location></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    </taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    <taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-uri>http://java.sun.com/jsp/jstl/sql</taglib-uri></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>      <taglib-location>/WEB-INF/tld/sql.tld</taglib-location></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>    </taglib></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>  </jsp-config></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US></web-app></SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">?/SPAN> <SPAN style="FONT-FAMILY: 宋体">建立一?/SPAN><SPAN lang=EN-US>html </SPAN><SPAN style="FONT-FAMILY: 宋体">文gҎ是右?/SPAN><SPAN lang=EN-US>Moudule directory>New>File>Name=Param,Type=Html</SPAN></P> <P class=MsoNormal><SPAN style="FONT-FAMILY: 宋体">代码?/SPAN><SPAN lang=EN-US>:</SPAN></P> <P class=MsoNormal><SPAN lang=EN-US><html></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US><head></SPAN></P> <P class=MsoNormal><SPAN lang=EN-US>  <title>CH6 - Param.html

     

    EL隐含对象 param?/SPAN>paramValues

     

     

    姓名Q?/SPAN>

     

    密码Q?/SPAN>

     

    性别Q?/SPAN>?/SPAN>

                  ?/SPAN>

     

    q龄Q?/SPAN>

     

    兴趣Q?/SPAN>看书

            玩游?/SPAN>

            旅游

            听音?/SPAN>

            看电?/SPAN>

     

     

           传?/SPAN>"/>

              清除"/>

     

    ?/SPAN> 新徏一?/SPAN>jsp文g

    File>New>Web>JSP >(Name=Param)>Next>N?/SPAN>JSTL1.1(JSTL1.0)>Finish

    代码如下:

    <%@ page contentType="text/html; charset=GB2312" %>

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

    <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

      CH6 - Param.jsp

     

     

    EL隐含对象 param?/SPAN>paramValues

     

     

     

      姓名Q?/SPAN>

      密码Q?/SPAN>

      性别Q?/SPAN>

      q龄Q?/SPAN>

      兴趣Q?/SPAN>

                 

     

    վ֩ģ壺 AƬ߹ۿ| 337pձŷ޴| ĻƵ| ٸ| һƬѿ| ղһ| ĻѸ| պvavaŷva| ƷƵ| þ޾ƷƷ| һѹۿ| Ʒþ| AVַ߹ۿ| mm1313޹ƷԿ| avһ| wwwƵ߹ۿ| þ޾ƷĻ| þþþþþ99Ʒ| ޹Ʒר| պaëƬƵ| jizz18Ƶ| ޸һ| պƵ| վ| þþƷAV鶹վ| 99߾Ʒѹۿ| ƷһëƬ| ɫĻAV| 99ƵȫѾƷȫĻ| ˳վ߹ۿ| ˳Ƶx8x8| Ƶ߹ۿ| þþƷAVũ帾Ů | ѻɫӰ߹ۿ| 91޹˾þþƷ| Ļ˾Ʒ | պ伤Ƶ߲ | ߹ۿAVվ| ޾Ʒ91| ۺϼƵ| ޾ƷƵ|

    建立好后应ؓ

    image005.jpg

    执行l果:

    image006.jpg

     

    image007.jpg

     

     

     



    limq 2005-02-19 23:38 发表评论
    ]]>