<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>gecko的博客</title>
<link>http://blogger.org.cn/blog/blog.asp?name=gecko</link>
<description>gecko的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[Active Directory 作为LDAP用java访问]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=9149</link>
<author>gecko</author>
<pubDate>2005/10/13 16:23:00</pubDate>
<description><![CDATA[<P><STRONG>问</STRONG>：我们的 J2EE 应用程序目前正通过我们在内部开发的 LDAPAuthentication 类访问 Domino LDAP Server 进行认证。这一 LDAPAuthentication 类将使用 JNDI API 来搜索 Domino LDAP Server。然而，我们无法使用这个 LDAPAuthentication 类来搜索 Active Directory，因为 Active Directory 不支持 JNDI API。有没有另一个 JAVA API（Active Directory 支持）可供我们用来定制 LDAPAuthentication 类以访问 Active Directory 进行认证？</P>
<P><STRONG>答</STRONG>：ActiveDirectory 支持 LDAP 协议，您可以在 Java 中使用标准的 Java JNDI API 来访问它。LDAP 服务器并非真的必须支持 JNDI API，只要支持 LDAP 协议就可以了。如果您有问题，最有可能是关于您打算如何访问 ActiveDirectory 的配置问题。我已经提供了一个简单的测试案例程序来认证一个 LDAP 服务器的识别名。请确认您的 LDAPAuthentication 类与它基本相同。一般情况下，您对待 ActiveDirectory 不必与对待任何其他的 LDAP 服务器有什么不同。</P>
<P>import java.util.Properties;<BR>import javax.naming.*;&nbsp;&nbsp; <BR>import javax.naming.directory.*;<BR><BR>//include the JNDI in the classpath. You should use the same JDK used by WebSphere Application server.<BR><BR>class wasLdapAuth <BR>{<BR>public static void main(String[] args) <BR>{<BR>&nbsp;&nbsp;&nbsp; //***************** user information to be authenticated ********************************<BR>&nbsp;&nbsp;&nbsp; //*****************Please modify the following three properties accordingly ************<BR>&nbsp;&nbsp;&nbsp; String ldapHost= "ldap://cliang1.austin.ibm.com:389"; //ldap host + port number<BR>&nbsp;&nbsp;&nbsp; String DN = "cn=user1, ou=Austin,o=ibm,c=us";&nbsp;&nbsp; // DN to be authenticated <BR>&nbsp;&nbsp;&nbsp; String password = "security";&nbsp; //&nbsp; DN's password&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; //***************** End of user information<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; Properties props = new Properties();&nbsp; <BR>&nbsp;&nbsp;&nbsp; props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");&nbsp;&nbsp;&nbsp; <BR> //for websphere 4.0 and 5.0<BR>&nbsp;&nbsp;&nbsp; //props.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.jndi.LDAPCtxFactory");&nbsp;&nbsp;&nbsp;&nbsp; <BR> // for WebSphere 3.5 release <BR>&nbsp;&nbsp;&nbsp; props.put(Context.SECURITY_AUTHENTICATION, "simple");&nbsp;&nbsp;&nbsp;&nbsp; //use simple authentication mechanism<BR>&nbsp;&nbsp;&nbsp; props.put(Context.SECURITY_CREDENTIALS, password);&nbsp; <BR>&nbsp;&nbsp;&nbsp; props.put(Context.SECURITY_PRINCIPAL, DN);&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; props.put(Context.PROVIDER_URL, ldapHost);&nbsp; <BR><BR>&nbsp;&nbsp;&nbsp; long start = System.currentTimeMillis();<BR>&nbsp;&nbsp;&nbsp; long end=0;<BR>&nbsp;&nbsp;&nbsp; long time =0;<BR><BR>&nbsp;&nbsp;&nbsp; try <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("authenticating");&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DirContext ctx = new InitialDirContext(props);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("authenticated"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end = System.currentTimeMillis();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time = end - start;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( "authentication takes = " + time + " millis");&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("successfully authenticate DN: "+DN);<BR><BR>&nbsp;&nbsp;&nbsp; } <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch (Exception ex)<BR>&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end = System.currentTimeMillis();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; time = end - start;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Exception is "+ex.toString()); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ex.printStackTrace();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println( "authentication takes = " + time + " millis");&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("fail to authenticate DN: "+DN);<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR>}<BR><BR></P>]]></description>
</item><item>
<title><![CDATA[从中央气象台抓取天气预报]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=9040</link>
<author>gecko</author>
<pubDate>2005/10/8 14:33:45</pubDate>
<description><![CDATA[<P>这几天郑州下雪,一直盼望晴天的到来,于是关注天气情况.</P>
<P>可以Google一下:tq 郑州</P>
<P>如今写了个抓取中央气象台的天气预报(<A href="http://www.tq121.com">http://www.tq121.com</A>)</P>
<P>public string GetWeather(string url)<BR>{<BR>&nbsp;&nbsp; string weacherhtml=String.Empty;<BR>&nbsp;&nbsp; HttpWebRequest rt=null;<BR>&nbsp;&nbsp; HttpWebResponse rs=null;<BR>&nbsp;&nbsp; Stream stream=null;<BR>&nbsp;&nbsp; StreamReader sr=null;<BR>&nbsp;<BR>&nbsp;&nbsp; try<BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp; rt=(HttpWebRequest)WebRequest.Create(url);<BR>&nbsp;&nbsp; rs=(HttpWebResponse)rt.GetResponse();<BR>&nbsp;&nbsp; stream=rs.GetResponseStream();<BR>&nbsp;&nbsp; sr=new StreamReader(stream,System.Text.Encoding.Default);<BR>&nbsp;&nbsp; weacherhtml=sr.ReadToEnd();<BR>&nbsp;&nbsp; <BR>}<BR>&nbsp;&nbsp; catch(Exception ee)<BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; Response.Write("&lt;script&gt;alert('发生异常')&lt;/script&gt;");<BR>&nbsp;&nbsp; }<BR>&nbsp;&nbsp; finally<BR>&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp; sr.Close();<BR>&nbsp;&nbsp;&nbsp; stream.Close();<BR>&nbsp;&nbsp;&nbsp; rs.Close();<BR>&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp; int start=weacherhtml.IndexOf("郑州");<BR>&nbsp;&nbsp;&nbsp; int end=weacherhtml.IndexOf("隐私保护");</P>
<P>&nbsp;&nbsp;&nbsp; return weacherhtml.Substring(start,end-start);</P>
<P>}<BR>别的城市天气情况请调用相应的URL,以及修改城市名称.<BR></P>
<P>引自他人</P>]]></description>
</item><item>
<title><![CDATA[rss2sample.xml]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=9039</link>
<author>gecko</author>
<pubDate>2005/10/8 14:32:17</pubDate>
<description><![CDATA[<P>&lt;?xml version="1.0"?&gt;<BR>&lt;rss version="2.0"&gt;<BR>&nbsp;&nbsp; &lt;channel&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;Liftoff News&lt;/title&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;link&gt;http://liftoff.msfc.nasa.gov/&lt;/link&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;description&gt;Liftoff to Space Exploration.&lt;/description&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;language&gt;en-us&lt;/language&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pubDate&gt;Tue, 10 Jun 2003 04:00:00 GMT&lt;/pubDate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;lastBuildDate&gt;Tue, 10 Jun 2003 09:41:01 GMT&lt;/lastBuildDate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;docs&gt;http://blogs.law.harvard.edu/tech/rss&lt;/docs&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;generator&gt;Weblog Editor 2.0&lt;/generator&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;managingEditor&gt;editor@example.com&lt;/managingEditor&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;webMaster&gt;webmaster@example.com&lt;/webMaster&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;Star City&lt;/title&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;link&gt;http://liftoff.msfc.nasa.gov/news/2003/news-starcity.asp&lt;/link&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;description&gt;How do Americans get ready to work with Russians aboard the International Space Station? They take a crash course in culture, language and protocol at Russia's &amp;lt;a href="<A href='http://howe.iki.rssi.ru/GCTC/gctc_e.htm"&amp;gt;Star'>http://howe.iki.rssi.ru/GCTC/gctc_e.htm"&amp;gt;Star</A> City&amp;lt;/a&amp;gt;.&lt;/description&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pubDate&gt;Tue, 03 Jun 2003 09:39:21 GMT&lt;/pubDate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;guid&gt;http://liftoff.msfc.nasa.gov/2003/06/03.html#item573&lt;/guid&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;description&gt;Sky watchers in Europe, Asia, and parts of Alaska and Canada will experience a &amp;lt;a href="<A href='http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&amp;gt;partial'>http://science.nasa.gov/headlines/y2003/30may_solareclipse.htm"&amp;gt;partial</A> eclipse of the Sun&amp;lt;/a&amp;gt; on Saturday, May 31st.&lt;/description&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pubDate&gt;Fri, 30 May 2003 11:06:42 GMT&lt;/pubDate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;guid&gt;http://liftoff.msfc.nasa.gov/2003/05/30.html#item572&lt;/guid&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;The Engine That Does More&lt;/title&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;link&gt;http://liftoff.msfc.nasa.gov/news/2003/news-VASIMR.asp&lt;/link&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;description&gt;Before man travels to Mars, NASA hopes to design new engines that will let us fly through the Solar System more quickly.&nbsp; The proposed VASIMR engine would do that.&lt;/description&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pubDate&gt;Tue, 27 May 2003 08:37:32 GMT&lt;/pubDate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;guid&gt;http://liftoff.msfc.nasa.gov/2003/05/27.html#item571&lt;/guid&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;item&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;title&gt;Astronauts' Dirty Laundry&lt;/title&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;link&gt;http://liftoff.msfc.nasa.gov/news/2003/news-laundry.asp&lt;/link&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;description&gt;Compared to earlier spacecraft, the International Space Station has many luxuries, but laundry facilities are not one of them.&nbsp; Instead, astronauts have other options.&lt;/description&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pubDate&gt;Tue, 20 May 2003 08:56:02 GMT&lt;/pubDate&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;guid&gt;http://liftoff.msfc.nasa.gov/2003/05/20.html#item570&lt;/guid&gt;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/item&gt;<BR>&nbsp;&nbsp; &lt;/channel&gt;<BR>&lt;/rss&gt;</P>]]></description>
</item><item>
<title><![CDATA[指定域的名称或安全标识SID与该域的信任信息不一致]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=9038</link>
<author>gecko</author>
<pubDate>2005/10/8 14:29:30</pubDate>
<description><![CDATA[<BR>1、首先更改vpc的配置文件里的MAC地址。<BR>2、解压在windows2003光盘里x:\support\tools\deploy.cab的文件，运行sysprep.exe,出现程序界面，点击重新封装，完成后重起OK]]></description>
</item><item>
<title><![CDATA[什么是 RSS]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=9037</link>
<author>gecko</author>
<pubDate>2005/10/8 14:29:27</pubDate>
<description><![CDATA[<P>RSS 是一种站点内容聚合的格式。</P>
<P>它的名字是Really Simple Syndication 的的简写。</P>
<P>RSS是XML的一种。所有的RSS文档都遵循 XML 1.0规范, 该规范发布在W3C网站上。</P>
<P>这里是RSS版本历史的一个概要。</P>
<P>在一个RSS文档中，最外层是一个&lt;rss&gt;元素，这个元素必须规定version属性，该属性明确了本文档遵从何种RSS版本规范。如果一个RSS文档以这个规范来表示，那么它的version属性就必须是2.0。</P>
<P>&lt;rss&gt;元素只有一个子元素&lt;channel&gt;，包含了关于这个频道(元数据)和它的内容的一些信息。</P>
<P>样本文件</P>
<P>这里有一些RSS样本文件： RSS 0.91, 0.92 和 2.0。</P>
<P>注意这些样本文件所指向的链接地址和服务器可能已经不再存在。在撰写0.91文档的时候，这个0.91的样本文件就已经创建了。维护一个样本文件的历史也许是一个不错的主意。</P>
<P>关于本文档</P>
<P>本文档完成于2002年秋天，版本为 2.0.1。</P>
<P>它包含从 RSS 0.91 规范(2000年)开始的所有的修改和添加，以及包含在RSS 0.92 （2000年12月）和RSS 0.94（2002年8月）中的新的特性。</P>
<P>详细的文档历史纪录请参阅这里。</P>
<P>本文档中首先介绍必须的和可选的频道元素；接着介绍了&lt;item&gt;的子元素。最后回答了一些经常碰到的问题，并提供了未来的发展路线和RSS扩展的指导方针。</P>
<P><BR>必需的频道元素</P>
<P>下面是一个必须包含的频道(channel)元素的列表，每一个都有一个简单的描述、一个例子、应该出现的位置和更详细描述的链接地址。</P>
<P>01.●　title　<BR>名称：title <BR>描述：频道的名称。它表明别人如何访问你的服务。如果你有一个与你的RSS文件内容一致的HTML网站，你的title元素值应该与你的网站的标题相同。 <BR>例子：GoUpstate.com 的新闻大字标题。 </P>
<P>02.●　link　<BR>名称：link <BR>描述：对应频道的网站的URL链接地址。 <BR>例子：<A href="http://www.goupstate.com/">http://www.goupstate.com/</A> 。 </P>
<P>03.●　description　<BR>名称：description <BR>描述：关于频道的描述。 <BR>例子：The latest news from GoUpstate.com, a Spartanburg Herald-Journal Web site。<BR>可选的频道元素</P>
<P>下面是一个可选的频道(channel)元素的列表。 <BR>01.●　language<BR>名称：language<BR>描述：频道使用的语言。比如，在一个网站上，允许聚合所有的意大利语站点到相应的分组。对于这个元素，可使用的值，参阅 Netscape提供的清单。或者可以参阅W3C定义的 清单。 <BR>例子：en-us。 </P>
<P>02.●　copyright<BR>名称：copyright<BR>描述：频道内容的版权声明。 <BR>例子：Copyright 2002, Spartanburg Herald-Journal </P>
<P>03.●　managingEditor<BR>名称：managingEditor<BR>描述：频道内容责任编辑的电子邮件地址。 <BR>例子：<A href="mailto:geo@herald.com">geo@herald.com</A> (George Matesky) </P>
<P>04.●　webMaster<BR>名称：webMaster<BR>描述：频道技术支持人员的电子邮件地址。 <BR>例子：<A href="mailto:betty@herald.com">betty@herald.com</A> (Betty Guernsey) </P>
<P>05.●　pubDate<BR>名称：pubDate<BR>描述：频道内容发布的日期。所有的日期和时间都必须遵循 RFC 822规范, 但年份可以用２个或４个字母表示(首选４个字母)。 <BR>例子：Sat, 07 Sep 2002 00:00:01 GMT </P>
<P>06.●　lastBuildDate<BR>名称：lastBuildDate<BR>描述：频道内容的最后修改时间。 <BR>例子：Sat, 07 Sep 2002 09:42:31 GMT </P>
<P>07.●　category<BR>名称：category <BR>描述：指定频道所属的一个或多个分类。遵循与item级category元素相同的规则。详见这里。 <BR>例子：&lt;category&gt;Newspapers&lt;/category&gt; </P>
<P>08.●　generator<BR>名称：generator <BR>描述：表明生成频道的程序名称的字符串。 <BR>例子：MightyInHouse Content System v2.3 </P>
<P>09.●　docs<BR>名称：docs<BR>描述：指向该RSS文件所用格式说明文档的URL链接地址。 <BR>例子：<A href="http://blogs.law.harvard.edu/tech/rss">http://blogs.law.harvard.edu/tech/rss</A>。 </P>
<P>10.●　cloud<BR>名称：cloud<BR>描述：允许通过注册一个cloud来处理获得频道的更新通知，并为rss种子实现一个轻量级的发布订阅协议，详见这里。 <BR>例子：&lt;cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="pingMe" protocol="soap"/&gt; </P>
<P>11.●　ttl<BR>名称：ttl <BR>描述：ttl是Time to live的缩写，表示生存时间。它表示频道从源更新之前可以缓存的时间。详见 这里。 <BR>例子：&lt;ttl&gt;60&lt;/ttl&gt;。 </P>
<P>12.●　image<BR>名称：image<BR>描述：指定一个可以在频道中显示的GIF、JPEG或者 PNG 图像。详见这里。 <BR>例子：。</P>
<P>13.●　rating<BR>名称：rating<BR>描述：频道的 PICS 内容分级信息。 <BR>例子： 。</P>
<P>14.●　textInput<BR>名称：textInput<BR>描述：指定一个可以在频道中显示的文本输入框。详见这里。<BR>例子：。 </P>
<P>15.●　skipHours<BR>名称：skipHours<BR>描述：提示聚合器，可以跳过那些小时的时间段。详见这里。<BR>例子：。 </P>
<P>16.●　skipDays<BR>名称：skipDays<BR>描述：提示聚合器，可以跳过那些天的时间段。详见这里。 <BR>例子：。 </P>
<P>&lt;channel&gt;的子元素&lt;image&gt; </P>
<P>&lt;image&gt; 是 &lt;channel&gt;的一个可选子元素, 它本身包含了三个必须的和三个可选的子元素。</P>
<P>&lt;url&gt;是一个GIF、JPEG或PNG图像文件的URL链接地址，该图像代表整个频道。</P>
<P>&lt;title&gt;用于描述上面的图像，当频道在HTML中显示时，用于HTML语言中的&lt;img&gt;的alt属性。</P>
<P>&lt;link&gt;是要连接的站点的url，当显示频道时，图像的连接指向该站点。(在实际中，&lt;title&gt;和&lt;link&gt;应该与频道的&lt;title&gt;和&lt;link&gt;有相同的值)。</P>
<P>可选的元素包括&lt;width&gt;和&lt;height&gt;，它们是数字类型，指定图像的宽度和高度，单位为像素。<BR>&lt;description&gt;就是link的TITLE属性中文本，它将在调用网页时显示出来。 </P>
<P>图像宽度的最大值为144，默认值为88 。</P>
<P>图像高度的最大值为400，默认值为31 。</P>
<P>&lt;channel&gt;的子元素&lt;cloud&gt;</P>
<P>&lt;cloud&gt; 是 &lt;channel&gt;的一个可选子元素。</P>
<P>它指定一个可以支持rssCloud接口的web服务，rssCloud接口可以在HTTP-POST、XML-RPC或SOAP1.1中实现。</P>
<P>它的目的是允许通过注册一个cloud来处理获得频道的更新通知，从而为RSS feeds实现一个轻量级的发布订阅协议.</P>
<P>&lt;cloud domain="rpc.sys.com" port="80" path="/RPC2" registerProcedure="myCloud.rssPleaseNotify" protocol="xml-rpc" /&gt;</P>
<P>在这个例子中，为了请求频道通知，你需要发送一个XML-RPC消息到rpc.sys.com的80端口，路径为/RPC2。调用的程序为为myCloud.rssPleaseNotify。 </P>
<P>这个元素的详细说明和 rssCloud 接口说明请参阅 这里。</P>
<P>&lt;channel&gt;子元素&lt;ttl&gt;</P>
<P>&lt;ttl&gt;&lt;channel&gt;的一个可选子元素。</P>
<P>ttl是Time to live的缩写，表示生存时间。它表示频道从源重新更新之前可以缓存的时间。这使得rss源可以被一个支持文件共享的网络所管理，例如Gnutella。</P>
<P>例子: &lt;ttl&gt;60&lt;/ttl&gt;</P>
<P>&lt;channel&gt;的子元素&lt;textInput&gt;</P>
<P>频道可以选择包含一个&lt;textInput&gt;子元素，它本身包含了四个必须的子元素。</P>
<P>&lt;title&gt;--文本输入区域提交按钮的标签。</P>
<P>&lt;description&gt;--文本输入区域的描述。</P>
<P>&lt;name&gt;--文本输入区域中文本对象的名称。</P>
<P>&lt;link&gt;--处理文本输入请求的CGI脚本的URL链接地址。</P>
<P>使用&lt;textInput&gt;元素的目的看起来有些神秘。你可以用它提供一个搜索引擎输入框，或让读者提供反馈信息。许多聚合器忽略该元素。 </P>
<P>&lt;item&gt;的元素</P>
<P>一个频道可以包含许多&lt;item&gt;元素。一个项目可以代表一个"故事" ——比如说一份报纸或杂志上的故事；如果是这样的话，那么项目的描述则是故事的摘要，项目的链接则指向整个故事的链接位置。一个项目也可以本身是完整的，如果是这样的话，项目的描述就包含了文本(整体以HTML格式编码是可以的；参见 例子)，而链接和标题可以省略。项目的所有元素都是可选的，但是至少要包含一个标题(title)或描述(description)。 </P>
<P>01.●　title<BR>名称：title<BR>描述：item的标题。 <BR>例子：Venice Film Festival Tries to Quit Sinking </P>
<P>02.●　link<BR>名称：link<BR>描述：item的URL链接地址。 <BR>例子：<A href="http://nytimes.com/2004/12/07FEST.html">http://nytimes.com/2004/12/07FEST.html</A></P>
<P>03.●　description　　 <BR>名称：description　　 <BR>描述：item的摘要。 <BR>例子：Some of the most heated chatter at the Venice Film Festival this week was about the way that the arrival of the stars at the Palazzo del Cinema was being staged. </P>
<P>04.●　author<BR>名称：author<BR>描述：item作者的电子邮件地址。详见这里。<BR>例子：。 </P>
<P>05.●　category<BR>名称：category<BR>描述：包含item在一个或多个分类中。详见这里。 <BR>例子：。 </P>
<P>06.●　comments<BR>名称：comments<BR>描述：与item相关的评论的URL链接地址。详见 这里。 <BR>例子：。 </P>
<P>07.●　enclosure<BR>名称：enclosure<BR>描述：item附加的媒体对象。详见这里。<BR>例子：。 </P>
<P>08.●　guid<BR>名称：guid<BR>描述：可以唯一确定item身份的字符串。详见 这里。<BR>例子：。 </P>
<P>09.●　pubDate<BR>名称：pubDate<BR>描述：item发布的时间。详见 这里。<BR>例子：。 </P>
<P>10.●　source<BR>名称：source<BR>描述：rss频道来源。详见 这里。<BR>例子：。 </P>
<P>&lt;item&gt;的子元素&lt;source&gt;</P>
<P>&lt;source&gt;是&lt;item&gt;的一个可选子元素。</P>
<P>它的值是item所属rss频道的名称，从title衍生而来。它有一个必须包含的属性url, 该属性链接到XML序列化源。</P>
<P>&lt;source url="<A href="http://www.tomalak.org/links2.xml&quot;>Tomalak's">http://www.tomalak.org/links2.xml"&gt;Tomalak's</A> Realm&lt;/source&gt;</P>
<P>该元素的作用是提高链接的声望，从而进一步推广新闻项目的源头。它可以用在聚合器的Post命令中。当从聚合器中通过一个webblog编辑工具提交一个item时，&lt;source&gt;应该能够被自动生成。</P>
<P>&lt;item&gt;的子元素&lt;enclosure&gt;</P>
<P>&lt;enclosure&gt;是&lt;item&gt;的一个可选子元素。</P>
<P>它有三个必须的属性。url属性表明enclosure的位置，length属性表明它的字节大小，而type属性则指出它的标准MIME类型。</P>
<P>这里的url必须为一个http url。 </P>
<P>&lt;enclosure url="<A href="http://www.scripting.com/mp3s/weatherReportSuite.mp3">http://www.scripting.com/mp3s/weatherReportSuite.mp3</A>" length="12216320" type="audio/mpeg" /&gt;</P>
<P>它的 use-case 说明请参见这里。</P>
<P>&lt;item&gt;的子元素&lt;category&gt;</P>
<P>&lt;category&gt;是&lt;item&gt;的一个可选子元素。</P>
<P>它有一个可选属性domain，该属性是一个用来定义分类法的字符串。 </P>
<P>该节点的值是一个斜杠分割的字符串，它用来表明在指定的分类法中的层次位置。处理器可以为分类的识别建立协定。以下是两个例子： </P>
<P>&lt;category&gt;Grateful Dead&lt;/category&gt;</P>
<P>&lt;category domain="<A href='http://www.fool.com/cusips">MSFT</category'>http://www.fool.com/cusips"&gt;MSFT&lt;/category</A>&gt;</P>
<P>你可以根据需要为不同的域包含很多&lt;category&gt;元素，并且可以在相同域的不同部分拥有一个交叉引用的item。 </P>
<P>&lt;item&gt;的子元素&lt;pubDate&gt;</P>
<P>&lt;pubDate&gt; 是&lt;item&gt;的一个可选子元素。</P>
<P>它的值是一个 日期, 表明项目发布的时间。如果它是一个将来的日期，则聚合器在日期到达之前可以选择不显示该项目。 </P>
<P>&lt;pubDate&gt;Sun, 19 May 2002 15:21:36 GMT&lt;/pubDate&gt;</P>
<P>&lt;item&gt;的子元素&lt;guid&gt; </P>
<P>&lt;guid&gt;是&lt;item&gt;的一个可选子元素。</P>
<P>guid 是 globally unique identifier的缩写。它是一个可以唯一识别这个&lt;item&gt;的字符串。在发布之后，聚合器可以选择使用该字符串判断这个&lt;item&gt;是否是新的。 </P>
<P>&lt;guid&gt;http://some.server.com/weblogItem3207&lt;/guid&gt;</P>
<P>guid没有特定的语法规则。聚合器必须将它们当作一个字符串来处理。生成具有唯一性的字符串guid取决于种子的源头。 </P>
<P>如果guid元素有isPermaLink属性，并且值为真，解释器就会认为它是item的permalink。permalink是一个可在web浏览器中打开的url链接，它指向&lt;item&gt;节点所描述的完整item。 例如：</P>
<P>&lt;guid isPermaLink="true"&gt;http://inessential.com/2002/09/01.php#a2&lt;/guid&gt; </P>
<P>isPermaLink是可选属性，默认值为真。如果值为假，guid将不会被认为是一个url或指向任何对象的url。 </P>
<P>&lt;item&gt;的子元素&lt;comments&gt;</P>
<P>&lt;comments&gt;是&lt;item&gt;的一个可选子元素。</P>
<P>如果出现，它指向与item相关的评论的url。</P>
<P>&lt;comments&gt;http://ekzemplo.com/entry/4403/comments&lt;/comments&gt;</P>
<P>更多信息，请参阅 这里。</P>
<P>&lt;item&gt;的子元素&lt;author&gt; </P>
<P>&lt;author&gt;是&lt;item&gt;的一个可选子元素。</P>
<P>它是item作者的电子邮件地址l。对于通过rss传播的报纸和杂志，作者可能是写该item所描述的文章的人。对于聚集型webblogs，作者可能不是责任编辑或站长。对于个人维护的webblog，忽略&lt;author&gt;节点是有意义的。</P>
<P>&lt;author&gt;lawyer@boyer.net (Lawyer Boyer)&lt;/author&gt;</P>
<P>注释</P>
<P>RSS限制&lt;link&gt; 和 &lt;url&gt;元素的数据首字母为非空格字符。这些元素的数据必须以IANA-registered URI方案规定的格式开始，如http://, https://, <A href="news://">news://</A>, mailto:和 ftp://等。在RSS2.0规范之前，RSS规范只允许http:// 和 ftp://，然而在实践中，其他的URI方案被内容开发者广泛使用，并被聚合器所支持。聚合器也许对它们支持的URI方案有一些限制，而内容开发者不应该假定所有的聚合器都支持所有的URI方案。</P>
<P>在 RSS 0.91规范中，各种元素都被限制为500或100个字符。在一个符合0.91规范的频道中，不能超过15个 &lt;item&gt; 元素。在RSS 0.92和以后的规范中，不再有这些字符长度或者XML级别的限制。处理器也许强加一些它们自己的限制，产生者也许有自己的一些参数选择，它们可以规定在一个频道中，不超过一定数目的&lt;item&gt;元素，或者字符串都限制在一定的长度。 </P>
<P>如上所述，在 RSS 2.0规范中，对于一个目录系统，当链接一个频道到它的标识中时，使用基于频道级别的分类特征。 例如，如果链接一个频道到它的Syndic8 标识，则将包括一个分类元素作为频道的子元素，它有域“Syndic8”属性，同时在Syndic8 数据库中为你的频道确定这个标识。正确的分类元素脚本应该是 &lt;category domain="Syndic8"&gt;1765&lt;/category&gt;。</P>
<P>一个经常被问到的问题是关于&lt;guid&gt; 如何和 &lt;link&gt;进行区别。它们指的是相同的事情吗？在一些内容系统中是，但在别的内容系统中可能不是。在一些系统中，&lt;link&gt;是一个网络日志项的永久链接。然后在别的系统中，每一个&lt;item&gt;都是一个较长文章的摘要，&lt;link&gt;指向这篇文章，而&lt;guid&gt;则是这个网络日志入口的永久链接。在所有的情况下，建议提供&lt;guid&gt;,如果可能的话，并使它成为一个永久链接。这使聚合着在内容发生变化时，也不会出现重复项目成为可能。</P>
<P>如果你对RSS 2.0规范的格式有任何问题，请向由Sjoerd Visscher维护的电子邮件列表RSS2-Support发送邮件。这个邮件列表不是一个技术辩论的列表，而是一个针对作者和开发人员在创建和使用RSS 2.0格式的内容时提供技术支持的列表。</P>
<P>RSS的扩展</P>
<P>RSS起源于1999年，目标是成为一个简单、易于理解的数据格式。在它逐渐成为一种流行格式之后，开发者想在一个名字空间中使用模块对它进行扩展，正像W3C定义的那样。 <BR>RSS遵循简单的规则，增加了它的能力。一个RSS feed 可以包含不是在本页中描述的内容，而只是在一个名字空间中定义的那些元素。</P>
<P><BR>本文档中定义的元素不是一个名字空间本省的元素，因此， RSS2.0从某种意义上来讲，和原来的版本是兼容的，即一个 0.91 或者 0.92 版本的文件也是一个有效的 2.0 版本文件。如果RSS2.0的元素是在一个名字空间中，那么这种约束将被打破，即 一个0.9x 版本的文件不可能是一个有效的2.0 版本的文件。</P>
<P>发展方向 </P>
<P>RSS决不是一个完美的格式，但是它现在已经非常流行，并得到广泛的支持。要成为一个固定的规范，RSS需要很长的一段时间。这项工作的目的是帮助RSS成为一个固定的事情，同时促进和培育围绕它进行的开发的市场的增长，并为新的聚合格式铺平道路。因此，为了实用的目的，RSS规范将被冻结在2.0.2版本。我们可以预期的可能的2.0.2 或者 2.0.3等版本，都只是出于澄清规范的目的，而不是在格式上增加新的特征。后续的工作应该集中在模块化、名字空间的使用和在完全新的聚合格式中用新的名字等方面。</P>
<P>许可协议和作者</P>
<P>RSS 2.0 是在遵循i the Attribution/Share Alike Creative Commons 许可协议 的基础上由 the Berkman Center for Internet &amp; Society at Harvard Law School 提供。本文档的作者是 Dave Winer，UserLand software的创始人，也是 Berkman Center 的员工<A></A></P>]]></description>
</item><item>
<title><![CDATA[利用commons-fileupload组件上传文件至服务器和数据库(ZT)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=6595</link>
<author>gecko</author>
<pubDate>2005/6/16 15:59:59</pubDate>
<description><![CDATA[
<P>common-fileupload是jakarta项目组开发的一个功能很强大的上传文件组件</P>
<P>下面先介绍上传文件到服务器（多文件上传）：</P>
<P>import javax.servlet.*;<BR>import javax.servlet.http.*;<BR>import java.io.*;<BR>import java.util.*;<BR>import java.util.regex.*;<BR>import org.apache.commons.fileupload.*;<BR></P>
<P>public class upload extends HttpServlet {<BR>&nbsp; private static final String CONTENT_TYPE = "text/html; charset=GB2312";<BR>&nbsp; //Process the HTTP Post request<BR>&nbsp; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {<BR>&nbsp;&nbsp;&nbsp; response.setContentType(CONTENT_TYPE);<BR>&nbsp;&nbsp;&nbsp; PrintWriter out=response.getWriter();<BR>&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp; DiskFileUpload fu = new DiskFileUpload();<BR>&nbsp;// 设置允许用户上传文件大小,单位:字节，这里设为2m<BR>&nbsp;fu.setSizeMax(2*1024*1024);<BR>&nbsp;// 设置最多只允许在内存中存储的数据,单位:字节<BR>&nbsp;fu.setSizeThreshold(4096);<BR>&nbsp;// 设置一旦文件大小超过getSizeThreshold()的值时数据存放在硬盘的目录<BR>&nbsp;fu.setRepositoryPath("c:\\windows\\temp");<BR>&nbsp;//开始读取上传信息<BR>&nbsp;List fileItems = fu.parseRequest(request);<BR>&nbsp;// 依次处理每个上传的文件<BR>&nbsp;&nbsp; Iterator iter = fileItems.iterator();</P>
<P>//正则匹配，过滤路径取文件名<BR>&nbsp;&nbsp; String regExp=".+\\\\(.+)$";</P>
<P>//过滤掉的文件类型<BR>String[] errorType={".exe",".com",".cgi",".asp"};<BR>&nbsp;&nbsp; Pattern p = Pattern.compile(regExp);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (iter.hasNext()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FileItem item = (FileItem)iter.next();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //忽略其他不是文件域的所有表单信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!item.isFormField()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String name = item.getName();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long size = item.getSize();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if((name==null||name.equals("")) &amp;&amp; size==0)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Matcher m = p.matcher(name);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean result = m.find();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (result){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int temp=0;temp<ERRORTYPE.LENGTH;TEMP++){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (m.group(1).endsWith(errorType[temp])){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IOException(name+": wrong type");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{</P>
<P>//保存上传的文件到指定的目录</P>
<P>//在下文中上传文件至数据库时，将对这里改写<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; item.write(new File("d:\\" + m.group(1)));</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.print(name+"&nbsp;&nbsp;"+size+"<BR>");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(Exception e){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println(e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new IOException("fail to upload");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; }<BR>}<BR>&nbsp;catch (IOException e){<BR>&nbsp;&nbsp; out.println(e);<BR>&nbsp;}<BR>&nbsp;catch (FileUploadException e){<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println(e);<BR>&nbsp;}<BR>&nbsp;<BR>&nbsp; }<BR>}</P>
<P>现在介绍上传文件到服务器，下面只写出相关代码：</P>
<P>以sql2000为例，表结构如下：</P>
<P>字段名：name&nbsp;&nbsp;&nbsp; filecode</P>
<P>类型： varchar&nbsp;&nbsp;&nbsp;&nbsp; image</P>
<P>数据库插入代码为：PreparedStatement pstmt=conn.prepareStatement("insert into test values(?,?)");</P>
<P>代码如下：</P>
<P>。。。。。。</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try{<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //item.write(new File("d:\\" + m.group(1)));//这段代码如果不去掉，将一同写入到服务器中</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int byteread=0;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream inStream=item.getInputStream();&nbsp; //读取输入流，也就是上传的文件内容<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pstmt.setString(1,m.group(1));<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pstmt.setBinaryStream(2,inStream,(int)size);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pstmt.executeUpdate();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inStream.close();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out.println(name+"&nbsp;&nbsp;"+size+"<BR>");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>。。。。。。</P>
<P>这样就实现了上传文件至数据库</P>
<P><BR>感谢引自：<A href="http://java.mblogger.cn/zhangpoo/archive/06012005.aspx">http://java.mblogger.cn/zhangpoo/archive/06012005.aspx</A></P>
<P>&nbsp;</P>]]></description>
</item><item>
<title><![CDATA[commons-fileupload用户指南]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=6430</link>
<author>gecko</author>
<pubDate>2005/6/7 14:56:32</pubDate>
<description><![CDATA[<P><FONT size=2>原文链接：</FONT><A href="http://iiu.cn/more.asp?name=dingl&amp;id=4906"><FONT size=2>http://iiu.cn/more.asp?name=dingl&amp;id=4906</FONT></A></P>
<DIV id=main>
<DIV class=post>
<DIV class=postText>
<P><FONT size=2><SPAN style="TEXT-DECORATION: underline">使用fileupload</SPAN><BR><BR>根据你的应用需求，fileupload可以有许多不同的使用方式。在最简单的情况下，你可以调用一个简单的方法来解析servlet请求，然后在他们提交到你的应用时处理表单列表。在其它规模的终端上，你也可能决定将fileupload进行自定义，以完全控制个别表单项存储的方法。比如，你或许会将内容流化来保存到数据中。<BR>在这里。我们将要描述fileupload的基本使用方法，然后解释一些更简单的，以及最常用的使用模式。fileupload的个性化在这里得到了描述。<BR><BR><SPAN style="TEXT-DECORATION: underline">它怎么工作</SPAN><BR><BR>一个文件上传请求由有序表单项的列表组成，这些表单是根据RFC1867来编码的，是在html中基于表单的文件上传。fileupload能解析这样一个请求然后向你的应用提供一个单独的上传表单项的列表。每一个这样的表单项实现了FileItem接口，而不需要考虑它潜在的实现方式。每个文件的表单项拥有一系列可能对你的应用有用的属性，比如，每个项目都有一个名字和文件类型，你就可以提供一个InputStream来取它的数据。从另一方面说，你可能需要对这些选项进行不同的处理，这个可以根据对这个选项是不是一个规则的表单项来判断，即可以根据这个数据是否来源于普通的文本框或者一个简单的html表单域，还是一个能被上传的文件。FileItem接口提供了多种方法来判断它是否是一个可上传的文件，然后你就可以用最合适的方式来处理这些数据了。FileUpload使用FileItemFactory来创建新的文件项目。这正是给FileUpload带来灵活性的原因。这个工厂最终控制每个项目的创建。默认的工厂在内存或者磁盘上保存了项目的数据，这个可以根据项目的大小来定（例如，字节数据）。当然，这个动作可以通过自定义来满足你应用的需要。<BR><BR></FONT><FONT size=2><SPAN style="TEXT-DECORATION: underline">解析请求<BR><BR></SPAN>在你对要上传的选项处理之前，很显然的你得先解析这些请求本身。很直接的就是要确保这个请求是不是一个要上传的文件，然而FileUpload使这一点简单化了，你只需提供一个静态的方法来做到这一点。<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>//检查是否是一个文件上传请求<BR>boolean isMultipart = FileUpload.isMultipartContent(request);<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>现在我们就可以准备解析这个请求到一个备选的选项了。解析的结果是一个文件选项的List,每个这样的选项都实现了FileItem接口，处理这些选项将在下面得到讨论。<BR><BR><SPAN style="TEXT-DECORATION: underline">最简单的情况</SPAN><BR><BR>最简单的使用场景可以参照下面：<BR></FONT></P>
<UL>
<LI><FONT size=2>被上传得选项必须以适度的大小驻留在内存中； </FONT>
<LI><FONT size=2>比较大的文件上传选项必须写入到磁盘的临时文件中去； </FONT>
<LI><FONT size=2>大文件上传请求必须不被允许； </FONT>
<LI><FONT size=2>默认的驻留内存的选项的最大大小，最大允许的上传文件请求，和临时文件的存储地方是可以接受的；</FONT></LI></UL>
<P><FONT size=2>在这种情景下处理这样一个请求并不是很简单的：<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>//创建一个新的文件上传句柄<BR>DiskFileUpload upload = new DiskFileUpload();<BR>//解析请求<BR>List /* FileItem */ items = upload.parseRequest(request);<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>这就是所有我们需要做的，真的！<BR>解析的结果是一个文件项目的List,每一个都实现了FileItem接口。处理这些项目将在下面讨论。<BR><BR></FONT><FONT size=2><SPAN style="TEXT-DECORATION: underline">练习更多的控制<BR><BR></SPAN>如果你的使用情景非常接近最简单的使用方式，在上文中可以看到，但是你需要更多的控制临界的大小和临时文件的驻留地址，你可以使用DiskFileUpload类的方法来自定义这些动作，就像这样：<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>//创建一个新的文件上传句柄<BR>DiskFileUpload upload = new DiskFileUpload();<BR>//设置上传参数<BR>upload.setSizeThrehold(最大内存大小);<BR>upload.setSizeMax(最大请求大小);<BR>upload.setRepositoryPath(临时目录);<BR>//解析请求<BR>List /* FileItem */ items = upload.parseRequest(request);<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>当然，每个配置方法都是独立于其它的，但是如果你想一次就配置它们，你可以使用可选的parseRequest()方法，像这样：<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>// 建立一个新的文件上传句柄<BR>DiskFileUpload upload = new DiskFileUpload();<BR>// 解析请求<BR>List /* FileItem */ items = upload.parseRequest(request,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 内存大小, 允许上传的最大文件, 临时目录);<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>如果你想更多地控制请求的解析，比如把上传选项存储到其它地方，例如，存到数据库中-你可以参照自定义FileUpload。<BR><BR><SPAN style="TEXT-DECORATION: underline">处理上传选项</SPAN><BR><BR>一旦解析过程完毕，你就可以获得一个文件选项的List，以便进一步处理。在大多数情况下，你将会根据规则的表单域来不同地处理文件的上传。所以你可能以这样的方式来处理：<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>// 处理上传的选项<BR>Iterator iter = items.iterator();<BR>while (iter.hasNext()) {<BR>&nbsp;&nbsp;&nbsp; FileItem item = (FileItem) iter.next();<BR><BR>&nbsp;&nbsp;&nbsp; if (item.isFormField()) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processFormField(item);<BR>&nbsp;&nbsp;&nbsp; } else {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; processUploadedFile(item);<BR>&nbsp;&nbsp;&nbsp; }<BR>}<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>对于一个规则的表单域来说，你对它感兴趣的可能就只有它的名字以及它的字符串值。你也会想到，处理它们是简单的:<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>//处理一个规则表单域<BR>if (item.isFormField()) {<BR>&nbsp;&nbsp;&nbsp; String name = item.getFieldName();<BR>&nbsp;&nbsp;&nbsp; String value = item.getString();<BR>&nbsp;&nbsp;&nbsp; ...<BR>}<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>而对于一个文件的上传，在你处理它的内容之前，可以有好多令你想知道的不同的东西，这里有一个采用了一些你可能感兴趣的方法的例子<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>// 处理一个文件上传<BR>if (!item.isFormField()) {<BR>&nbsp;&nbsp;&nbsp; String fieldName = item.getFieldName();<BR>&nbsp;&nbsp;&nbsp; String fileName = item.getName();<BR>&nbsp;&nbsp;&nbsp; String contentType = item.getContentType();<BR>&nbsp;&nbsp;&nbsp; boolean isInMemory = item.isInMemory();<BR>&nbsp;&nbsp;&nbsp; long sizeInBytes = item.getSize();<BR>&nbsp;&nbsp;&nbsp; ...<BR>}<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>对于这些上传的文件，你一般不想通过内存来存取它们，除非它们很小，或者你没有其它好的方法，更进一步，你想将内容当作文件流来处理，或者将整个文件写到最终的地址。FileUpload提供了简单的方法来完成这些 操作。<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>// 处理一个文件上传的情况<BR>if (writeToFile) {<BR>&nbsp;&nbsp;&nbsp; File uploadedFile = new File(...);<BR>&nbsp;&nbsp;&nbsp; item.write(uploadedFile);<BR>} else {<BR>&nbsp;&nbsp;&nbsp; InputStream uploadedStream = item.getInputStream();<BR>&nbsp;&nbsp;&nbsp; ...<BR>&nbsp;&nbsp;&nbsp; uploadedStream.close();<BR>}<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><FONT size=2>注意到，在默认的FileUpload的实现中，write()方法将尝试把文件改名以将它保存到特定的地点，如果数据已经在临时文件中了，如果重命名失败，实际的复制文件就完成了（？），在其它原因看来，或者数据已经在内存中了。如果你的确需要在内存中取上传的数据，你只需简单的调用get()方法来把它当作一个字符数组来获得。<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><BR><FONT size=2>// 在内存中处理一个上传的文件<BR>byte[] data = item.get();<BR>...<BR></FONT></P><FONT size=2>
<HR style="WIDTH: 100%; HEIGHT: 2px">
</FONT>
<P><BR><FONT size=2><SPAN style="TEXT-DECORATION: underline">和杀毒软件的相互作用</SPAN><BR><BR>当web容器在运行时，而杀毒软件又同时运行在同样的系统上，这种情况下在应用中使用FileUpload容易导致一些很难预料的事情.这部分将描述一些你可能要遇到的情况，我们会提供一些方法来处理它们。默认的FileUpload实现将会使超过它在内存中大小的上传的选项写入到磁盘。而当这样的文件关闭后，任何系统中的杀毒软件都会被唤醒,然后去检查它，然后会潜在地隔离这个文件--就是说，将它移动到一个不产生问题的特定地方。这样一来，对开发者来说当然是一个意外，因为刚刚上传的文件将不能被处理了。从另一方面来说，小于设定的内存大小的那些上传的文件将被保持在内存中，这样一来，将不会被杀毒软件所检测到，这样就有可能使病毒以某种方式驻留在了系统中了（虽然如果一旦它被写入到磁盘，杀毒软件就会定位并检测到它）。一个通用的解决方法是在系统中专门设置一个目录来存放这些上传的文件，然后配置杀毒软件忽略这个目录。这样将确保上传的文件在系统中不被隔离，但是这样就把扫描病毒的责任交给了应用程序的开发者了。扫描这些上传的文件的任务可以在外部的处理中实现。这样可以将干净的文件移动到一个“改进”过的地方，或者也可以把杀毒集成到应用中去。至于怎么将外部处理或集成病毒扫描到一个<BR>应用，这个已经超出了本文档的讨论范围。<BR><BR></FONT><FONT size=2><SPAN style="TEXT-DECORATION: underline">下一步是什么<BR><BR></SPAN>希望这个页面能提供给你一个好的意见，让你在你自己的应用中能使用FileUpload。更多关于这里介绍的方法，以及其它可用的方法，你可以参照api文档。这里介绍的用法已经可以满足大多数的文件上传的需要了，当然，如果你还有更多的复杂的需求，使用它的灵活的自定义配置的能力，FileUpload一定可以能够帮助你。<BR><BR>Author: Bruce chen<BR>email:love.oss@gmail.com<BR>msn:cf_asp_master@yahoo.com.cn</FONT></P></DIV></DIV></DIV>]]></description>
</item><item>
<title><![CDATA[如何建立DB2的工具数据库TOOLSDB]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=6183</link>
<author>gecko</author>
<pubDate>2005/5/30 9:05:48</pubDate>
<description><![CDATA[<P>安裝 DB2 时，工具数据库可能已经被建立好了，但如果它不可用，可以用 DB2 命令或工具功能表建立它</P>
<P>1、从命令行建立工具数据库，打开DB2的命令窗口输入：</P>
<P>db2 create tools catalog cc create new database toolsdb</P>
<P>2、使用工具建立工具数据库，从控制中心选择Tools=&gt;Tools Settings=&gt;Scheduler Settings</P>
<P><IMG style="BORDER-LEFT-COLOR: #000000; BORDER-BOTTOM-COLOR: #000000; BORDER-TOP-COLOR: #000000; BORDER-RIGHT-COLOR: #000000" src="uploadfile/200553091622685.GIF" border=0></P>
<P>参考文件：</P>
<P>DB2信息中心</P>
<P><A href="http://publib.boulder.ibm.com/infocenter/db2help/index.jsp?topic=/com.ibm.db2.udb.doc/core/r0008881.htm">http://publib.boulder.ibm.com/infocenter/db2help/index.jsp?topic=/com.ibm.db2.udb.doc/core/r0008881.htm</A></P>]]></description>
</item><item>
<title><![CDATA[Microsoft Biztalk 2004 vs IBM WebSphere Business Integration Server Foundation 5.1]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=5411</link>
<author>gecko</author>
<pubDate>2005/4/30 9:55:16</pubDate>
<description><![CDATA[
<P><FONT face=Georgia>最近有幸深入了解了一些 Biztalk 2004&nbsp;和 WebSphere Integration Server Foundation 5.1&nbsp;的内容，作为两大软件厂商的两大商业流程集成平台，不仿做一下对比。</FONT></P>
<P><FONT face=Georgia>Biztalk 2004 以下简称为 Biztalk，WebSphere Business Integration Server Foundation 5.1 简称 WBI-SF。</FONT></P>
<P><STRONG><FONT face=Georgia>1、对于关键标准的支持</FONT></STRONG></P>
<P><FONT face=Georgia>由于&nbsp;WebServices 技术成为将来 EAI、B2Bi 方案使用的一种主流技术，两个平台在此方面的支持均比较完善，可以在流程中很方便地调用 Web Service。</FONT></P>
<P><FONT face=Georgia>但对于 Web Service 的一个重要协议：BPEL4WS --- 商业流程执行语言，两者支持的力度则不同。WebSphere 的流程编排（Choreograph）是以 BPEL4WS 为基础，增加了一定扩展。而 Biztalk 则更象是延用了 XLANG 的流程编排（Orchestration），而做了一些扩展以便能够支持 BPEL4WS。</FONT></P>
<P><FONT face=Georgia>这个也可能与产品的发布日期有关，Biztalk 2004 在研发中的时候，BPEL 1.1 的标准还没未成形，而 WBI-SF 则是在 BPEL 1.1 成为正式标准之后才发布的。</FONT></P>
<P><STRONG><FONT face=Georgia>2、应用接口与适配器（Adapter）</FONT></STRONG></P>
<P><FONT face=Georgia>Biztalk 似乎在这个方面要具有优势，这可能归功于 Biztalk 产品历史稍长，很早就有 Biztalk Framework、Adapter Framework，加上近几年的不断发展，已经可以支持所有主流数据库、基础架构和产品（如 CORBA、EJB、MQ、EDI）、垂直行业标准（HIPAA,RosettaNet、FIX, SWIFT (Financial)），应用程序（Sibel CRM、SAP、J.D.Edwards、PeopleSoft），数量达到数百个，而 WBI-SF 则除了与自己的产品/技术（如CICS、Lotus等）具有接口外，其它的 Adapter 并不多。</FONT></P>
<P><STRONG><FONT face=Georgia>3、开发难易程度</FONT></STRONG></P>
<P><FONT face=Georgia>Biztalk 的开发并不是很容易的事情，需要了解端口、管道等诸多易另人混淆的东西，而且基本上是基于 XML 消息的处理，所以在流程的各个部分要经常做消息类型定义，消息转换等。而 WBI-SF 中则更多是使用容易理解的变量的概念，类似于函数中的参数。两者各有优缺点，基于变量（参数）易理解、容易开发，而基于消息较适合于完整的商业文档转换、交换，并且能证可以保证其中数据的安全性。</FONT></P>
<P><FONT face=Georgia>在流程活动基本元素（如循环、分支、顺序执行等）方面，Biztalk 支持较为完善，而 WBI-SF 则只是在 BPEL4WS 的基本元素基础上加入了有限扩展，不够丰富。</FONT></P>
<P><FONT face=Georgia>在文档转换与映射（Maping）方面，Biztalk 提供了完备的设计界面和转换函数，而 WBI-SF 只是提供了基本的映射功能。</FONT></P>
<P><STRONG><FONT face=Georgia>4、开发工具支持</FONT></STRONG></P>
<P><FONT face=Georgia>Microsoft 使用扩展后的 Visual Stuidio .NET 2003 做为 Biztalk 应用的开发工具，IBM 则紧紧围绕 Ecipse ，提供了一个类似于 WSAD 的&nbsp;WebSphere Application Developer for Integration Edition（简称 WSAD-IE）来对 WBI-SF 应用开发提供支持。</FONT></P>
<P><FONT face=Georgia>就个人体会来说，在 WSAD-IE 中开发应用要比 VS.NET 中方便一些，目前在 VS.NET 中开发 Biztalk 应用还是很麻烦，需要安装 Biztalk 开发版，开发工具中不支持调试，只能通过另外的一个工具来跟踪调试。</FONT></P>
<P><FONT face=Georgia>在 WSAD-IE 中自带有一个 WBI-SF 简化版，所以不用另外安装 WBI-SF ，而且可以直接在开发工具中进行流程调试，如设置断点、单步执行等。</FONT></P>
<P><STRONG><FONT face=Georgia>5、性能与效率</FONT></STRONG></P>
<P><FONT face=Georgia>从理论上来说，Biztalk 的所有消息都要存储到消息数据库后再进行进一步处理，而 WBI-SF 则将商业流程分为两类：没有人工参与的流程的短流程以及有人工参与的长流程（类似于传统意义上的工作流），对于前者只在内存中进行处理，对于后者，则要存储到数据库中后再进行处理。</FONT></P>
<P><FONT face=Georgia>很难说两者那个的效率更好，Biztalk 都存储在数据库中，异步处理，很少会发生资源争用、死锁的情况，而且可靠性很高，而如果在内存中处理，并发量较小的时候可能会较快，但并发量大的时候，很可能会产生资源争用，进而死锁降低系统效率。</FONT></P>
<P><FONT face=Georgia>就开发工具来说，WSAD-IE 继承了 WSAD 奇慢的速度，在 1G 的 Vmware Virtual Machine 中花了 1 分钟时间才启动完成，编译部署时间也很长，在这方面，其与 Biztalk 和 VS.NET 的速度差异不是一两倍，简直是糟蹋了 Eclipse。</FONT></P>
<P><STRONG><FONT face=Georgia>6、人力工作流支持</FONT></STRONG></P>
<P><FONT face=Georgia>人力工作流（Human Workflow）主要指商业流程中需要人力参与，如审批、复核等。在&nbsp;WBI-SF 中对人力工作流有一定的支持，每个活动结点可以设置其类型为 staff activities ，然后可以设置操作用户、权限等，且有内建的、简单的 Web 操作界面来完成在流程上定义的操作。</FONT></P>
<P><FONT face=Georgia>IBM 对于人力工作流更完整的支持体现在&nbsp;WebSphere Interchange Server 4 （购自 CrossWorlds ）中，估计这个东西以后会和 WBI-SF 进行整合。</FONT></P>
<P><FONT face=Georgia>Biztalk 本身的工作流特性较弱，只是提供了一些工作流基础（基础服务和接口等），具体的实现需要较多的二次开发，结合 SharePoint Services 和 InfoPath 等完成。</FONT></P>
<P><STRONG><FONT face=Georgia>7、建模工具</FONT></STRONG></P>
<P><FONT face=Georgia>Microsoft 提供了一个基于 Visio 的插件，可以由业务人员绘制商业处理流程图，并可以导入到 VS.NET 中直接作为 Biztalk&nbsp;Orchestration 基本框架来使用。</FONT></P>
<P><FONT face=Georgia>IBM 有一个名为 WebSphere Business Integration Modeler 的单独的建模工具，不知道是否是提供 WBI-SF 来使用的，此建模工具也构建在 Eclipse 的基础上。</FONT></P>
<P><STRONG><FONT face=Georgia>8、其它相关信息</FONT></STRONG></P>
<P><FONT face=Georgia>虽然大家说 Biztalk 与 Infopath 的关系有如 Outlook 和 Exchange ，但在实际应用中，Infopath 要想利用 Biztalk 的功能，远不如 Outlook 配置一个 Profile 就可以使用 MailBox 和 Public Folder 那样简单。</FONT></P>
<P><FONT face=Georgia>Biztalk 仍需要在 BPEL4WS、Human Workflow、开发支持等方面继续进步。</FONT></P>
<P><FONT face=Georgia>IBM 在整合方面的工具很多，如 WebSphere Business Integration（不知道其与 WBI-SF 的关系如何，个人以为 WBI-SF 是 WBI 的升级版本）、WBI MessageBroker、WBI Modeler、WBI Adapter Framework、WebSphere Interchange Server、WebSphere MQ Workflow、MQ Integrator&nbsp;等，说实话，这么多东西，实在很让人 Confuse ，即然天天对外宣称口号：整合应用（ IBM 开发大会口号），何不把自己的整合产品先好好整合一下？或者至少给用户一个明确的产品发展计划以便于产品或技术选型/决策呀。</FONT></P>]]></description>
</item><item>
<title><![CDATA[CsvJdbc和XLSJDBC]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=4664</link>
<author>gecko</author>
<pubDate>2005/4/7 9:08:37</pubDate>
<description><![CDATA[<P><A>　<!--StartFragment --> CSV(Comma Separated Value)，Foxmail 和 Outlook 导出的地址本都可以是 csv 文件。</A><A href="http://csvjdbc.sourceforge.net/" target=_blank><FONT color=blue>CsvJdbc</FONT></A><A> 提供了Java 访问 csv 文件的的 JDBC 驱动，它其实是把一个 csv 文件当做一个数据库表来操作，提供简单的查询。<BR><BR>另外，在 CsvJDBC 的基础上衍生了另一个开源项目，</A><A href="http://xlsjdbc.sourceforge.net/" target=_blank><FONT color=blue>XLSJDBC</FONT></A><A>，看名字就知道，XLSJDBC 是访问 xls 文件的 JDBC 驱动。<BR><BR>CsvJdbc 和 XLSJDBC 都只提供只读的方式，意味着只能SELECT，不能 UPDATE 和 DELETE。 </A></P>
<P><A href="http://sourceforge.net/projects/xlsjdbc/">http://sourceforge.net/projects/xlsjdbc/</A></P>
<P><A href="http://sourceforge.net/projects/csvjdbc">http://sourceforge.net/projects/csvjdbc</A></P>]]></description>
</item><item>
<title><![CDATA["微软打折销售WindowsXP－里面有陷阱"]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=3332</link>
<author>gecko</author>
<pubDate>2005/3/5 14:18:31</pubDate>
<description><![CDATA[<P>　&gt; 微软在华以打折销售WinXP为幌子，但是购买时要先介绍用盗版情况，用于收集证据状<BR>&gt; 告中国盗版严重<BR>&gt; <BR>&gt; 本报讯 (记者 张见悦) 昨天，连邦、微软"金鸡报晓大型正版推进计划"正式启动，国<BR>&gt; 内用户第一次有机会以接近半价的优惠价格购买微软的操作系统Windows XP。<BR>&gt; <BR>&gt; 昨天下午，连邦对外公布了首批118家连邦Winxp打折专卖店名单，按照微软在中国市<BR>&gt; 场破天荒的优惠政策，原本1498元的家庭版Winxp打折价格为786元，原本价格为1998<BR>&gt; 元的专业版Winxp打折价格为1270元，价格下调了将近一半。不过，按照微软的要求，<BR>&gt; 用户必须在2005年3月31日之前提交一份"获得未经授权Windows软件情况说明"给微软<BR>&gt; 公司，以换取微软公司的电子优惠券，微软方面同时将发出的优惠券名单发送给连邦<BR>&gt; 公司，用户才能凭单购买廉价产品。<BR>&gt; <BR>&gt; ＝＝＝＝＝＝＝＝＝＝＝＝<BR>&gt; 警告：<BR>&gt; <BR>&gt; 无论多便宜都不能买！ 这是陷阱！<BR>&gt; 你一旦提供了"获得未经授权Windows软件情况说明"，就导致两个后果：<BR>&gt; <BR>&gt; 1. 书面承认你使用盗版，微软可以要求你就以前使用盗版的行为进行赔偿；<BR>&gt; <BR>&gt; 2. 美国现在正在收集中国保护知识产权不力的证据。微软的所谓优惠，也正是配合美<BR>&gt; 国政府收集这方面的证据。你提交的说明等于是中国人自己写的"认罪悔过书"。<BR>&gt; <BR>&gt; 强烈谴责微软！<BR>&gt; 强烈谴责联邦软件！强烈谴责那些为了小利出卖中国的人！<BR>&gt; 试想，某天美国的贸易代表拿着统计数据说，看呐，这是中国人自己承认的盗版行<BR>&gt; 为，普及率... 我们大概才会如梦初醒？<BR>&gt; <BR>&gt; 如果你是中国人的话，请看到此文后尽可能转发、转贴，并相互转告<BR></P>]]></description>
</item><item>
<title><![CDATA[追MM与设计模式（java的32种设计模式）]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=3040</link>
<author>gecko</author>
<pubDate>2005/2/23 2:08:53</pubDate>
<description><![CDATA[
<DIV>创建型模式?<BR><BR>1、FACTORY一追MM少不了请吃饭了，麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西，虽然口味有所不同，但不管你带MM去麦当劳或肯德基，只管向服务员说“来四个鸡翅”就行了。麦当劳和肯德基就是生产鸡翅的Factory?<BR><BR>工厂模式：客户类和工厂类分开。消费者任何时候需要某种产品，只需向工厂请求即可。消费者无须修改就可以接纳新产品。缺点是当产品修改时，工厂类也要做相应的修改。如：如何创建及如何向客户端提供。?<BR><BR>2、BUILDER—MM最爱听的就是“我爱你”这句话了，见到不同地方的MM,要能够用她们的方言跟她说这句话哦，我有一个多种语言翻译机，上面每种语言都有一个按键，见到MM我只要按对应的键，它就能够用相应的语言说出“我爱你”这句话了，国外的MM 也可以轻松搞掂，这就是我的“我爱你”builder。（这一定比美军在伊拉克用的翻译机好卖）?<BR><BR>建造模式：将产品的内部表象和产品的生成过程分割开来，从而使一个建造过程生成具有不同的内部表象的产品对象。建造模式使得产品内部表象可以独立的变化，客户不必知道产品内部组成的细节。建造模式可以强制实行一种分步骤进行的建造过程。?<BR><BR>3、FACTORY?METHOD—请MM去麦当劳吃汉堡，不同的MM有不同的口味，要每个都记住是一件烦人的事情，我一般采用Factory?Method模式，带着MM到服务员那儿，说“要一个汉堡”，具体要什么样的汉堡呢，让MM直接跟服务员说就行 了。?<BR><BR>工厂方法模式：核心工厂类不再负责所有产品的创建，而是将具体创建的工作交给子类去做，成为一个抽象工厂角色，仅负责给出具体工厂类必须实现的接口，而不接触哪一个产品类应当被实例化这种细节。?<BR><BR>4、PROTOTYPE—跟MM用QQ聊天，一定要说些深情的话语了，我搜集了好多肉麻的情话，需要时只要copy出来放到QQ里面就行了，这就是我的情话prototype了。（100块钱一份，你要不要）?<BR><BR>原始模型模式：通过给出一个原型对象来指明所要创建的对象的类型，然后用复制这个原型对象的方法创建出更多同类型的对象。原始模型模式允许动态的增加或减少产品类，产品类不需要非得有任何事先确定的等级结构，原始模型模式适用于任何的等级结构。缺点是每一 个类都必须配备一个克隆方法。?<BR><BR>5、SINGLETON—俺有6个漂亮的老婆，她们的老公都是我，我就是我们家里的老公Sigleton，她们只要说道“老公”，都是指的同一个人，那就是我(刚才做了个梦啦，哪有这么好的事)?<BR><BR>单例模式：单例模式确保某一个类只有一个实例，而且自行实例化并向整个系统提供这个实例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。?<BR><BR>结构型模式?<BR><BR>6、ADAPTER—在朋友聚会上碰到了一个美女Sarah，从香港来的，可我不会说粤语，她不会说普通话，只好求助于我的朋友kent了，他作为我和Sarah之间的Adapter，让我和Sarah可以相互交谈了(也不知道他会不会耍我)?<BR><BR>适配器（变压器）模式：把一个类的接口变换成客户端所期待的另一种接口，从而使原本因接口原因不匹配而无法一起工作的两个类能够一起工作。适配类可以根据参数返还一个合适的实例给客户端。?<BR><BR>7、BRIDGE—早上碰到MM，要说早上好，晚上碰到MM，要说晚上好；碰到MM穿了件新衣服，要说你的衣服好漂亮哦，碰到MM新做的发型，要说你的头发好漂亮哦。不要问我“早上碰到MM新做了个发型怎么说”这种问题，自己用BRIDGE组合一下不就行 了?<BR><BR>桥梁模式：将抽象化与实现化脱耦，使得二者可以独立的变化，也就是说将他们之间的强关联变成弱关联，也就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系，从而使两者可以独立的变化。?<BR><BR>8、COMPOSITE—Mary今天过生日。“我过生日，你要送我一件礼物。”“嗯，好吧，去商店，你自己挑。”“这件T恤挺漂亮，买，这条裙子好看，买，这个包也不错，买。”“喂，买了三件了呀，我只答应送一件礼物的哦。”“什么呀，T恤加裙子加包包 ，正好配成一套呀，小姐，麻烦你包起来。”“……”，MM都会用Composite模式了，你会了没有？?<BR><BR>合成模式：合成模式将对象组织到树结构中，可以用来描述整体与部分的关系。合成模式就是一个处理对象的树结构的模式。合成模式把部分与整体的关系用树结构表示出来。合成模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。?<BR><BR>9、DECORATOR—Mary过完轮到Sarly过生日，还是不要叫她自己挑了，不然这个月伙食费肯定玩完，拿出我去年在华山顶上照的照片，在背面写上“最好的的礼物，就是爱你的Fita”，再到街上礼品店买了个像框（卖礼品的MM也很漂亮哦），再找 隔壁搞美术设计的Mike设计了一个漂亮的盒子装起来……，我们都是Decorator，最终都在修饰我这个人呀，怎么样，看懂了吗？?<BR><BR>装饰模式：装饰模式以对客户端透明的方式扩展对象的功能，是继承关系的一个替代方案，提供比继承更多的灵活性。动态给一个对象增加功能，这些功能可以再动态的撤消。增加由一些基本功能的排列组合而产生的非常大量的功能。?<BR><BR>10、FACADE—我有一个专业的Nikon相机，我就喜欢自己手动调光圈、快门，这样照出来的照片才专业，但MM可不懂这些，教了半天也不会。幸好相机有Facade设计模式，把相机调整到自动档，只要对准目标按快门就行了，一切由相机自动调整，这样 MM也可以用这个相机给我拍张照片了。?<BR><BR>门面模式：外部与一个子系统的通信必须通过一个统一的门面对象进行。门面模式提供一个高层次的接口，使得子系统更易于使用。每一个子系统只有一个门面类，而且此门面类只有一个实例，也就是说它是一个单例模式。但整个系统可以有多个门面类。?<BR><BR>11、FLYWEIGHT—每天跟MM发短信，手指都累死了，最近买了个新手机，可以把一些常用的句子存在手机里，要用的时候，直接拿出来，在前面加上MM的名字就可以发送了，再不用一个字一个字敲了。共享的句子就是Flyweight，MM的名字就是提 取出来的外部特征，根据上下文情况使用。?<BR><BR>享元模式：FLYWEIGHT在拳击比赛中指最轻量级。享元模式以共享的方式高效的支持大量的细粒度对象。享元模式能做到共享的关键是区分内蕴状态和外蕴状态。内蕴状态存储在享元内部，不会随环境的改变而有所不同。外蕴状态是随环境的改变而改变的。外蕴状 态不能影响内蕴状态，它们是相互独立的。将可以共享的状态和不可以共享的状态从常规类中区分开来，将不可以共享的状态从类里剔除出去。客户端不可以直接创建被共享的对象，而应当使用一个工厂对象负责创建被共享的对象。享元模式大幅度的降低内存中对象的数量 。?<BR><BR>12、PROXY—跟MM在网上聊天，一开头总是“hi,你好”,“你从哪儿来呀？”“你多大了？”“身高多少呀？”这些话，真烦人，写个程序做为我的Proxy吧，凡是接收到这些话都设置好了自动的回答，接收到其他的话时再通知我回答，怎么样，酷吧。? <BR><BR>代理模式：代理模式给某一个对象提供一个代理对象，并由代理对象控制对源对象的引用。代理就是一个人或一个机构代表另一个人或者一个机构采取行动。某些情况下，客户不想或者不能够直接引用一个对象，代理对象可以在客户和目标对象直接起到中介的作用。客户端 分辨不出代理主题对象与真实主题对象。代理模式可以并不知道真正的被代理对象，而仅仅持有一个被代理对象的接口，这时候代理对象不能够创建被代理对象，被代理对象必须有系统的其他角色代为创建并传入。?<BR><BR>行为模式?<BR><BR>13、CHAIN?OF?RESPONSIBLEITY—晚上去上英语课，为了好开溜坐到了最后一排，哇，前面坐了好几个漂亮的MM哎，找张纸条，写上“Hi,可以做我的女朋友吗？如果不愿意请向前传”，纸条就一个接一个的传上去了，糟糕，传到第一排的M M把纸条传给老师了，听说是个老处女呀，快跑!?<BR><BR>责任链模式：在责任链模式中，很多对象由每一个对象对其下家的引用而接?<BR><BR>起来形成一条链。请求在这个链上传递，直到链上的某一个对象决定处理此请求。客户并不知道链上的哪一个对象最终处理这个请求，系统可以在不影响客户端的情况下动态的重新组织链和分配责任。处理者有两个选择：承担责任或者把责任推给下家。一个请求可以最终不 被任何接收端对象所接受。?<BR><BR>14、COMMAND—俺有一个MM家里管得特别严，没法见面，只好借助于她弟弟在我们俩之间传送信息，她对我有什么指示，就写一张纸条让她弟弟带给我。这不，她弟弟又传送过来一个COMMAND，为了感谢他，我请他吃了碗杂酱面，哪知道他说：“我同时给 我姐姐三个男朋友送COMMAND，就数你最小气，才请我吃面。”，:-(?<BR><BR>命令模式：命令模式把一个请求或者操作封装到一个对象中。命令模式把发出命令的责任和执行命令的责任分割开，委派给不同的对象。命令模式允许请求的一方和发送的一方独立开来，使得请求的一方不必知道接收请求的一方的接口，更不必知道请求是怎么被接收，以及 操作是否执行，何时被执行以及是怎么被执行的。系统支持命令的撤消。?<BR><BR>15、INTERPRETER—俺有一个《泡MM真经》，上面有各种泡MM的攻略，比如说去吃西餐的步骤、去看电影的方法等等，跟MM约会时，只要做一个Interpreter，照着上面的脚本执行就可以了。?<BR><BR>解释器模式：给定一个语言后，解释器模式可以定义出其文法的一种表示，并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。解释器模式将描述怎样在有了一个简单的文法后，使用模式设计解释这些语句。在解释器模式里面提到的语言是指任何 解释器对象能够解释的任何组合。在解释器模式中需要定义一个代表文法的命令类的等级结构，也就是一系列的组合规则。每一个命令对象都有一个解释方法，代表对命令对象的解释。命令对象的等级结构中的对象的任何排列组合都是一个语言。?<BR><BR>16、ITERATOR—我爱上了Mary，不顾一切的向她求婚。?<BR><BR>Mary：“想要我跟你结婚，得答应我的条件”?<BR><BR>我：“什么条件我都答应，你说吧”?<BR><BR>Mary：“我看上了那个一克拉的钻石”?<BR><BR>我：“我买，我买，还有吗？”?<BR><BR>Mary：“我看上了湖边的那栋别墅”?<BR><BR>我：“我买，我买，还有吗？”?<BR><BR>Mary：“你的小弟弟必须要有50cm长”?<BR><BR>我脑袋嗡的一声，坐在椅子上，一咬牙：“我剪，我剪，还有吗？”?<BR><BR>……?<BR><BR>迭代子模式：迭代子模式可以顺序访问一个聚集中的元素而不必暴露聚集的内部表象。多个对象聚在一起形成的总体称之为聚集，聚集对象是能够包容一组对象的容器对象。迭代子模式将迭代逻辑封装到一个独立的子对象中，从而与聚集本身隔开。迭代子模式简化了聚集的 界面。每一个聚集对象都可以有一个或一个以上的迭代子对象，每一个迭代子的迭代状态可以是彼此独立的。迭代算法可以独立于聚集角色变化。?<BR><BR>17、MEDIATOR—四个MM打麻将，相互之间谁应该给谁多少钱算不清楚了，幸亏当时我在旁边，按照各自的筹码数算钱，赚了钱的从我这里拿，赔了钱的也付给我，一切就OK啦，俺得到了四个MM的电话。?<BR><BR>调停者模式：调停者模式包装了一系列对象相互作用的方式，使得这些对象不必相互明显作用。从而使他们可以松散偶合。当某些对象之间的作用发生改变时，不会立即影响其他的一些对象之间的作用。保证这些作用可以彼此独立的变化。调停者模式将多对多的相互作用转 化为一对多的相互作用。调停者模式将对象的行为和协作抽象化，把对象在小尺度的行为上与其他对象的相互作用分开处理。?<BR><BR>18、MEMENTO—同时跟几个MM聊天时，一定要记清楚刚才跟MM说了些什么话，不然MM发现了会不高兴的哦，幸亏我有个备忘录，刚才与哪个MM说了什么话我都拷贝一份放到备忘录里面保存，这样可以随时察看以前的记录啦。?<BR><BR>备忘录模式：备忘录对象是一个用来存储另外一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下，将一个对象的状态捉住，并外部化，存储起来，从而可以在将来合适的时候把这个对象还原到存储起来的状态。?<BR><BR>19、OBSERVER—想知道咱们公司最新MM情报吗？加入公司的MM情报邮件组就行了，tom负责搜集情报，他发现的新情报不用一个一个通知我们，直接发布给邮件组，我们作为订阅者（观察者）就可以及时收到情报啦?<BR><BR>观察者模式：观察者模式定义了一种一队多的依赖关系，让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时，会通知所有观察者对象，使他们能够自动更新自己。?<BR><BR>20、STATE—跟MM交往时，一定要注意她的状态哦，在不同的状态时她的行为会有不同，比如你约她今天晚上去看电影，对你没兴趣的MM就会说“有事情啦”，对你不讨厌但还没喜欢上的MM就会说“好啊，不过可以带上我同事么？”，已经喜欢上你的MM就会 说“几点钟？看完电影再去泡吧怎么样？”，当然你看电影过程中表现良好的话，也可以把MM的状态从不讨厌不喜欢变成喜欢哦。?<BR><BR>状态模式：状态模式允许一个对象在其内部状态改变的时候改变行为。这个对象看上去象是改变了它的类一样。状态模式把所研究的对象的行为包装在不同的状态对象里，每一个状态对象都属于一个抽象状态类的一个子类。状态模式的意图是让一个对象在其内部状态改变的 时候，其行为也随之改变。状态模式需要对每一个系统可能取得的状态创立一个状态类的子类。当系统的状态变化时，系统便改变所选的子类。?<BR><BR>21、STRATEGY—跟不同类型的MM约会，要用不同的策略，有的请电影比较好，有的则去吃小吃效果不错，有的去海边浪漫最合适，单目的都是为了得到MM的芳心，我的追MM锦囊中有好多Strategy哦。?<BR><BR>策略模式：策略模式针对一组算法，将每一个算法封装到具有共同接口的独立的类中，从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。策略模式把行为和环境分开。环境类负责维持和查询行为类，各种算法在具体的策略类中提供。 由于算法和环境独立开来，算法的增减，修改都不会影响到环境和客户端。?<BR><BR>22、TEMPLATE?METHOD——看过《如何说服女生上床》这部经典文章吗？女生从认识到上床的不变的步骤分为巧遇、打破僵局、展开追求、接吻、前戏、动手、爱抚、进去八大步骤(Template?method)，但每个步骤针对不同的情况，都有 不一样的做法，这就要看你随机应变啦(具体实现)；?<BR><BR>模板方法模式：模板方法模式准备一个抽象类，将部分逻辑以具体方法以及具体构造子的形式实现，然后声明一些抽象方法来迫使子类实现剩余的逻辑。不同的子类可以以不同的方式实现这些抽象方法，从而对剩余的逻辑有不同的实现。先制定一个顶级逻辑框架，而将逻辑 的细节留给具体的子类去实现。?<BR><BR>23、VISITOR—情人节到了，要给每个MM送一束鲜花和一张卡片，可是每个MM送的花都要针对她个人的特点，每张卡片也要根据个人的特点来挑，我一个人哪搞得清楚，还是找花店老板和礼品店老板做一下Visitor，让花店老板根据MM的特点选一束花 ，让礼品店老板也根据每个人特点选一张卡，这样就轻松多了；?<BR><BR>访问者模式：访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话，接受这个操作的数据结构可以保持不变。访问者模式适用于数据结构相对未定的系统，它把数据结构和作用于结构上的操作之间的耦合解脱开，使得操作集合可以 相对自由的演化。访问者模式使得增加新的操作变的很容易，就是增加一个新的访问者类。访问者模式将有关的行为集中到一个访问者对象中，而不是分散到一个个的节点类中。当使用访问者模式时，要将尽可能多的对象浏览逻辑放在访问者类中，而不是放到它的子类中。 访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。</DIV><!-- / message -->]]></description>
</item><item>
<title><![CDATA[linux 操作技巧(二)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=3039</link>
<author>gecko</author>
<pubDate>2005/2/22 22:28:45</pubDate>
<description><![CDATA[<FONT color=#0000ff>Tip1 命令行下制作ISO<BR><BR></FONT>用法: mkisofs -a -I -J -r -o filename.iso /目录<BR>用途: 将linux下某个目录中的所有文件做成iso镜像.而且我加上了参数,可以保证你做出来的光盘是在windows下也可以用的 (iso是有文件大小限制的...具体多少偶忘记了)<BR><BR><FONT color=blue>-Tip2 Linux下ISO的虚拟方法</FONT><BR><BR>步骤如下:<BR><BR>1. 把 /dev/cdrom 删除,然后运行 ln -s /dev/loop7 /dev/cdrom<BR>2. losetup /dev/loop7 xxx.iso<BR>3. mount /mnt/cdrom<BR><BR>如何换盘:<BR><BR>1. losetup -d /dev/loop7 ;目的是取消这个设备<BR>2. losetup /dev/loop7 yyy.iso ;新的iso文件<BR><BR><FONT color=blue>-Tip3 hosts的用法</FONT><BR><BR>host能够用来查询域名,然而它可以得到更多的信息.host -t mx linux.com可以查询出linux.com的MX记录,以及处理mail的host的名字.host -l linux.com会返回所有注册在linux.com下的域名.host -a linux.com则会显示这个主机的所有域名信息.<BR><BR><FONT color=blue>-Tip4 *.bz2文件如何解压缩</FONT><BR><BR>使用tar -I 或者bunzip2命令都可以.<BR><BR><FONT color=blue>-Tip5 RPM常见用法</FONT><BR><BR>安装rpm包时显示进度并校验包的正确性<BR>用-vh参数:<BR>如 rpm -ivh ipchains-1.3.6-1.i386.rpm <BR>如果用glint或xrpm则不必.<BR><BR>直接通过ftp来安装rpm包 <BR>如 rpm -i ftp://ftp.xxx.xxx <BR><BR>校验所有的rpm包，查找丢失的文件 <BR>rpm -Va <BR><BR>查找一个文件属于哪个rpm包 <BR>如 rpm -qf /usr/bin/who <BR><BR>列出一个rpm包的描述信息 <BR>如 rpm -qpi mon-0.37j-1.i386.rpm <BR><BR>列出一个rpm包的文件信息 <BR>如 rpm -qpl mon-0.37j-1.i386.rpm<BR><BR><FONT color=blue>-Tip6 查看系统监听的服务</FONT><BR><BR>用法: netstat -ln<BR>解释: "l"表示显示当前系统监听的端口信息;"n"表示端口按照端口号来显示,而不转换为service文件中定义的端口名;若希望了解各个端口都是由哪些进程监听则可以使用p参数.<BR><BR><FONT color=blue>-Tip7 查看系统运行的进程</FONT><BR><BR>用法: ps -auxw<BR>解释: 其中参数"a"表示显示系统中所有用户的的进程;"u"表示输出进程用户所属信息;"x"表示也显示没有控制台的进程;若显示行太长而被截断则可以使用f参数.<BR><BR><FONT color=blue>-Tip8 Linux帐号搬家</FONT><BR><BR>对于新账号-&gt;<BR>保证将要加入系统的新帐号放在新的位置上,这通过修改/etc/default/useradd文件中的HOME值来实现. 如: HOME=/home2 使新增帐号的主目录建在/home2下.<BR><BR>将已有帐号移至新的位置-&gt;<BR>首先，将已有帐号的主目录连带目录属性拷至新位置,可用下面命令:<BR>cp -a /home /home2<BR>或<BR>cp -rpd /home /home2<BR>然后,修改/etc/passwd文件中相应记录的home_directory域为/home2/username.<BR><BR>这样两步已将旧帐号移至新位置.确保无误后,可删去旧帐号的旧主目录以腾出原文件系统的空间. <BR><BR><FONT color=blue>-Tip9</FONT><BR>Linux 启动时屏幕显示的信息来不及看清就一闪而过,如果对这些信息感兴趣的话可以在启动完后用命令 dmesg 查看.<BR><BR><FONT color=blue>-Tip10 GRUB引导恢复小法</FONT><BR><BR>用启动盘或安装盘(linux rescue)进linux <BR>sh# grub <BR>grub&gt; root (hdx,y)<BR>grub&gt; setup (hd0) <BR>重启<BR>说明: 如果成功会有一个successful......这里的x,如果是一个盘,就是0.如果你所安装的linux的根分区在第二个硬盘上,那x就是1了;y就是装有linux系统所在的根分区.setup (hd0)就是把GRUB写到硬盘的MBR上.如果我知道我的linux装在第一个硬盘上,但我不知道装在哪个分区上,就可以先输入root (hd0,然后用[TAB]键来补齐,然后就明白了.<BR><BR><FONT color=blue>-Tip11 测试磁盘性能</FONT><BR><BR>用法: hdparm -tT /dev/hd?<BR>例如: hdparm -tT /dev/hda (测试第一个物理硬盘的速度)<BR><BR><FONT color=blue>-Tip12 将内网的服务对外开放 </FONT><BR><BR>将192.168.1.2上的8888端口映射到192.168.1.3的8888端口<BR>#iptables -t nat -A PREROUTING -p tcp -m tcp --dport 8888 -j DNAT --to-destination 192.168.1.2:8888<BR>#iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -d 192.168.1.2 -p tcp -m tcp --dport 8888 -j SNAT --to-source 192.168.1.3<BR>#iptables -A INPUT -p tcp --dport 8888 -i eth0 -j ACCEPT (视情况而加)<BR><BR><FONT color=blue>-Tip13 关闭"讨厌"的Linux按键Beep声</FONT><BR><BR>vi /etc/.inputrc 增加下面一行<BR>set bell-style none<BR><BR><FONT color=blue>-Tip14 开机进入图形/文本登陆方式</FONT><BR><BR>vi /etc/inittab<BR>id:x:initdefault: <BR>x=3:文本方式 x=5:图形方式<BR><BR><FONT color=blue>-Tip15 在GRUB中限制系统可使用的内存数量</FONT><BR><BR>限制Linux只能使用120MB内存<BR><BR>title Red Hat Linux (2.4.19) <BR>root (hd0,1) <BR>kernel /boot/vmlinuz-2.4.19 ro root=/dev/hda2 mem=120M <BR>initrd /boot/initrd-2.4.18-14.img <BR><BR><FONT color=blue>-Tip16 如何查找某条命令的相关库文件</FONT><BR><BR>在Linux环境下通过ldd命令即可实现,在控制台执行:<BR>ldd /bin/ls<BR>即可得到/bin/ls命令的相关库文件列表.<BR><BR><FONT color=blue>-Tip17 只列子目录(文件)</FONT><BR><BR>ls -F | grep /$<BR><BR>你也可以在.bashrc(针对bash)中把该命令作成alias,以后只要敲入sub就可以实现只列子目录的功能.<BR><BR>　　alias sub = “ls －F | grep /$” <BR><BR>同样,ls -l | grep ^－则是只列普通文件.<BR><BR><FONT color=blue>-Tip18 计算目录下的文件及子目录</FONT><BR><BR>ls -al | wc -l<BR><BR><FONT color=blue>-Tip19 RedHat 下显示彩色目录列表</FONT><BR><BR>ls -color 可以显示彩色目录列表,其中:<BR><BR>　　蓝色→目录<BR>　　绿色→可执行文件<BR>　　红色→压缩文件<BR>　　浅蓝色→链接文件<BR>　　灰色→其他文件<BR><BR>同样你还可以试试ls --color(比前面多-),看看两者的差别吧<BR><BR><FONT color=blue>-Tip20 列目录时显示中文文件名</FONT><BR><BR>在没有打补丁的Linux系统中,我们用ls列目录,发现中文文件名都成了?号.我们可以使用--show-control-chars命令选项来显示.<BR><BR>ls --show-control-chars<BR><BR><FONT color=blue>-Tip21 改变当前路径下所有目录和文件的所有权</FONT><BR><BR>chown -R owner[.group] *<BR><BR>也可以用find命令来实现: <BR><BR>　　find . -exec chown owner[.group] {} ;<BR><BR><FONT color=blue>-Tip22 改变所有子目录及文件的属性</FONT><BR><BR>在你要改变属性的目录下,输入命令:<BR><BR>chmod －R 777 * <BR><BR>就可以改变下面所有子目录及文件的属性,不过使用这个命令的时候要特别小心,要是在根目录下打入这个命令,你所有文件的属性都将改变,这就会引起很大的安全性问题.<BR><BR><FONT color=blue>-Tip22 使用nohup命令</FONT><BR><BR>如果你想进程在你退出系统后还能执行,可以使用nohup命令. <BR>如:<BR><BR>　　nohup tar cf /dev/tape /home &amp; <BR><BR>你退出后再重新登录的话,使用ps命令会发现进程还在执行.<BR><BR><FONT color=blue>-Tip23 重新启动</FONT><BR><BR>Ctrl+Alt+Del 或 init 6 或 shutdown -r now<BR><BR><FONT color=blue>-Tip24 快速查找文件</FONT><BR><BR>查找文件可以用find,但最好是用locate.速度快,参数少.<BR><BR>　　locate filename <BR><BR>它是在一个数据库里面查找.所以,要记得经常用updatedb命令更新数据库.一般地,我们是在crontab里面加一句,让机子在每天深夜更新数据库.<BR>另外,快速查找命令文件,可以使用whereis.<BR>例如:<BR><BR>　　whereis rpm<BR><BR><FONT color=blue>-Tip25 查找Linux命令</FONT><BR><BR>如果你想实现某种功能,但是不知道该使用什么命令.你可以试试apropos命令,它也许能帮你找到你想要的命令.例如: 你要“查找”文件,又不知道用什么命令,你可以敲入下面的命令:<BR><BR>　　apropos search<BR><BR><FONT color=blue>-Tip26 在同一个命令行上同时执行多条命令</FONT><BR><BR>用分号分隔.如编译一个源文件:<BR><BR>　　#./configure ; make ; make install<BR><BR><FONT color=blue>-Tip27 用gzip(gunzip)压缩(解压)同一目录下的多个文件</FONT><BR><BR>gzip * 或者 gunzip *<BR><BR><FONT color=blue>-Tip28 在使用less或more时,直接启动vi</FONT><BR><BR>在less或者more中打入v键,会立即启动vi编辑器,可以对文件进行编辑.<BR><BR><FONT color=blue>-Tip29 在使用mail中启动vi</FONT><BR><BR>如果你觉得用mail发送邮件编辑起来很不方便,你可以在正文的顶格输入~v,启动vi进行编辑,编辑完后退出vi,回到mail.<BR><BR><FONT color=blue>-Tip30 观察文件大小变化</FONT><BR><BR>使用watch命令,可以反复执行命令.和ls配合,可以达到观察某文件大小变化的效果. <BR><BR>　　watch ls －| file.name<BR><BR><FONT color=blue>-Tip31 查找含特定字符串的文件</FONT><BR><BR>例如查找当前目录下含有"the string you want find..."字符串的文件:<BR><BR><BR><FONT color=blue>-Tip32 观看binary文件中的字符串</FONT><BR><BR>strings binaryfile<BR><BR><FONT color=blue>-Tip33 重装Win 9x后lilo失效无法启动Linux</FONT><BR><BR>只须先用软盘启动Linux然后运行一次lilo即可.对于RedHat可以用命令mkbootdisk来制作启动盘,例如:<BR><BR>　　mkbootdisk --device /dev/fd0 2.4.20<BR><BR>其中2.4.20是/lib/modules下的一个目录.<BR><BR><FONT color=blue>-Tip34 去掉引导区内的lilo信息</FONT><BR><BR>安装lilo后如果硬盘数量或分区情况有改变的话将导致硬盘不能启动,这时只需用软盘启动DOS再运行fdisk/mbr即可.<BR><BR><FONT color=blue>-Tip35 把DOS/Windows改为缺省操作系统</FONT><BR><BR>RedHat把Linux作为lilo缺省操作系统,即出现 boot: 提示符后直接回车启动Linux.如果想改为DOS/Windows,修改文件/etc/lilo.conf,把有关启动DOS的部分放在前面,再运行一次lilo即可.也可以在lilo.conf的配置文件前面加上 Default=dos 其中DOS是DOS/Windows的label <BR><BR><FONT color=blue>-Tip36 如何使用.iso文件</FONT><BR><BR>许多Linux发行版本都有.iso的光盘镜像文件,可以用来刻录光盘.我们也可以在Linux系统下直接使用.<BR><BR>　　mount -t iso9660 xxxxx.iso /any/path/if/u/like -o loop<BR><BR><FONT color=blue>-Tip37 显示文件的类型</FONT><BR><BR>用命令 file 可以使你知道某个文件究竟是ELF格式的可执行文件,还是shell script文件或是其他的什么格式.<BR><BR>　　file filename<BR><BR><FONT color=blue>-Tip38 解压.tar.gz文件</FONT><BR><BR>xxxx.tar.gz文件使用tar带zxvf参数,可以一次解压开.<BR><BR>　　tar zxvf xxxx.tar.gz<BR><BR><FONT color=blue>-Tip39 后台运行程序</FONT><BR><BR>可以在程序后面加“&amp;”符号,让程序在后台运行.例如: 你想用updatedb更新文件路径数据库,又不影响你其他的工作.可以:<BR><BR>　　updatedb &amp;<BR><BR><FONT color=blue>-Tip40 强行退出 X</FONT><BR><BR>有时候在 X 里由于程序出错鼠标键盘都不起作用,这时候不用着急,因为在Linux下几乎不会像在Win 95里那样恶性死机,你只须同时按下Ctrl+Alt+BackSpace键就可以回到字符界面下了.<BR><BR><FONT color=blue>-Tip41 压缩可执行文件</FONT><BR><BR>可以使用gzexe压缩可执行文件,压缩后的可执行文件仍然可以直接执行.使用本方法可以达到节省磁盘空间的目的(如果你真的需要的话).<BR><BR>　　gzexe gawk<BR><BR><FONT color=blue>-Tip42 处理文件名内含有特殊字符的文件</FONT><BR><BR>如果有一个文件名叫-file,如果想删除它,键入 rm -file 会显示invalid option,原来由于文件名的第一个字符为"-",Linux把文件名当做选项了,可以加--解决这个问题,如rm -- -file.如果是其他特殊字符的话可以在特殊字符前加一个\,或者用双引号把整个文件名括起来.<BR><BR><FONT color=blue>-Tip43 快速进入目录</FONT><BR><BR>键入 cd ~ 可进入用户的home目录;键入 cd - 可进入上一个进入的目录.<BR><BR><FONT color=blue>-Tip44 想全部删除以.开头的file或dir时你会如何干?</FONT><BR><BR>Wrong-&gt; rm -r /tmp/.*<BR>Correct-&gt; rm -r /tmp/\.*<BR><BR><FONT color=blue>-Tip45 修改网卡MAC地址</FONT><BR><BR>ifconfig eth0 down<BR>ifconfig eth0 hw ether 00:AA:BB:CCD:EE<BR>ifconfig eth0 up<BR>上面的是临时性的你可以加入rc.local让它开机自动执行<BR><BR><FONT color=blue>-Tip46 查看网卡工作状态</FONT><BR><BR>#mii-tool -v<BR>eth0: no link<BR>product info: vendor 00:00:00, model 0 rev 0<BR>basic mode: autonegotiation enabled<BR>basic status: no link<BR>capabilities: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD<BR>advertising: 100baseTx-FD 100baseTx-HD 10baseT-FD 10baseT-HD<BR>SIOCGMIIPHY on 'eth1' failed: Operation not supported<BR><BR><BR><FONT color=blue>-Tip47 如何解决sendmail和sm-client启动爆慢的问题！</FONT><BR><BR>造成sendmail和sm-client启动慢是因为解析的问题，解决方法将自己的主机名加入/etc/hosts中即可，例如我的主机名是linuxbox.localdomain则/etc/hosts中应该有一条<BR>192.168.100.1 linuxbox.localdomain linuxbox<BR>]]></description>
</item><item>
<title><![CDATA[linux 操作技巧(一)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=3038</link>
<author>gecko</author>
<pubDate>2005/2/22 22:22:06</pubDate>
<description><![CDATA[<FONT color=#0000ff>-Tip1 查看man文件...<BR></FONT>nroff -man man/libnet.3 | less<BR><BR>有时候man文件不在系统目录..这时候就可以用上面的方式来查看非标准的man文件<BR><BR><BR><FONT color=blue>-Tip2 以不同的用户身份运行程序...</FONT><BR>su - username -c "where/is/command/line"<BR><BR>有时候需要运行特殊身份的程序...就可以让su来做...<BR><BR><FONT color=blue>-Tip3 解压bz文件</FONT><BR>tar -jvxf some.bz<BR><BR>就是把tar的zvxf 改成jvxf<BR><BR><BR><FONT color=blue>-Tip4 编辑/etc/inittab后直接生效的方法..</FONT><BR><BR>执行init q<BR><BR><FONT color=blue>-Tip5 让linux连续执行几个命令,出错停止</FONT><BR><BR>command1 &amp;&amp; command2 &amp;&amp; command3 ....<BR><BR><FONT color=blue>-Tip6 linux中的bg和fg管理</FONT><BR><BR>当我们打ctrl+z的时候一个任务就被挂起(就是暂停),同时屏幕上返回一个数字,<BR>这时候可以用 "bg %数字" 来把这个进程放到后台执行...这个很适合在你忘了加<BR>&amp;的时候进行补救...同样 " fg %数字 "就能让这个进程放到前台来执行了...<IMG class=inlineimg title=Smile alt="" src="http://bbs.et8.net/bbs/images/smilies/Default/dft009.gif" border=0><BR>job命令用来查看当前的被bg的进程...<BR><BR><FONT color=blue>-Tip7 ctrl+s与ctrl+q</FONT><BR><BR>ctrl-s 好象是从终端时代遗传过来的东东, 流量控制, 用来暂停向终端发送数据的. ctrl-q 用来恢复恢复<BR><BR><FONT color=blue>-Tip8 目录统计教本</FONT><BR><BR>保存成total.sh ,然后用total.sh 绝对路径,就会统计路径下目录的大小了 
<DIV style="MARGIN: 5px 20px 20px">
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">代码:</DIV>
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">#!/bin/sh<BR>du $1 --max-depth=1 | sort -n|awk '{printf "%7.2fM ----&gt; %s\n",$1/1024,$2}'|sed 's:/.*/\([^/]\{1,\}\)$:\1:g'<BR><FONT color=#0000ff>-Tip9 grep不显示本身进程<BR></DIV></FONT>
<DIV class=smallfont style="MARGIN: 5px 20px 20px">
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">代码:</DIV><PRE class=alt2 style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 5px; BORDER-TOP: 1px inset; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 640px; PADDING-TOP: 5px; BORDER-BOTTOM: 1px inset; HEIGHT: 34px">ps -aux|grep httpd|grep -v grep</PRE></DIV>
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">通过再一次grep -v grep就可以取消显示你所执行的grep本身这个进程,-v参数是不显示所列出的进程名.<BR><BR><BR><FONT color=blue>-Tip10 自己用的一个统计httpd的脚本</FONT><BR></DIV>
<DIV class=smallfont style="MARGIN: 5px 20px 20px">
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">代码:</DIV><PRE class=alt2 style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 5px; BORDER-TOP: 1px inset; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 640px; PADDING-TOP: 5px; BORDER-BOTTOM: 1px inset; HEIGHT: 130px">#!/bin/sh
while (true)
do
pstree |grep "*\[httpd\]$"|sed 's/.*-\([0-9][0-9]*\)\*\[httpd\]$/\1/'
sleep 3
done</PRE></DIV>
<DIV class=smallfont style="MARGIN-BOTTOM: 2px"><BR><FONT color=blue>-Tip 11 解压rpm包中的文件</FONT> </DIV>
<DIV class=smallfont style="MARGIN: 5px 20px 20px">
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">代码:</DIV><PRE class=alt2 style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 5px; BORDER-TOP: 1px inset; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 640px; PADDING-TOP: 5px; BORDER-BOTTOM: 1px inset; HEIGHT: 50px">cat gnome-libs-1.4.1.2.90.22.i386.rpm | rpm2cpio | pax -r</PRE></DIV>
<DIV class=smallfont style="MARGIN-BOTTOM: 2px"><BR><FONT color=blue>-Tip12 去掉apache的manual目录中的所有.en的后缀名</FONT><BR><BR>进入到manual目录<BR></DIV>
<DIV class=smallfont style="MARGIN: 5px 20px 20px">
<DIV class=smallfont style="MARGIN-BOTTOM: 2px">代码:</DIV><PRE class=alt2 style="BORDER-RIGHT: 1px inset; PADDING-RIGHT: 5px; BORDER-TOP: 1px inset; PADDING-LEFT: 5px; PADDING-BOTTOM: 5px; MARGIN: 0px; OVERFLOW: auto; BORDER-LEFT: 1px inset; WIDTH: 640px; PADDING-TOP: 5px; BORDER-BOTTOM: 1px inset; HEIGHT: 34px">find ./ -regex .*\.en|awk -F. '{ printf "mv %s.%s.%s.%s %s.%s.%s\n",$1,$2,$3,$4,$1,$2,$3}'|sh</PRE></DIV>
<DIV class=smallfont style="MARGIN-BOTTOM: 2px"><BR><BR><FONT color=blue>-Tip 13 linux里如何映射windows里的硬盘</FONT><BR>mount -t smbfs -o username=xxx,password=xxx //winxp_ip_or_hostname/sharename /local_path<BR><BR>fc2中已经不需要-t smbfs这个参数了.<BR><BR><FONT color=blue>-Tip 14 linux里如何查看可用的硬盘设备</FONT><BR>fdisk -l</DIV>
<DIV class=smallfont style="MARGIN-BOTTOM: 2px"><!-- / message --><!-- edit note --></DIV></DIV>]]></description>
</item><item>
<title><![CDATA[有用的国外开源项目网址]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=2091</link>
<author>gecko</author>
<pubDate>2005/1/19 21:41:59</pubDate>
<description><![CDATA[<SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">sourceforge <A href="http://www.sourceforge.net/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://www.sourceforge.net</SPAN></A> <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p></o:p></SPAN>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">java.net <A href="http://www.java.net/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://www.java.net</SPAN></A><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><A href="http://www.eclipse.org/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">www.eclipse.org</SPAN></A><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><A href="http://www.opensource.org/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">www.opensource.org</SPAN></A><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Lomboz <A href="http://www.objectlearn.com/index.jsp"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://www.objectlearn.com/index.jsp</SPAN></A>&nbsp;(J2EE plugin for Eclipse)<BR>htmlArea <A href="http://sourceforge.net/projects/itools-htmlarea/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/itools-htmlarea/</SPAN></A>&nbsp;(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">所见即所得的在线</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">HTML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编辑器</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>XmlBuddy <A href="http://www.xmlbuddy.com/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://www.xmlbuddy.com/</SPAN></A>&nbsp;(XML Editor plugin for Eclipse)<BR>JFreeChart <A href="http://www.jfree.org/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://www.jfree.org/</SPAN></A>&nbsp;(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于生成图表的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>EclipseME <A href="http://eclipseme.sourceforge.net/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://eclipseme.sourceforge.net/</SPAN></A>&nbsp;(J2ME Developmnt Plugin for Eclipse)<BR>mvnForum <A href="http://sourceforge.net/projects/mvnforum/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/mvnforum/</SPAN></A>&nbsp;(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">论坛</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>jChatBox <A href="http://www.javazoom.net/index.shtml"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://www.javazoom.net/index.shtml</SPAN></A>&nbsp;(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">实现的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">WEB</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">聊天引擎</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>POI <A href="http://jakarta.apache.org/poi/index.html"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/poi/index.html</SPAN></A>&nbsp;(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Excel,WORD</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">等文档的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>FileUpload <A href="http://jakarta.apache.org/commons/fileupload/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/fileupload/</SPAN></A>&nbsp;(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">HTTP</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文件上传得项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>PDFBox <A href="http://sourceforge.net/projects/pdfbox/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/pdfbox/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">PDF</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文档的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Lucene <A href="http://jakarta.apache.org/lucene/index.html"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/lucene/index.html</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">搜索引擎</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Digester <A href="http://jakarta.apache.org/commons/digester/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/digester/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">XML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">信息的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>DBCP <A href="http://jakarta.apache.org/commons/dbcp/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/dbcp/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">数据库连接池</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>AXIS <A href="http://ws.apache.org/axis/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://ws.apache.org/axis/</SPAN></A> (WebService </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的实现框架</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Jetspeed <A href="http://portals.apache.org/jetspeed-1/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://portals.apache.org/jetspeed-1/</SPAN></A> (Portal)<BR>HSQLDB <A href="http://sourceforge.net/projects/hsqldb/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/hsqldb/</SPAN></A> (Im memory Database Engine)<BR>CEWOLF <A href="http://sourceforge.net/projects/cewolf/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/cewolf/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">一套标签库实现</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">报表</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">使用的是</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">jFreeChart</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">引擎</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Struts Menu <A href="http://sourceforge.net/projects/struts-menu/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/struts-menu/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">基于</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Struts</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">菜单项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>htmlparser <A href="http://sourceforge.net/projects/htmlparser/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/htmlparser/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于解析</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">HTML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">信息的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Mondrian <A href="http://sourceforge.net/projects/mondrian/"></A><SPAN style="COLOR: navy"><A href="http://sourceforge.net/projects/mondrian/(Open"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/mondrian/</SPAN></A></SPAN>(Open Source OLAP Database)<BR>ProGuard <A href="http://sourceforge.net/projects/proguard/"></A><SPAN style="COLOR: navy"><A href="http://sourceforge.net/projects/proguard/(Java"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/proguard/</SPAN></A></SPAN>(Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的混淆器</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>InfoGlue <A href="http://sourceforge.net/projects/infoglue/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/infoglue/</SPAN></A> (J2EE </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">内容管理系统</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>JPivot <A href="http://sourceforge.net/projects/jpivot/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/jpivot/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">基于</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">WEB</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">OLAP </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">展现</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR><A href="http://java-source.net/"><SPAN style="COLOR: navy; mso-bidi-font-size: 12.0pt">http://java-source.net/</SPAN></A><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(5)</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">几个常用</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">JAVA</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">开源项目的地址荟萃</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">:<BR>Lomboz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://www.objectlearn.com/index.jsp"><SPAN style="mso-bidi-font-size: 12.0pt">http://www.objectlearn.com/index.jsp</SPAN></A> (J2EE plugin for Eclipse)<BR>htmlArea&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/itools-htmlarea/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/itools-htmlarea/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">所见即所得的在线</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">HTML<o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">编辑器</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>XmlBuddy&nbsp;&nbsp; <A href="http://www.xmlbuddy.com/"><SPAN style="mso-bidi-font-size: 12.0pt">http://www.xmlbuddy.com/</SPAN></A> (XML Editor plugin for Eclipse)<BR>JFreeChart <A href="http://www.jfree.org/"><SPAN style="mso-bidi-font-size: 12.0pt">http://www.jfree.org/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于生成图表的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>EclipseME&nbsp;&nbsp; <A href="http://eclipseme.sourceforge.net/"><SPAN style="mso-bidi-font-size: 12.0pt">http://eclipseme.sourceforge.net/</SPAN></A> (J2ME Developmnt Plugin for Eclipse)<BR>mvnForum&nbsp; <A href="http://sourceforge.net/projects/mvnforum/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/mvnforum/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">论坛</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>jChatBox&nbsp;&nbsp;&nbsp; <A href="http://www.javazoom.net/index.shtml"><SPAN style="mso-bidi-font-size: 12.0pt">http://www.javazoom.net/index.shtml</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">servlet</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">实现的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">WEB</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">聊天引擎</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>POI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://jakarta.apache.org/poi/index.html"><SPAN style="mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/poi/index.html</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Excel,WORD</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">等文档</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>FileUpload <A href="http://jakarta.apache.org/commons/fileupload/"><SPAN style="mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/fileupload/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">HTTP</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文件上传得项</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>PDFBox&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/pdfbox/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/pdfbox/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">PDF</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">文档的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Lucene&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://jakarta.apache.org/lucene/index.html"><SPAN style="mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/lucene/index.html</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">搜索引擎</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Digester&nbsp;&nbsp;&nbsp; <A href="http://jakarta.apache.org/commons/digester/"><SPAN style="mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/digester/</SPAN></A> (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">XML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">信息的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>DBCP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://jakarta.apache.org/commons/dbcp/"><SPAN style="mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/dbcp/</SPAN></A>&nbsp; (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">数据库连接池</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>AXIS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://ws.apache.org/axis/"><SPAN style="mso-bidi-font-size: 12.0pt">http://ws.apache.org/axis/</SPAN></A> (WebService </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的实现框架</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Jetspeed&nbsp;&nbsp; <A href="http://portals.apache.org/jetspeed-1/"><SPAN style="mso-bidi-font-size: 12.0pt">http://portals.apache.org/jetspeed-1/</SPAN></A> (Portal)<BR>HSQLDB&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/hsqldb/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/hsqldb/</SPAN></A> (Im memory Database Engine)<BR>CEWOLF&nbsp;&nbsp; <A href="http://sourceforge.net/projects/cewolf/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/cewolf/</SPAN></A>&nbsp; <o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">(</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">一套标签库实现</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">报表</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">,</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">使用的是</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">jFreeChart</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">引擎</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Struts Menu <A href="http://sourceforge.net/projects/struts-menu/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/struts-menu/</SPAN></A>&nbsp; (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">基于</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Struts</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Web</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">菜单项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>htmlparser&nbsp;&nbsp; <A href="http://sourceforge.net/projects/htmlparser/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/htmlparser/</SPAN></A>&nbsp;&nbsp; (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">用于解析</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">HTML</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">信息的项目</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt"><o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>Mondrian&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/mondrian/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/mondrian/</SPAN></A>&nbsp; (Open Source OLAP <o:p></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan; mso-margin-top-alt: auto; mso-margin-bottom-alt: auto" align=left><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">Database)<BR>ProGuard&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/proguard/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/proguard/</SPAN></A> (Java</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的混淆器</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>InfoGlue&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/infoglue/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/infoglue/</SPAN></A>&nbsp; (J2EE </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">内容管理系统</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>JPivot&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="http://sourceforge.net/projects/jpivot/"><SPAN style="mso-bidi-font-size: 12.0pt">http://sourceforge.net/projects/jpivot/</SPAN></A>&nbsp; (</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">基于</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">WEB</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">的</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">OLAP </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">展现</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">)<BR>HttpClient&nbsp;&nbsp; <A href="http://jakarta.apache.org/commons/httpclient/"><SPAN style="mso-bidi-font-size: 12.0pt">http://jakarta.apache.org/commons/httpclient/</SPAN></A>&nbsp; </SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">处理</SPAN><SPAN lang=EN-US style="FONT-FAMILY: Arial; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt">http</SPAN><SPAN style="FONT-FAMILY: 宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-family: Arial">客户端的接口</SPAN></P>]]></description>
</item><item>
<title><![CDATA[Java的时间处理]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=1682</link>
<author>gecko</author>
<pubDate>2005/1/8 20:04:02</pubDate>
<description><![CDATA[<P>学习在java中计算基本的时间段<BR><STRONG>概述</STRONG><BR>如果你知道怎样在java中使用日期，那么使用时间和它才不多一样简单。这篇文章告诉你怎样把他们的差别联系起来。Robert Nielsen还告诉你怎样使用java来计算抵达航班和制造过程的时间。<BR><STRONG>作者：</STRONG>Robert Nielsen <BR><STRONG>翻译：</STRONG>Cocia Lin</P>
<P>&nbsp;</P>
<P>这篇文章是在我发表过的<A href="http://www.javaworld.com/jw-12-2000/jw-1229-dates.html">&lt;计算Java时间&gt;</A>(译者:已经翻译完成)的基础上的。在这里，我列出那篇文章几个你应该熟悉得关键点。如果这几点你不太清楚，我建议你读一下&lt;计算Java时间&gt;，了解一下。 <BR>1. Java计算时间依靠1970年1月1日开始的毫秒数.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>2. Date类的构造函数Date()返回代表当前创建的时刻的对象。Date的方法getTime()返回一个long值在数值上等于1970年1月1日之前或之后的时刻。<BR>3. DateFormat类用来转换Date到String,反之亦然。静态方法getDateInstance()返回DateFormat的缺省格式；getDateInstance(DateFormat.FIELD)返回指定的DateFormat对象格式。Format(Date d)方法返回String表示日期，例如＂January 1,2002.＂反过来，parse(String s)方法返回以参数字符串表示的Date对象。<BR>4. format()方法返回的字符串格式根据不同地区的时间设置而有所不同。<BR>5. GregorianCalendear类有两个重要的构造函数：GregorianCalerdar(),返回代表当前创建时间的对象；GregorianCalendar(int year,int month,int date)返回代表任意日期的对象。GregorianCalendar类的getTime()方法返回日期对象。Add(int field,int amount)方法通过加或减时间单位，象天数，月数或年数来计算日期。<BR><STRONG>GregorianCalendar和 时间</STRONG><BR>&nbsp;两个GregorianCalendar的构造函数可以用来处理时间。前者创建一个表示日期，小时和分钟的对象：</P>
<P>GregorianCalendar(int year, int month, int date, int hour, int minute)<BR><BR>第二个创建一个表示一个日期，小时，分钟和秒：</P>
<P>GregorianCalendar(int year, int month, int date, int hour, int minute, int second)<BR><BR>首先，我应该提醒一下，每一个构造函数需要时间信息中的日期信息(年，月，日)。如果你想说2:30 p.m.,你必须指出日期。 <BR>同样，每一个GregorianCalendar构造函数创建一个在时间上使用毫秒计算的对象。所以，如果你的构造函数只提供年，月，日参数，那小时，分钟，秒和毫秒的值将被置0.<BR><STRONG>DateFormat和时间</STRONG><BR>你可以使用静态方法getDateTimeInstance(int dateStyle,int timeStyle)来建立DateFormat对象来显示时间和日期。这个方法表明你想要的日期和时间格式。如果你喜欢使用缺省格式，可以使用getDateTimeInstance()来代替它。<BR>你可以使用静态方法getTimeInstance(int timeStyle)创建DateFormat对象来显示正确的时间。 <BR>下面的程序示范了getDateTimeInstance()和getTimeInstance()怎样工作：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class Apollo {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar liftOffApollo11 = new GregorianCalendar(1969, Calendar.JULY, 16, 9, 32);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d = liftOffApollo11.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df1 = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df2 = DateFormat.getTimeInstance(DateFormat.SHORT);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s1 = df1.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s2 = df2.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(s1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(s2);<BR>&nbsp;&nbsp; }<BR>}&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR>在我的电脑上，上面的程序显示如下：<BR><BR>Jul 16, 1969 9:32:00 AM<BR>9:32 AM<BR>(输出根据你所在得地区有所不同) <BR><BR><STRONG>计算时间间隔</STRONG><BR>&nbsp;&nbsp;&nbsp;&nbsp; 你可能有时需要计算过去的时间；例如，给你开始和结束时间，你想知道制造流程的持续时间。一个出租公司按小时或天数出租东西，计算时间对他们也很有用。同样的，在金融界，经常需要计算重要的支付时间。<BR>将问题复杂化，人类至少是用两种方法计算时间。你可以说一天已经结束当24小时过去了，或者日历从今天翻到明天。我们将讨论我们想到的这两种情况。<BR><STRONG>时间段，情况 1：严格时间单位</STRONG><BR>在这种情况中，只有24小时过去，这天才过去，60分钟过去，这个小时才过去，60秒过去，这个分钟才过去，以此类推。在这个方法中，23小时的时间将被认为是0天。<BR>使用这种方法计算时间段，你从计算过去的毫秒开始。为了做到这一点，首先转换每个日期为从1970年1月1日起得毫秒数。你可以从第二个毫秒值中减去第一个毫秒值。这里有一个简单的计算：</P>
<P>import java.util.*;</P>
<P>public class ElapsedMillis {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc1 = new GregorianCalendar(1995, 11, 1, 3, 2, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc2 = new GregorianCalendar(1995, 11, 1, 3, 2, 2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // the above two dates are one second apart<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d1 = gc1.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d2 = gc2.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long l1 = d1.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long l2 = d2.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long difference = l2 - l1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Elapsed milliseconds: " + difference);<BR>&nbsp;&nbsp; }<BR>}&nbsp;&nbsp;&nbsp;&nbsp; <BR><BR>上面的程序打印如下： <BR><BR>Elapsed milliseconds: 1000 <BR><BR>这个程序也带来一点混淆。GregorianCalendar类的getTime()返回一个Date对象，Date类的getTime()方法返回从1970年1月1日到这个时间的long类型的毫秒数值。虽然他们的方法名字相同，返回值却不一样！<BR>下面的程序片断用简单的整数除法转换毫秒到秒：</P>
<P>long milliseconds = 1999;<BR>long seconds = 1999 / 1000;<BR><BR>这种方法舍去小数部分转换毫秒到秒，所以1,999毫秒等于1秒，2,000毫秒等于2秒。<BR>计算更大的单位-例如天数，小时和分钟-给定一个时间数值，可以使用下面的过程：<BR>1. 计算最大的单位，减去这个数值的秒数<BR>2. 计算第二大单位，减去这个数值的秒数<BR>3. 重复操作直到只剩下秒<BR>例如,如果你的时间的10,000秒，你想知道这个数值相应的是多少小时，多少分钟，多少秒，你从最大的单位开始：小时。10,000除以3600（一个小时的秒数）得到小时数。使用整数除法，答案是2小时（整数除法中小数舍去）计算剩下的秒数，10,000-(3,600 x 2) = 2,800秒。所以你有2小时和2,800秒。<BR>将2,800秒转换成分钟，2,800除以60。使用整数除法，答案是46。2,800 - (60 x 46) = 40秒。最后答案是2小时，46分，40秒。<BR>下面的Java程序使用上面的计算方法：</P>
<P>import java.util.*;</P>
<P>public class Elapsed1 {<BR>&nbsp;&nbsp; public void calcHMS(int timeInSeconds) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int hours, minutes, seconds;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hours = timeInSeconds / 3600;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeInSeconds = timeInSeconds - (hours * 3600);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minutes = timeInSeconds / 60;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeInSeconds = timeInSeconds - (minutes * 60);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; seconds = timeInSeconds;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(hours + " hour(s) " + minutes + " minute(s) " + seconds + " second(s)");<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Elapsed1 elap = new Elapsed1();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elap.calcHMS(10000);<BR>&nbsp;&nbsp; }<BR>}&nbsp;<BR><BR>输出结果如下：<BR><BR>2 hour(s) 46 minute(s) 40 second(s) <BR><BR>上面的程序甚至在时间少于一个小时也可以正确的计算小时数。例如，你用上面的程序计算1,000秒，输出入下： <BR>0 hour(s) 16 minute(s) 40 second(s) <BR>举一个现实世界的例子，下面的程序计算阿波罗11飞到月球使用得时间：</P>
<P>import java.util.*;</P>
<P>public class LunarLanding {</P>
<P>&nbsp;&nbsp; public long getElapsedSeconds(GregorianCalendar gc1, GregorianCalendar gc2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d1 = gc1.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d2 = gc2.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long l1 = d1.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long l2 = d2.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long difference = Math.abs(l2 - l1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return difference / 1000;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public void calcHM(long timeInSeconds) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long hours, minutes, seconds;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hours = timeInSeconds / 3600;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; timeInSeconds = timeInSeconds - (hours * 3600);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; minutes = timeInSeconds / 60;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(hours + " hour(s) " + minutes + " minute(s)" );<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar lunarLanding = new GregorianCalendar(1969, Calendar.JULY, 20, 16, 17);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar lunarDeparture = new GregorianCalendar(1969, Calendar.JULY, 21, 13, 54);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar startEVA = new GregorianCalendar(1969, Calendar.JULY, 20, 22, 56);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar endEVA = new GregorianCalendar(1969, Calendar.JULY, 21, 1, 9);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LunarLanding apollo = new LunarLanding();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long eva = apollo.getElapsedSeconds(startEVA, endEVA);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("EVA duration = ");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; apollo.calcHM(eva);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long lunarStay = apollo.getElapsedSeconds(lunarLanding, lunarDeparture);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.print("Lunar stay = ");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; apollo.calcHM(lunarStay);<BR>&nbsp;&nbsp; }<BR>}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <BR><BR>上面程序输出如下：<BR><BR>EVA duration = 2 hour(s) 13 minute(s)<BR>Lunar stay = 21 hour(s) 37 minute(s) <BR><BR>目前为止，我们计算的基础公式是这样的：1分钟=60秒，1小时=60分，1天=24小时。<BR>"1个月=？天，1年=？天"怎么办？<BR>月份的天数有28，29，30，31；一年可以是365或366天。因此，当你试图计算严格单位的月份和年时，问题就产生了。例如，如果你使用月份的平均天数（近似30.4375），并且计算下面的时间间隔:<BR><BR>* July 1, 2:00 a.m. to July 31, 10:00 p.m. <BR>* February 1, 2:00 a.m. to February 29, 10:00 p.m. <BR><BR>第一个计算结果是1个月；第二个结果是0个月！<BR>所以，在计算严格单位时间的月份和年份是要想好。<BR><STRONG>时间段，情况 2:时间单位变化<BR></STRONG>时间单位的变化相当的简单：如果你要统计天数，你可以简单的统计日期变化次数。例如，如果某事15日开始，17日结束，经过2天。（日期先是便到16，再到17）同样的，一个步骤下午3：25开始，4：10 p.m结束，历时1个小时，因为小时数值变了一次（从3到4）。<BR>图书馆经常使用这种习惯计算时间。例如，如果你从图书馆接一本书，我不能占有这本书最少24小时，会认为图书馆这样才给你算一天。而是，我的账号上记录我借书的日期。日期以变成下一天，我就已经结这本书一天了，即使总计不足24小时。<BR>当使用单位的变化来计算时间段，通常感觉计算的时间没有多于一个时间单位。例如，如果9:00 p.m.我借了一本图书馆的书，第二天中午还回去，我能算出我借了这本书一天了。可是，有一种感觉在问："1天和几个小时呢？"这本说总计借出15个小时，答案是一天还差9个小时呢？因此，这篇文章里，我将以一个时间单位变化计算时间。<BR><STRONG>单位变化的时间算法</STRONG><BR>&nbsp;这是你怎样计算两个日期的时间变化：<BR>1. 制作两个日期的拷贝。Close()方法能制作拷贝。 <BR>2. 使用日期拷贝，将所有的小于时间单位变化的部分设置成它的最小单位。例如，如果计算天数，那么将小时，分钟，秒和毫秒设置成0。这种情况中，使用clear()方法将时间值设置称他们各自的最小值。<BR>3. 取出较早的日期，将你要计算的单位加1，重复直到两个日期相等。你加1的次数就是答案。可以使用before()和after()方法，他们返回boolean值，来判断是否一个日期在另一个日期之前或之后。<BR>下面的类的方法用来计算天数和月数。</P>
<P>import java.util.*;</P>
<P>public class ElapsedTime {</P>
<P>&nbsp;&nbsp; public int getDays(GregorianCalendar g1, GregorianCalendar g2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int elapsed = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc1, gc2;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (g2.after(g1)) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2 = (GregorianCalendar) g2.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1 = (GregorianCalendar) g1.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2 = (GregorianCalendar) g1.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1 = (GregorianCalendar) g2.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.MILLISECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.SECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.MINUTE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.HOUR_OF_DAY);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.MILLISECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.SECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.MINUTE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.HOUR_OF_DAY);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( gc1.before(gc2) ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.add(Calendar.DATE, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elapsed++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return elapsed;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public int getMonths(GregorianCalendar g1, GregorianCalendar g2) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int elapsed = 0;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc1, gc2;</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (g2.after(g1)) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2 = (GregorianCalendar) g2.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1 = (GregorianCalendar) g1.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2 = (GregorianCalendar) g1.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1 = (GregorianCalendar) g2.clone();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.MILLISECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.SECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.MINUTE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.HOUR_OF_DAY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.clear(Calendar.DATE);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.MILLISECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.SECOND);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.MINUTE);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.HOUR_OF_DAY);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc2.clear(Calendar.DATE);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ( gc1.before(gc2) ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.add(Calendar.MONTH, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elapsed++;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return elapsed;<BR>&nbsp;&nbsp; }<BR>}<BR><BR>你可以在上面的类中补充另外的方法来处理小时和分钟。同样，计算时间段的算法能更高效一些，尤其是时间相隔很长。可是，作为介绍目的，这个算法有短小和简单的优势。<BR>下面的例子使用ElapsedTime类来计算两个日期之间的天使，而后是月数：</P>
<P>import java.util.*;</P>
<P>public class Example {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc1 = new GregorianCalendar(2001, Calendar.DECEMBER, 30);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc2 = new GregorianCalendar(2002, Calendar.FEBRUARY, 1);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ElapsedTime et = new ElapsedTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int days = et.getDays(gc1, gc2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int months = et.getMonths(gc1, gc2);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Days = " + days);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Months = " + months);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>当计算时，上面的程序可能有用，例如，最近的航班。它显示下面的输出： <BR><BR>Days = 33<BR>Months = 2 <BR><BR>(OK,关于航班的计算有些夸张；这个天数算法很适合像图书馆借书这样的应用，你看到了她怎样工作) <BR><STRONG>告诫<BR></STRONG>在进行时间工作时要谨慎：你看到的时间段的例子，你精确仔细的考虑非常重要。本文介绍了两种通常计算时间段的想法，但是人们能想到的时间段的计算方法仅仅受到人类想象力的限制。<BR>所以，当写一个Java程序的时候，确信你的精确度能让使用和以来这些程序的人满意。同样，彻底的测试程序对处理时间的程序非重重要。<BR><STRONG>总结<BR></STRONG>本文是在我的前一篇文章 Java时间计算介绍怎样使用GregorianCalendar 和 DateFormat类处理时间问题的基础上的。你已经看到了两种方法来思考时间段问题和两种相应的途径使用Java来处理时间问题。这里提供的信息，很基础，提供给你一个在Java中处理时间问题的有力工具。</P>
<P><STRONG>关于作者</STRONG><BR>&nbsp;Robert Nielsen是SCJP。他拥有硕士学位，专攻计算机教育，并且在计算机领域执教多年。他也在各样的杂志上发表过很多计算机相关的文章。<BR><STRONG>关于译者<BR></STRONG>Cocia Lin(<A href="mailto:cocia@163.com">cocia@163.com</A>)是程序员。它拥有学士学位，现在专攻Java相关技术，刚刚开始在计算机领域折腾。</P>]]></description>
</item><item>
<title><![CDATA[计算Java日期]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=1681</link>
<author>gecko</author>
<pubDate>2005/1/8 19:58:57</pubDate>
<description><![CDATA[<P>学习怎样创建和使用日期 <BR><STRONG>概要</STRONG><BR>&nbsp;&nbsp;&nbsp; 不管你是处理财务交易还是计划着下一步的行动，你都要知道怎样在Java中建立，使用和显示日期。这需要你简单的查阅一下相应类的API参考：一个日期可以创建3个相关类的对象。这篇文章告诉你你想要知道的内容。（3,000字）<BR><STRONG>作者：</STRONG>Robert Nielsen <BR><STRONG>翻译：</STRONG>Cocia Lin</P>
<P>&nbsp;&nbsp;&nbsp; Java统计从1970年1月1日起的毫秒的数量表示日期。也就是说，例如，1970年1月2日，是在1月1日后的86，400，000毫秒。同样的，1969年12月31日是在1970年1月1日前86，400，000毫秒。Java的Date类使用long类型纪录这些毫秒值.因为long是有符号整数，所以日期可以在1970年1月1日之前，也可以在这之后。Long类型表示的最大正值和最大负值可以轻松的表示290，000，000年的时间，这适合大多数人的时间要求。<BR><STRONG>Date 类<BR>&nbsp;&nbsp; </STRONG>Date类可以在java.util包中找到，用一个long类型的值表示一个指定的时刻。它的一个有用的构造函数是Date(),它创建一个表示创建时刻的对象。getTime()方法返回Date对象的long值。在下面的程序中，我使用Date()构造函数创建一个表示程序运行时刻的对象，并且利用getTime()方法找到这个日期代表的毫秒数量：</P>
<P>import java.util.*;</P>
<P><BR>public class Now {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date now = new Date();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long nowLong = now.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Value is " + nowLong);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>当我运行这个程序后，我得到972,568,255,150.快速确认一下这个数字，起码在一个合理的范围：它不到31年，这个数值相对1970年1月1日到我写这篇文章的时间来说，是合理的。计算机是这个毫秒值表示时间，人们可不愿意说" 我将在996,321,998,34见到你。"幸运的是，Java提供了一个转换Date对象到字符串的途径，表示成传统的形式。我们在下一节讨论DateFormat类，它直观的建立日期字符串。 <BR>DateFormat类<BR>&nbsp;DateFormat类的一个目标是建立一个人们能够识别的字符串。然而，因为语言的差别，不是所有的人希望看到严格的相同格式的日期。法国人更喜欢看到"25 decembre 2000,",但是美国人习惯看到"December 25,2000."所以一个DateFormat的实例创建以后，这个对象包含了日期的显示格式的信息。如果使用用户电脑区域设置缺省的格式，你可以象下面那样，创建DateFormat对象，使用getDateInstance()方法：</P>
<P>DateFormat df = DateFormat.getDateInstance();&nbsp;&nbsp; <BR><BR>DateFormat类在java.text包中可以找到。<BR><STRONG>转换成字符串<BR></STRONG>你可以使用format()方法转换Date对象为一个字符串。下面的示例程序说明了这个问题：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class NowString {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date now = new Date();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = df.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Today is " + s);<BR>&nbsp;&nbsp; }<BR>}&nbsp; <BR><BR>在上面的代码中，展示了没有参数，使用缺省格式的getDateInstance()方法。Java还提供了几个选择日期格式，你可以通过使用重载的getDateInstance(int style)获得。出于方便的原因，DateFormat提供了几种预置的常量，你可以使用这些常量参数。下面是几个SHORT, MEDIUM, LONG, 和FULL类型的示例：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class StyleDemo {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date now = new Date();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df =&nbsp; DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df2 = DateFormat.getDateInstance(DateFormat.MEDIUM);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df3 = DateFormat.getDateInstance(DateFormat.LONG);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df4 = DateFormat.getDateInstance(DateFormat.FULL); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s =&nbsp; df.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s1 = df1.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s2 = df2.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s3 = df3.format(now);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s4 = df4.format(now);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("(Default) Today is " + s);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("(SHORT)&nbsp;&nbsp; Today is " + s1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("(MEDIUM)&nbsp; Today is " + s2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("(LONG)&nbsp;&nbsp;&nbsp; Today is " + s3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("(FULL)&nbsp;&nbsp;&nbsp; Today is " + s4);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>程序输出如下：</P>
<P>(Default) Today is Nov 8, 2000<BR>(SHORT)&nbsp;&nbsp; Today is 11/8/00<BR>(MEDIUM)&nbsp; Today is Nov 8, 2000<BR>(LONG)&nbsp;&nbsp;&nbsp; Today is November 8, 2000<BR>(FULL)&nbsp;&nbsp;&nbsp; Today is Wednesday, November 8, 2000<BR><BR>同样的程序，在我的电脑上使用缺省设置运行后，改变区域设置为瑞典，输出如下：</P>
<P>(Default) Today is 2000-nov-08<BR>(SHORT)&nbsp;&nbsp; Today is 2000-11-08<BR>(MEDIUM)&nbsp; Today is 2000-nov-08<BR>(LONG)&nbsp;&nbsp;&nbsp; Today is den 8 november 2000<BR>(FULL)&nbsp;&nbsp;&nbsp; Today is den 8 november 2000&nbsp;&nbsp;&nbsp;&nbsp; <BR>&nbsp; <BR>从这里，你能看到，瑞典的月份不是大写的（虽然November还是november）.还有，LONG和FULL版本在瑞典语中是一样的，但是美国英语却不同。另外，有趣的是，瑞典语单词的星期三,onsdag，没有包含在FULL日期里，英语却包括。 <BR>注意你能够使用getDateInstance()方法改变DateFormat实例的语种；但是，在上面的例子中，是通过改变Windows98的控制面板的区域设置做到的。不同的地方的区域设置不同，结果就不同，这样有好处，也有不足，Java程序员应该了解这些。一个好处是Java程序员可以只写一行代码就可以显示日期，而且世界不同地区的电脑运行同样的程序会有不用的日期格式。 但是这也是一个缺点，当程序员希望显示同一种格式的时--这也有可取之处，举例来说，在程序中混合输出文本和日期，如果文本是英文，我们就不希望日期格式是其他的格式，象德文或是西班牙文。如果程序员依靠日期格式编程，日期格式将根据运行程序所在电脑的区域设置不用而不同。 <BR><FONT size=4><STRONG>解析字符串</STRONG></FONT><BR>&nbsp;通过parse()方法，DateFormat能够以一个字符串创立一个Date对象。这个方法能抛出ParseException异常，所以你必须使用适当的异常处理技术。下面的例子程序通过字符串创建Date对象：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class ParseExample {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ds = "November 1, 2000";<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d = df.parse(ds);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; catch(ParseException e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Unable to parse " + ds);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp; }<BR>}<BR><BR>在创建一个任意的日期时parse()方法很有用。我将通过另一种方法创建一个任意得日期。同时，你将看到怎样进行基本日期计算，例如计算90天后的另一天。你可以使用GregorianCalendar类来完成这个任务。 <BR><STRONG>GregorianCalendar类</STRONG><BR>&nbsp;创建一个代表任意日期的一个途径使用GregorianCalendar类的构造函数，它包含在java.util包中：</P>
<P>GregorianCalendar(int year, int month, int date) <BR><BR>注意月份的表示，一月是0，二月是1，以此类推，是12月是11。因为大多数人习惯于使用单词而不是使用数字来表示月份，这样程序也许更易读，父类Calendar使用常量来表示月份：JANUARY, FEBRUARY,等等。所以，创建Wilbur 和 Orville制造第一架动力飞机的日期（December 17, 1903），你可以使用：</P>
<P>GregorianCalendar firstFlight = new GregorianCalendar(1903, Calendar.DECEMBER, 17);&nbsp; <BR>出于清楚的考虑，你应该使用前面的形式。但是，你也应该学习怎样阅读下面的短格式。下面的例子同样表示December 17,1903（记住，在短格式中，11表示December）</P>
<P>GregorianCalendar firstFlight = new GregorianCalendar(1903, 11, 17);&nbsp;&nbsp; <BR><BR>在上一节中，你学习了转换Date对象到字符串。这里，你可以做同样的事情；但是首先，你需要将GregorianCalendar对象转换到Date。要做到这一点，你可以使用getTime()方法，从它得父类Calendar继承而来。GetTime()方法返回GregorianCalendar相应的Date对象。你能够创建GregorianCalendar对象，转换到Date对象，得到和输出相应的字符串这样一个过程。下面是例子： </P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class Flight {</P>
<P>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar firstFlight = new GregorianCalendar(1903, Calendar.DECEMBER, 17);&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d = firstFlight.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("First flight was " + s);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>有时候创建一个代表当前时刻的GregorianCalendar类的实例是很有用的。你可以简单的使用没有参数的GregorianCalendar构造函数，象这样：</P>
<P>GregorianCalendar thisday = new GregorianCalendar();<BR><BR>一个输出今天日期的例子程序，使用GregorianCalendar对象：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>class Today {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar thisday = new GregorianCalendar();&nbsp;<BR>&nbsp;&nbsp; &nbsp;&nbsp; Date d = thisday.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Today is " + s);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>注意到，Date()构造函数和GregorianCalendar()构造函数很类似：都创建一个对象，条件简单，代表今天。<BR><STRONG>日期处理<BR></STRONG>GregorianCalendar类提供处理日期的方法。一个有用的方法是add().使用add()方法，你能够增加象年，月数，天数到日期对象中。要使用add()方法，你必须提供要增加的字段，要增加的数量。一些有用的字段是DATE, MONTH, YEAR, 和 WEEK_OF_YEAR。下面的程序使用add()方法计算未来80天的一个日期。在Jules的&lt;环球80天&gt;是一个重要的数字，使用这个程序可以计算Phileas Fogg从出发的那一天1872年10月2日后80天的日期：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class World {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar worldTour = new GregorianCalendar(1872, Calendar.OCTOBER, 2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; worldTour.add(GregorianCalendar.DATE, 80);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d = worldTour.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("80 day trip will end " + s);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>这个例子是想象的，但在一个日期上增加天数是一个普遍的操作：影碟可以租3天，图书馆可以借书21天，商店经常需要将购买的物品在30天内卖出。下面的程序演示了使用年计算：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class Mortgage {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar mortgage = new GregorianCalendar(1997, Calendar.MAY, 18);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mortgage.add(Calendar.YEAR, 15);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d = mortgage.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s = df.format(d);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("15 year mortgage amortized on " + s);&nbsp;&nbsp;&nbsp; }<BR>}<BR><BR>&nbsp;&nbsp;&nbsp; add()一个重要的副作用是它改变的原来的日期。有时候，拥有原始日期和修改后的日期很重要。不幸的是，你不能简单的创建一个GregorianCalendar对象，设置它和原来的相等（equal）。原因是两个变量指向同一个Date()对象地址。如果Date对象改变，两个变量就指向改变后的日期对象。代替这种做法，应该创建一个新对象。下面的程序示范了这种做法：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class ThreeDates {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc1 = new GregorianCalendar(2000, Calendar.JANUARY, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc2 = gc1;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc3 = new GregorianCalendar(2000, Calendar.JANUARY, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Three dates all equal to January 1, 2000</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; gc1.add(Calendar.YEAR, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <A href="file://gc1/">file://gc1</A> and gc2 are changed</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d1 = gc1.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d2 = gc2.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date d3 = gc3.getTime();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s1 = df.format(d1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s2 = df.format(d2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String s3 = df.format(d3);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("gc1 is " + s1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("gc2 is " + s2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("gc3 is " + s3);<BR>&nbsp;&nbsp; }<BR>}<BR><BR>&nbsp;&nbsp;&nbsp; 程序运行后，gc1和gc2被变成2001年（因为两个对象指向同一个Date，而Date已经被改变了）。对象gc3指向一个单独的Date，它没有被改变。<BR>计算复习日期<BR>在这节，你将看到一个依据现实世界的例子。这个详细的程序计算过去一个具体的日期。例如，你阅读这篇文章，你想要记住一个印象深刻的知识点。如果你没有照片一样的记忆力，你就要定期的复习这些新资料，这将帮助你记住它。关于复习系统，Kurt Hanks 和 Gerreld L. Pulsipher在他们的&lt; Five Secrets to Personal Productivity个人能力的5个秘密&gt;中有讨论，建议看过第一眼后马上回顾一下，然后是1天后，1个星期后，1个月后，3个月后，1年后。我的这篇文章，你要马上回顾一下，从现在算起，再就是明天，然后是1个星期，1个月，3个月，1年后。我们的程序将计算这些日期。<BR>这个程序非常有用的，它将是PIM(Personal Information Manager个人信息管理器)的一个组成部分，并将确定复习时间。在下面的程序中，getDates()方法对一个返回日期数组（复习日期）的电子软件很有用。另外，你可以返回单独的一个日期，使用getFirstDay(),getOneDay(),getOneWeek(),getOnMonth()和getOneYear().当时间范围超出这个PIM的ReviewDates的计算范围时ReviewDates类演示了怎样计算时间段。现在，你可以容易的修改它用来处理你需要的时间段，象图书馆借书，录影带租赁和抵押计算。首先，ReviewDates类显示在下面：</P>
<P>import java.util.*;<BR>import java.text.*;</P>
<P>public class ReviewDates {<BR>&nbsp;&nbsp; private GregorianCalendar firstDay, oneDay, oneWeek, oneMonth, oneQuarter, oneYear;<BR>&nbsp;&nbsp; final int dateArraySize = 6;</P>
<P>&nbsp;&nbsp; ReviewDates(GregorianCalendar gcDate) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int year = gcDate.get(GregorianCalendar.YEAR);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int month = gcDate.get(GregorianCalendar.MONTH);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int date = gcDate.get(GregorianCalendar.DATE);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; firstDay = new GregorianCalendar(year, month, date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneDay = new GregorianCalendar(year, month, date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneWeek = new GregorianCalendar(year, month, date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneMonth = new GregorianCalendar(year, month, date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneQuarter = new GregorianCalendar(year, month, date);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneYear = new GregorianCalendar(year, month, date);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneDay.add(GregorianCalendar.DATE, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneWeek.add(GregorianCalendar.DATE, 7);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneMonth.add(GregorianCalendar.MONTH, 1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneQuarter.add(GregorianCalendar.MONTH, 3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oneYear.add(GregorianCalendar.YEAR, 1);<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; ReviewDates() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this(new GregorianCalendar());<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public void listDates() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DateFormat df = DateFormat.getDateInstance(DateFormat.LONG); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date startDate = firstDay.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date1 = oneDay.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date2 = oneWeek.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date3 = oneMonth.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date4 = oneQuarter.getTime();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Date date5 = oneYear.getTime();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ss =&nbsp; df.format(startDate);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ss1 = df.format(date1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ss2 = df.format(date2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ss3 = df.format(date3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ss4 = df.format(date4);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String ss5 = df.format(date5);</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Start date is " + ss);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("Following review dates are:");<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ss1);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ss2);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ss3);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ss4);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(ss5);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println();<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar[] getDates() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar[] memoryDates = new GregorianCalendar[dateArraySize];<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memoryDates[0] = firstDay;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memoryDates[1] = oneDay;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memoryDates[2] = oneWeek;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memoryDates[3] = oneMonth;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memoryDates[4] = oneQuarter;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; memoryDates[5] = oneYear;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return memoryDates;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar getFirstDay() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.firstDay;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar getOneDay() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.oneDay;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar getOneWeek() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.oneWeek;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar getOneMonth() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.oneMonth;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar getOneQuarter() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.oneQuarter;<BR>&nbsp;&nbsp; }</P>
<P>&nbsp;&nbsp; public GregorianCalendar getOneYear() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.oneYear;<BR>&nbsp;&nbsp; }<BR>}&nbsp;<BR><BR>下面是使用ReviewDates类列出复习日期的例子程序：</P>
<P>import java.util.*;</P>
<P>public class ShowDates {<BR>&nbsp;&nbsp; public static void main(String[] args) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReviewDates rd = new ReviewDates();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rd.listDates();</P>
<P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GregorianCalendar gc = new GregorianCalendar(2001, Calendar.JANUARY, 15);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReviewDates jan15 = new ReviewDates(gc);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jan15.listDates();<BR>&nbsp;&nbsp; }<BR>}<BR><BR><STRONG>总结</STRONG><BR>&nbsp;这篇文章介绍了关于日期处理的3个重要的类：Date,DateFormat,GregorianCalendar.这些类让你创建日期，转换成字符串，和计算日期基本元素。处理Java中的日期问题，这篇文章只是冰山一角。可是，我在这里介绍的类和方法不仅仅是你学习高级技术的跳板，这些类和方法本身就可以处理很多通常的日期相关的任务<BR><STRONG>关于作者</STRONG><BR>&nbsp;Robert Nielsen是SCJP。他拥有硕士学位，专攻计算机教育，并且在计算机领域执教多年。他也在各样的杂志上发表过很多计算机相关的文章。<BR><STRONG>关于译者</STRONG><BR>Cocia Lin(<A href="mailto:cocia@163.com">cocia@163.com</A>)是程序员。他拥有学士学位，现在专攻Java相关技术，刚刚开始在计算机领域折腾。</P><A></A>]]></description>
</item><item>
<title><![CDATA[JSR#168 Portlet 说明]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=gecko&amp;id=1492</link>
<author>gecko</author>
<pubDate>2005/1/2 18:21:25</pubDate>
<description><![CDATA[
<H3>ch1 序言</H3>
<P>许多大型企业的网站, 渐渐采用了 portal server 作为开发的基础. 至于什么是 portal 呢, 中文翻译为 "门户网站"。 有人可能想.. 天杀的.. 门户网站不是就像 yahoo, pchome, yam 等等。不过, 我们现在讨论的 portal server, 不是那么地简单, 基本上 yahoo, pchome, yam 那些只能称为搜索引擎的门户网站。 
<P>如果你从来沒有用过 portal server 或是似懂非懂.. 大家可以连结到 <A href="http://www.mynetscape.com/">MyNetscape</A> 或 <A href="http://my.yahoo.com/">MyYahoo</A> 去 注册一个帐号。因为 MyNetscape 的样式比较好看, 所以我接下来就以 MyNetscape 为介绍的范例。 
<P>如果你第一次接触到 portal，你会惊讶的发现... 哇.. 为何一个网站里面充满了这么多小窗口. 我们称这些小窗口叫做 "portlet"，而且每个小窗口都存在着独立的信息与内容，可以放到最大化，缩小，还原，关闭等等。当你登陆之后，可以选择及调整自己 portlet 的配置，也可以设置自己喜爱的风格与样式，更可以设置每个 portlet 的资料配置。这种以客户为上帝的系统，就是我们将要介绍的 portal。 
<H3>ch2 Portal 的组成</H3>
<P>Portal 的组成可以分为三部份 (1) Portal Server (2) Portlet Container (3) Portlet 
<H5>1) Portal Server 的定义是</H5>
<P>一个 Portal（门户网站）就是指一个 Web-based 的系统，通常都会提供个人化设置、单一登陆、以及由各种不同来源或不同网站取得各式各样的信息，并且将这些信息放在网页之中组合而成的呈现平台，门户网站会有精巧的个人化设置去提供定制的网页，当不同等级的使用者来浏览该页面将获得不同的信息内容。 </P>
<H5>2) Portlet Container 的定义是</H5>
<P>portlet container 是提供 portlets 执行的环境，包含了许多 portlets 并且管理他们的生命周期，他也会永远保存着 portlets 的喜好设置，一个 portlet container 接收到来自 portal 的请求后，接着将这个请求传递给存在 container 的 portlet 执行。portlet container 没有义务去组合 portlets 产生的信息內容，这个工作必须由 portal 来处理。portal 和 portlet container 可以放在一起视为同一个系统的组件，或者分开成为两个独立的组件。 </P>
<H5>3) Portlet 的定义是</H5>
<P>一个 Portlet 是以 Java 技术为技术的 Web 组件，由 Portlet Container 所管理，专门处理客户的 request 以及产生各种动态的信息内容。Portlets 为可插式 ( pluggable ) 的客户界面组件，提供呈现层成为一个信息系统。这些由 portlet 产生的内容也被称为片段 (fragment)，而片段是具有一些规则的Markup( HTML、XHTML、WML )，而且可以和其他的片段组合而成一个复杂的文件。而 Portlet 中的内容正常来说是与其他 Portlet 的内容聚合而成为一个 Portal 网页。而 Portlet 的生命周期是被 Portlet Container 所管理控制的。客户端和 portlets 的互动是由 portal 通过典型的 request/response 方式实现，正常来说，客户会和 portlets 所产生的内容互动，举例来说，根据下一步的连接或者是确认送出的表单，结果 portal 将会接收到 portlet 的动作，将这个处理状况转向到目标 portlet。这些 portlet 内容的产生可能会因为不同的使用者而有不同的变化，完全是根据客户对于这个 portlet 的设置。 </P>
<H3>ch3 portlet 与 servlet 的关系</H3>
<P>Portlet 和 Servlet 算是兄弟有那么一点点相似却又有那么一点点不同，因为 Servlet 和 Portlet 不尽然相同，所以研究小組決定将 portlets 定义成为一个新的组件，因此定义了 portlets 一个新的并且明确的界面与行为。为了尽可能与现有的 servlet 结合达到重复使用的目的，portlet 的规范利用了 servlet 的规范，许多观念都很相似的，结合 portlets、servlets 及 jsp 在同一个网站系统中，我们称为 portlet application 。在同一个 portlet application 中，他们将分享同一个 classloader，context 及 session。 </P>
<H5>1) Portlet 和 Servlet 的相似之处</H5>
<P>@ portlets 也是 Java 技术的 web 组件<BR>@ portlets 也是有特定的 container 在管理<BR>@ portlets 可以动态产生各种内容<BR>@ portlets 的生命周期由 container 所管理<BR>@ portlets 和客户端的互动是通过 request/response 的机制 </P>
<H5>2) Portlet 和 Servlet 也有一些不同</H5>
<P>@ portlets 只产生 markup 信息片段，不是完整的网页文件。而 Portal 会将所有的 Portlet markup 信息片 段放到一个完整的 Portal 网页。<BR>@ portlets 不会和 URL 有直接的关系<BR>@ 客户端必须通过 portal 系统才能和 portlets 互动<BR>@ portlets 有一些定义好的 request 处理，action request 以及 render request。<BR>@ portlets 默认定义 portlet modes 及窗口状态可以指出在网页中该 portlet 的哪个功能正在执行及现在的 状态。<BR>@ portlets 可以在同一个 portal 网页之中存在多个。 </P>
<H5>3) Portlet 有一些附加的功能是 Servlet 所没有的</H5>
<P>@ Portlets 能够存取及储存永久配置文件及定制资料。<BR>@ portlets 可以存取使用者数据<BR>@ portlets 具有 URL 的重写功能在文件中去动态建立连结，允许 portal server 不用去知道如何在网页的片 段之中建立连结及动作。<BR>@ portlets 可以储存临时性的数据在 portlet session 之中，拥有两个不同的范围 ：<BR>application-wide scope 及 portlet private scope 。 </P>
<H5>4) Portlet 不具有一些功能， 但是 Servlet 却有提供</H5>
<P>@ servlet 具有设置輸出的文字编码( character set encoding)方式<BR>@ servlet 可以设置 HTTP 输出的 header<BR>@ servlet 才能夠接收客户对于 portal 发出的 URL 请求 </P>
<H3>ch4 RI - pluto 冥王星计划</H3>
<P>JSR 是由 JCP ( www.jcp.org ) 这个 Java 组织所定义出来的规范。几乎每个 JSR 都会产出 TCK* 及 RI** 
<P>*TCK ( Technology Compatibility Kit ) 兼容性测试组件<BR>*RI ( Reference Implementation ) 实现参考 
<P>2003/10/27 JSR#168 Portlet Spec 1.0 已经正式公布。以后, 大家就可以开始根据这个规范开发兼容性的产品。而这个标准规范书的 RI 就是采用 <A href="http://jakarta.apache.org/pluto/">Apache Jakarta Pluto</A> 冥王星计划。至于为何叫做冥王星,我猜是 Sun 想要把光芒射到冥王星都会发光吧 :P 
<P>目前 pluto 尚未有正式的版本释放, 将来有兴趣的人可以从 jakarta 网站下载。不过目前我由 CVS 取得版本已经可以正常运行了。安装的方法十分简单.. 只需要执行 %pluto%/bin/install 就可以安装了，安装过程会询问你 tomcat 的目录，假设你 tomcat 根目录是 c:\tomcat4.1.27 ，你输入 c:\tomcat4.1.27 就可以了。 
<P>接着 http://localhost:8080/pluto/portal 就可以看到很漂亮的 portal 界面，至于操作模式与方法非常简单，请多加操控就可以慢慢了解 portlet 的控制方法了。 
<P>在 portlet spec 中定义的控制有分为 <BR>1) 基本的 Portlet Modes<BR>VIEW - 你没有做任何动作仅仅做内容显示<BR>EDIT - 编辑相关的设置<BR>HELP - 寻求帮助 
<P>2) 基本的 Window States<BR>NORMAL - 还原 portlet 窗口<BR>MAXIMIZED - 最大化 portlet 窗口<BR>MINMIZED - 最小化 portlet 窗口<BR>
<P>其实, 这些动作都已经由 portal 所实现，portlet container 将接收与回应相关的动作。真正在程序开发上并不会考虑到这些细节，除非你要做一個 portlet container。而开发上要考虑的是什么人能夠做什么事情。例如说尚未登陆的人应该只能夠 doView / doHelp，而不能夠 doEdit 这种权限管控机制的开发。 
<H3>ch5 css 定义</H3>
<P>每个通过认证的使用者，就可以使用相关的 portlet 外观 ( Look&amp;Feel )设置，而这些设置就是通过 css 来 编辑。在没有 portlet spec 之前，各家厂商都自行规定或由 ISV 各自完成，造成了許多 portlet 无法共用同一份 CSS 来实现，移植上将会有许多问题发生。 </P>
<P>因此 css 的定义对于具有定制功能的 portal 是相当重要的。 
<P>0) Anchor<BR><A ...>这个并没有定义 :P 
<P>1) Fonts ( font )<BR>portlet-font <BR>portlet-font-dim <BR>
<P>2) Message ( paragraph .. )<BR>portlet-msg-status<BR>portlet-msg-info<BR>portlet-msg-error<BR>portlet-msg-alert<BR>portlet-msg-success<BR>
<P>3) Sections ( table, div, span ... )<BR>portlet-section-header<BR>portlet-section-body<BR>portlet-section-alternate<BR>portlet-section-selected<BR>portlet-section-subheader<BR>portlet-section-footer<BR>portlet-section-text<BR>
<P>4) Forms ( form )<BR>portlet-form-label<BR>portlet-form-input-field<BR>portlet-form-button<BR>portlet-icon-label<BR>portlet-dlg-icon-label<BR>portlet-form-field-label<BR>portlet-form-field<BR>
<P>5) menus ( popup menu )<BR>portlet-menu<BR>portlet-menu-item<BR>portlet-menu-item-selected<BR>portlet-menu-item-hover<BR>portlet-menu-item-hover-selected<BR>portlet-menu-cascade-item<BR>portlet-menu-cascade-item-selected<BR>portlet-menu-description<BR>portlet-menu-caption <BR>
<P>基本上, 你要了解什么地方该用什么 css，这些 css 名称套用在你开发的 portlet 之中，你就可以移植到其他支持 jsr#168 的系统，不需要在花时间去更改成为他们的 Look&amp;Feel。 
<H3>ch6 信息片段 ( fragment markup ) 的限制</H3>
<P>每个 portlet 输出都是一个信息片段，之前有提到, 这些 markup 有些限制。 </P>
<P>如果你是生成 HTML 格式的信息片段，就*不可以*拥有以下这些 tag ：<BR>base, body, iframe, frame, frameset, head, html, 及 title 
<P>如果生成是 XHTML 或 XHTML-basic 格式的信息片段，就*不可以*拥有以下这些 tag ：<BR>base, body, iframe, head, html 及 title 
<H3>ch7 其他细节</H3>
<P>最后, portlet 需要考虑的还有 security, caching, taglib 等等.. </P>
<P>Portal 是连结后端 EAI 处理的信息整合平台，提供了企业完整的解决方案，提供了单一登陆的机制，贴心的个人化页面设置，更可以提供各式各样平台如 pda, 手机等等的统一窗口。因此, 政府与大企业都 *应该* 采用这种解决方案，通过 Webservice 达成信息流/金流/物流 的效果.... </P></A><A></A>]]></description>
</item>
</channel>
</rss>