﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Kelven Cheung-文章分类-其它</title><link>http://www.blogjava.net/zhangrenquan/category/6863.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 15 Nov 2012 05:44:47 GMT</lastBuildDate><pubDate>Thu, 15 Nov 2012 05:44:47 GMT</pubDate><ttl>60</ttl><item><title>JBOSS5.0 配置详解(转)</title><link>http://www.blogjava.net/zhangrenquan/articles/366152.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Mon, 12 Dec 2011 07:13:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/366152.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/366152.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/366152.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/366152.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/366152.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: [转自：http://xuebin530.blog.163.com/blog/static/377214720093915555643/]一． &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下载与安装JBoss 在本文中，我下载的JBoss版本为：JBOSS5.0 Beta4。下...&nbsp;&nbsp;<a href='http://www.blogjava.net/zhangrenquan/articles/366152.html'>阅读全文</a><img src ="http://www.blogjava.net/zhangrenquan/aggbug/366152.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2011-12-12 15:13 <a href="http://www.blogjava.net/zhangrenquan/articles/366152.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>登录各搜索引擎免费入口</title><link>http://www.blogjava.net/zhangrenquan/articles/365648.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Tue, 06 Dec 2011 02:35:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/365648.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/365648.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/365648.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/365648.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/365648.html</trackback:ping><description><![CDATA[登录搜索引擎是推广网站很重要的一步。为了方便大家，整理了主要搜索引擎，希望对大家有帮助。以下地址都经过了测试，可以使用，若您在使用时发现死链接，请通知我们，以便更好的为大家服务。同时也欢迎大家推荐好的搜索引擎，在留言本中给我留言就可以了。另外要指出的是，贡献流量的主要是几个著名的搜索引擎，其它的对流量贡献微乎其微。如果您时间不多，大可不必全部登录。当然，如果时间充足，又没有很多推广经费，登录一下也大有好处。 <br /><br /><span>百度免费登录入口 http://www.baidu.com/search/url_submit.htm <br />新浪免费登录入口 http://bizsite.sina.com.cn/newbizsite/docc/index-2jifu-09.htm <br />搜狐免费登录入口http://db.sohu.com/regurl/regform.asp?Step=REGFORM&amp;class= <br />天网免费登录入口 http://bingle.pku.edu.cn/submit.htm <br />雅虎免费登录入口 http://cn.yahoo.com/docs/info/suggest.html <br />Google免费登录入口 http://www.google.com/intl/zh-CN/add_url.html <br />慧聪行业免费登录入口http://202.108.33.161/web/frontward/free/free_speedlogin.asp <br />搜豹免费登录入口 http://search.sobao.com/Computers_and_Internet/Personal/ <br />焦点网免费登录入口 http://search.focus.com.cn/search/search_newurl_register.ecgi <br />协通免费登录入口 http://www.net2asp.com.cn/search/regform.htm <br />银河免费登录入口 http://search.inhe.net/navigate.asp <br />中国假日免费登录入口 http://www.china-holiday.com/newterms/hall/it/sort.asp?sortid=259 <br />山西互连网免费登录入口 http://www.shanxi.net.cn/sxhulian/addcate.asp <br />网络奇兵登陆入口http://www.net7b.com/net7b_site/denglu/index.asp <br />6128搜索引擎免费登陆入口http://www.6128.cn/add.htm <br />深圳网狐登陆入口 http://www.szfox.com/search/ <br />中国搜索同盟免费登录入口 http://service.chinasearch.com.cn/web/frontward/free/free_protocol.htm <br />北极星免费登录入口 http://www.beijixing.com.cn/bjx01/search/regi_1.asp <br />亦凡信息娱乐网络－亦凡搜索 http://www.gotofind.com/opendir/ <br />法律网免费登录入口 http://www.law-lib.com/lawseek/wzdl.asp <br />银河免费登录入口 http://search.inhe.net/navigate.asp <br />温州信息港免费登录入口 http://www.wzonline.com.cn/ <br />建设免费登录入口http://www.cnjjl.com/other/ <br />孙悟空免费登录入口 http://www.sunwukong.cn/add.php <br />猫头鹰 http://www.owlchina.com/publish.asp?l=pub <br />凯希 http://www2d.biglobe.ne.jp/~kinryou/cgi/url.html <br />ebsee http://www.ebsee.com/cgi-bin/find/find.cgi?menu=add <br />focus http://search.focus.com.cn/search/search_newurl_register.ecgi <br />zhao5.com登陆入口 http://www.zhao5.com/deng_9.htm <br />三百六十行在线登陆入口 http://www.360hang.com/ <br />中国168免费登录入口 http://www.china168.com/chaoshi/it/regsta1.asp?sortid=242 <br />中国车网免费登录入口 http://www.cncar.net/search/addsite.asp <br />绿界免费登录入口 http://ep.sunup.net/add.php <br />天上人间中文搜索引擎 http://www.6mj.com/search/ <br />企业搜索引擎 http://www.shengdarealestate.com.cn/search/sort.asp?sortid=37 <br />好东西网址登陆 http://dir.haodx.com/computer/internet/search/search_egines/ <br />中国搜索登陆入口 http://service.chinasearch.com.cn/zhongsou/wzdl/free_protocol.htm <br />网讯快车 http://www.ne163.com/ <br />广东阳江在线 http://www.gdyj.com/ <br />泰达搜索引擎 http://www.tedanet.com/search/index.asp <br />Y28 Search http://www.y28.com/cgi-bin/link/join.pl <br /></span><img src ="http://www.blogjava.net/zhangrenquan/aggbug/365648.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2011-12-06 10:35 <a href="http://www.blogjava.net/zhangrenquan/articles/365648.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse插件开发</title><link>http://www.blogjava.net/zhangrenquan/articles/89332.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Thu, 21 Dec 2006 09:34:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/89332.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/89332.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/89332.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/89332.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/89332.html</trackback:ping><description><![CDATA[<p>一、新建项目。  <br />　　按照上一篇的新建插件项目的方法，新建一个名为myplugin2的插件项目，注意：在最后一步选择“建立白空插件项目”，除此，其它都一样。截图如下：</p>
		<p>
				<img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-102058521.png" o:title="" />
				<br />   <br />       附注：发现又有上一篇的错误，中文版的Eclipse在新建项目时，比较容易有“由于类路径错误（不完整或涉及循环），所以未构建项目。”这类的错误。好办，因为中文包只是一些文本文件，对开发没用，用前面一篇所说的方法删除那些对中文包的引用（前面字符为ECLIPSE_HOME_LANGUAGE_LINK…….），如下图：  <br /><br />   <img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-102058523.png" o:title="" /><br />二、插件开发的几个关注点。 <br />　　a) 库引用。如上附注所说库引用是在建立插件初期要设置好的地方，不过一经设置基本不需要再改变。功能类似于JDK的classpath或者Jbuilder里的库引用。  <br />　　b) 插件JAVA源代码。今后主要的工作，狂写代码吧。主要都是一些*.JAVA文件。  <br />　　c) 项目根目录下的plugin.xml文件。这个文件是插件的入口文件，Eclipse根据这个文件中的设置来加载插件。代码写完了，要让Eclipse加载你的代码就要在这里面做些手脚了，这些手脚有个术语叫“设置扩展点”。象在Eclipse的加个主菜单、视图、按钮，都在这个文件里面做不同的扩展点，后面的教程会看到这个文件的使用。要人会说那我开发一个系统会有很多的菜单和按钮，那是不是都要设置这个文件呢？回答：不必，这里面只设置主要和Eclipse接壤的扩展点，其它系统里的菜单按钮就没必要了，今后会讲到。  <br />   <br />三、设置库引用。  <br />　　在删除了上面附注所说的无用且出错的引用，接下来我们要加入一些开发插件要用到的库。是那些呢？呵呵，前面我们还是用向导建立了一个helloword插件吗，参考它的就行了。如下图：  <br /><img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-102058525.png" o:title="" /></p>
		<p>   <br />　　手工加可真累，这里有个好办法。把目录C:\eclipse2.1.3\eclipse\workspace\myplugin\下的.classpath文件拷贝到C:\eclipse2.1.3\eclipse\workspace\myplugin2目录就行了。所有关于库引用的设置全保存在这个文件中。最后别忘记刷新一下项目，如下图所示：  </p>
		<p>
				<img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-102058527.png" o:title="" />
		</p>
		<p>
				<br />附注说明：</p>
		<p>　　有些文章在这里是用“文件&gt;导入...&gt;外部插件和段”来提供插件开发支持库的引用，本文不采用这种方法，因为这种会将支持库（也是一种插件项目）会新建很多相应项目，让开发界面显得很乱。还不如本文所用的建立库引用变量的方法方便简洁。  <br />   </p>
		<p>四、写源代码。  <br />　　a) 新建一个包。方法如下图所示。  <br />　　　<img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-102058529.png" o:title="" /></p>
		<p>　　包名如下：  </p>
		<p>　　　<img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-1020585211.png" o:title="" /><br />   <br />　　结果如下：  </p>
		<p>　　　<img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-1020585213.png" o:title="" /><br /><br />   <br />　　b) 然后将上一章的myplugin的SampleAction直接移动本项目myplugin2中就可以了（Eclipse支持鼠标拖拉操做）。  <br />　　c)  本文SampleAction做了一些小修改（删除了注释和构造函数）。代码如下：  <br /></p>
		<p>
		</p>
		<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
				<tbody>
						<tr>
								<td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">public class SampleAction implements IWorkbenchWindowActionDelegate {   <br />    private IWorkbenchWindow window;   <br />    public void run(IAction action) {   <br />        //这是打开一个提示窗口   <br />        MessageDialog.openInformation(window.getShell(), "myplugin 插件", "这是手工做的插件");   <br />    }   <br />    public void selectionChanged(IAction action, ISelection selection) {}   <br />    public void dispose() {}   <br />    public void init(IWorkbenchWindow window) {   <br />        this.window = window;   <br />    }   <br />}  </td>
						</tr>
				</tbody>
		</table>
		<p>   </p>
		<p>五、在plugin.xml文件中加入扩展点的代码。  <br />　　库将本项目plugin.xml文件打开，并转到其源代码视图。将如下代码加入到“&lt;/runtime&gt;”之后。（这些xml还是从上一章的项目搬过来的  <br /></p>
		<table style="BORDER-RIGHT: #cccccc 1px dotted; TABLE-LAYOUT: fixed; BORDER-TOP: #cccccc 1px dotted; BORDER-LEFT: #cccccc 1px dotted; BORDER-BOTTOM: #cccccc 1px dotted" cellspacing="0" cellpadding="6" width="95%" align="center" border="0">
				<tbody>
						<tr>
								<td style="WORD-WRAP: break-word" bgcolor="#f3f3f3">&lt;requires&gt;   <br />      &lt;import plugin="org.eclipse.core.resources"/&gt;   <br />      &lt;import plugin="org.eclipse.ui"/&gt;   <br />&lt;/requires&gt;   <br />&lt;extension point="org.eclipse.ui.actionSets"&gt;   <br />      &lt;actionSet label="样本操作集" visible="true" id="myplugin.actionSet"&gt;   <br />         &lt;menu label="样本菜单" id="sampleMenu"&gt;   <br />            &lt;separator name="sampleGroup"&gt; &lt;/separator&gt;   <br />         &lt;/menu&gt;   <br />         &lt;action   <br />               label="样本操作"   <br />               icon="icons/sample.gif"   <br />               class="com.glchengang.SampleAction"   <br />               tooltip="Hello，Eclipse world"   <br />               menubarPath="sampleMenu/sampleGroup"   <br />               toolbarPath="sampleGroup"   <br />               id="com.glchengang.SampleAction"&gt;   <br />         &lt;/action&gt;   <br />         &lt;action   <br />               label="样本操作２"   <br />               icon="icons/sample.gif"   <br />               class="com.glchengang.SampleAction"   <br />               tooltip="Hello，Eclipse world２"   <br />               menubarPath="sampleMenu/sampleGroup2"   <br />               toolbarPath="sampleGroup2"   <br />               id="com.glchengang.SampleAction2"&gt;   <br />         &lt;/action&gt;   <br />      &lt;/actionSet&gt;   <br />   &lt;/extension&gt;  </td>
						</tr>
				</tbody>
		</table>   <br />说明：  <br />　　a) requires域中定义了该插件所要使用的依赖插件,随着开发的不断深入,这里将会填加更多的引用,现在两项就够了  <br />　　b) 在extension中说明了要们要扩展org.eclipse.ui. actionSets扩展点, &lt;actionSet&gt;…..&lt;/ actionSet &gt;表示一个action组(按钮、菜单)。还有其它类型的扩展点，如org.eclipse.ui.views是视图的扩展点，org.eclipse.ui.editors是编辑器的扩展点，各种扩展点在eclipse的帮助中有详细的说明。label是显示的名称。id是唯一标识符，只要保证在plugin.xml文件不存在重复的id就行了，这里建议以包路径和类名的组合来做为id。  <br />　　c) &lt;menu&gt;….&lt;/menu&gt;表示菜单　separator标签是一个结束符，它可以对菜单分组  <br />　　d) &lt;action&gt;....&lt;/action&gt;表示按钮。Icon是图片的路径，绝对路径是什么大家实际对照就知道了，如果eclipse找不到这个图片，默认是一个红色实心小框。Class是这个按钮所对应的类，注意把包名写全，这样比较规范些。menubarPath表示把这个action做成一个菜单放在上前&lt;menu&gt;….&lt;/menu&gt;定义的主菜单下。toolbarPath表示把这个action做成一个工具栏按钮。在这里为了方便比较我将这个action的设置复制成了两份，大家可以自己改改其中的设置，然后看看实际效果。  <br />　　e) 各详细的plugin.xml大家可以参考eclipse自带的帮助文件，这里仅做一个入门性的说明。  <br />   <br />六、按钮前面一章所说的方法运行插件（运行之前注意将原来那个向导做的myplugin项目关闭掉，关闭方法：鼠标右键点击此项目－＞弹出菜单中选择关闭项目）。插件效果如下图  <br /><br />   <img src="http://www.csdn.net/Develop/ArticleImages/27/27689/CSDN_Dev_Image_2004-5-1020585215.png" o:title="" /><br /><img src ="http://www.blogjava.net/zhangrenquan/aggbug/89332.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-12-21 17:34 <a href="http://www.blogjava.net/zhangrenquan/articles/89332.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用JSP 2.0开发Web应用程序</title><link>http://www.blogjava.net/zhangrenquan/articles/85776.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Wed, 06 Dec 2006 03:01:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/85776.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/85776.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/85776.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/85776.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/85776.html</trackback:ping><description><![CDATA[JSP（JavaServer Pages）技术是对Servlet的进一步抽象，它由JCP（Java Community Process）开发，是用于生成动态内容的开放式的、可免费获取的规范，也是J2EE（Java 2 Enterprise Edition）规范的重要组成部分。许多商业应用服务器如BEA WebLogic、IBM WebSphere、Live Jrun和Orion都支持JSP技术。 <br /><br />　　从机票预订系统、银行系统到购物系统，Web上到处都在应用JSP技术。新发布的2.0版是对JSP1.2的升级，增加了一些有趣的新特性。JSP2的目标是使动态网页的设计更加容易，而且无需学习Java编程语言。<br /><br />　　本文内容包括：<br /><br />　　提供具有丰富示例代码的教程来使你熟悉JSP2.0 <br /><br />　　介绍JSP2.0的新特性 <br /><br />　　提供利用JSP2.0开发应用程序的一些体会给出了一些示例代码，对这些代码稍加修改即可用于你自己的应用程序。 <br /><br />　　如果你还不熟悉JSP，那么直接从JSP2.0入手是一个不错的主意。但是如果希望学习JSP1.2，也许你需要从JSP教程开始学习。 <br /><br />　　JSP 2.0<br /><br />　　JSP 2.0是对JSP 1.2的升级，增加了几个有趣的新特性，可以使Web应用程序设计人员和开发人员的工作更容易一些。JSP 2.0的目标是比以前更易于使用，更重要的是无须学习Java语言本身就可以使用它。它增加了一种称为SimpleTag的新扩展机制来简化标签API（Tag API）。<br /><br />　　除了其他一些改进外，JSP 2.0引入的最主要的新特性包括：<br /><br />　　一种简单的表达式语言（EL），能够用来容易地从JSP页面访问数据，这种表达式语言简化了基于JSP的不含脚本的应用程序的编写，不需要使用Java Scriptlet或者Java表达式； <br /><br />　　用于直接使用JSP技术来定义可重用的自定义行为的新语法，该语法使用.tag和.tagx文件，这类文件可由开发人员或者网页作者编写； <br />3XML语法得到了实质性的改进，增加了新的标准文件扩展名（.tagx用于标签文件，.jspx用于JSP文件）。<br /><br />　　本文主要讨论表达式语言、简化的标签API和标签文件。相信目前的JSP开发人员将会发现这些重要的特性不但有趣，而且非常有用。 为何要从1.2跨越到2.0？<br /><br />　　在Java规格请求（JSR 152）中版本号最初定为1.3。但是正如你将在后面看到的那样，由于这些新特性对JSP应用程序的开发模型产生了如此深刻的影响，专家组感到有必要把主版本号升级到2.0，这样才能充分反映这种影响。此外，新的版本号也有助于把开发人员的注意力吸引到这些有趣的新特性上来。令人欣慰的是，所有合法的JSP1.2页面同时也是合法的JSP2.0页面。<br /><br />　　JSP 2.0起步<br /><br />　　在着手学习JSP 2.0之前，你需要一个支持JSP2.0和Java Servlet 2.4规范的JSP环境。幸运的是，Jakarta Tomcat 5.0（alpha测试版）支持新的JSP2.0和Servlet 2.4规范，可以从http://jakarta.apache.org/builds/jakarta-tomcat/release/v5.0.4-alpha/下载并安装Tomcat 5.0。 <br /><br />　　JSP表达式语言<br /><br />　　向JSP网页传递信息是通过JSP scoped属性和请求参数完成的。专门为网页作者量身定做的一种表达式语言（EL）把JSP scoped属性提升为从业务逻辑向JSP页面传递信息的标准方式。但是要注意，尽管这种表达式语言是JSP的一个重要特性，它并不是一种通用的程序语言。它仅仅是一种数据访问语言，可以方便地访问和处理应用程序数据，而无需使用scriptlet或者请求时（request-time）表达式的值。 <br /><br />　　在JSP2.0之前，网页作者只能使用表达式＜%= aName %＞访问系统的值，比如下面的例子：<br /><br /><font color="#000000">＜someTags:aTag attribute="＜%= pageContext.getAttribute("aName") %＞"＞ </font><br /><font color="#000000">　　或者使用自定义JavaBeans组件的值：<br /><br /></font><font color="#000000">＜%= aCustomer.getAddress().getCountry() %＞</font><br /><font color="#000000">　　表达式语言允许网页作者使用简单的语法访问对象。比如要访问一个简单变量，可以像下面这样写： <br /><br /></font><font color="#000000">＜someTags:aTag attribute="${ aName}"＞ </font><br /><font color="#000000">　　而访问嵌套的JavaBeans属性，则可以像下面这样写： <br /><br /></font><font color="#000000">${ aCustomer.address.country} </font><p><br /><font color="#000000">　　你可能会问，这不是JavaScript的语法吗？完全正确！如果你使用过JavaScript，就会感到非常轻松，因为表达式语言正是借用了访问结构化数据的JavaScript语法。 <br /><br />　　--------------------------------------------------------------------------------<br /><br />　　注意：<br /><br />　　表达式语言最初是作为JSP标准标签库（JSTL）1.0的一部分而开发的，JSTL是一种标准标签库，它提供对通用的、结构化的任务的支持，如迭代和条件、XML文档处理、国际化和利用SQL访问数据库等。JSTL规范是由JSR 52专家组开发的。关于JSTL的介绍，请参见Faster Development with JSTL（使用JSTL加速开发）. </font></p><p><font color="#000000"></font></p><p align="center"><b><font color="red"></font>          </b></p><center>【字体：大 小】【<font color="#ff0000">报告错误</font>】【<font color="#ff0000">进入软件交流区</font>】【关闭】 
<p></p></center><p></p><p><font color="#000000">访问应用程序数据</font></p><p><font color="#000000">　　可以使用点号运算符（.）访问作为对象属性的应用程序数据，也可使用方括号运算符[‘name’]访问命名的数组元素。</font></p><p><font color="#000000">　　表达式${ data}表示名为data的scoped变量。可以使用点号（.）或方括号（[]）运算符从集合中检索属性值：</font></p><p><font color="#000000">　　点号运算符用于访问命名的属性，比如表达式${ customer.name}表示scoped变量customer的name属性；方括号运算符可用于检索命名的属性，比如在${ customer[“name”]}中。也可以通过${ customers[0]}的形式来访问集合customers中的第一项。 </font></p><p><font color="#000000">　　表达式语言统一了对点号和方括号运算符的处理，因此${ customer.name}与${ customer[“name”]}是等价的。正如你看到的那样，表达式必须使用${ 和}包围起来。</font></p><p><font color="#000000">　　EL的标识符求值方式是使用PageContext.findAttribute(String)，把标识符作为一个属性来查找它的值。如果没有找到该属性，则返回null。</font></p><p><font color="#000000">　　运算符</font></p><p><font color="#000000">　　表达式语言支持算术运算符、关系运算符和逻辑运算符，以完成大多数的数据处理操作。此外，它还提供了一个用于测试一个对象是否为空的特殊运算符。运算符如表1所示。你可以使用empty运算符判断某个集合或字符串是否为空。比方说，只有当要求的命名参数param没有给出时，表达式${ empty param.name}才返回真。Empty运算符可以与“!”运算符一起使用，比如${ !empty param.name}当要求的命名参数param存在时返回真。</font></p><p><font color="#000000">　　表1：表达式语言运算符</font></p><p><br /></p><div align="center"><font color="#000000">运算符</font></div><div align="center"><font color="#000000">说明</font></div><font color="#000000">+</font><font color="#000000">加</font><font color="#000000">-</font><font color="#000000">减</font><font color="#000000">*</font><font color="#000000">乘</font><font color="#000000">/ 或 div</font><font color="#000000">除</font><font color="#000000">% 或 mod</font><font color="#000000">模（求余）</font><font color="#000000">== 或 =</font><font color="#000000">等于</font><font color="#000000">!= 或 !=</font><font color="#000000">不等于</font><font color="#000000">＜ 或 lt</font><font color="#000000">小于</font><font color="#000000">＞ 或 gt</font><font color="#000000">大于</font><font color="#000000">＜= 或 le</font><font color="#000000">小于等于</font><font color="#000000">＞= 或 ge</font><font color="#000000">大于等于</font><font color="#000000">&amp;&amp; 或 and</font><font color="#000000">逻辑与</font><font color="#000000">|| or or</font><font color="#000000">逻辑或</font><font color="#000000">! 或 not</font><font color="#000000">逻辑非</font><font color="#000000">empty</font><font color="#000000">检查是否为空值</font><font color="#000000">a ? b : c</font><font color="#000000">条件运算符</font><br /><br /><font color="#000000">　　隐含对象<br /><br />　　除了运算符外，表达式语言还定义了一些隐含对象以支持网页作者访问需要的应用程序数据。表达式语言定义的隐含对象如表2所示，后面将给出使用这些隐含对象的一个例子。<br /><br />　　表2：表达式语言中的隐含对象<br /><br /></font><div align="center"><font color="#000000">隐含对象</font></div><div align="center"><font color="#000000">内容</font></div><font color="#000000">applicationScope</font><font color="#000000">应用程序范围内的scoped变量组成的集合</font><font color="#000000">cookie</font><font color="#000000">所有cookie组成的集合</font><font color="#000000">header</font><font color="#000000">HTTP请求头部，字符串</font><font color="#000000">headerValues</font><font color="#000000">HTTP请求头部，字符串集合</font><font color="#000000">initParam</font><font color="#000000">全部应用程序参数名组成的集合</font><font color="#000000">pageContext</font><font color="#000000">当前页面的javax.servlet.jsp.PageContext对象</font><font color="#000000">pageScope</font><font color="#000000">页面范围内所有对象的集合</font><font color="#000000">param</font><font color="#000000">所有请求参数字符串组成的集合</font><font color="#000000">paramValues</font><font color="#000000">所有作为字符串集合的请求参数</font><font color="#000000">requestScope</font><font color="#000000">所有请求范围的对象的集合</font><font color="#000000">sessionScope</font><font color="#000000">所有会话范围的对象的集合</font><br /><font color="#000000">　　表达式语言的例子<br /><br />　　如你所言，网页作者无须学习Java也能够使用这种表达式语言。示例代码1显示了一些表达式的例子和隐含对象的使用。 <br /><br />　　代码示例1: ex1.jsp <br /><br />　　要运行这个例子，请参照以下步骤，这里我们假定Tomcat 5.0安装在c:\tomcat5.0下。<br /><br />　　切换目录到 c:\Tomcat5.0\webapps\jsp-examples 创建新目录，名字可以是任意的，比如jsp2-tutorial切换到jsp2-tutorial，把ex1.jsp复制并保存到该目录下启动Tomcat 5服务器：指向“开始”-＞“程序”-＞“Apache Tomcat 5.0”，单击“Apache Tomcat 5.0”来启动Tomcat在浏览器中输入http://localhost:8080/jsp-examples/jsp2-tutorial/ex1.jsp你将看到类似图1所示的画面。使用表达式语言就这么简单！ <br /><br /></font><div align="center"><font color="#000000"><img onerror="this.src='/biancheng/UploadFiles_1911/200603/2006358537552.gif';" hspace="3" src="http://www.pcday.cn/biancheng/UploadFiles_1911/200603/2006358537552.gif" align="center" vspace="1" border="1" /><br />图1：JSP表达式语言和隐含对象</font></div><br /><font color="#000000">　　--------------------------------------------------------------------------------<br /><br />　　<b>注意:</b> 在本文中，所有的JSP文件都保存在c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial目录下。 <br /><br />　　--------------------------------------------------------------------------------<br /><br />　　填充表单例子<br /><br />　　隐含对象可用于读取填充表单的数据。代码示例2给出了一个简单的表单，该表单提示用户输入一个名字。 <br /><br />　　代码示例2: form.jsp <br /><br /></font><font color="#000000">＜HTML＞<br />＜HEAD＞<br />＜TITLE＞Form Content＜/TITLE＞<br />＜/HEAD＞<br /><br />＜BODY＞<br />　＜H3＞Fill-out-form＜/H3＞<br />　＜P＞<br />　＜FORM action="form.jsp" method="GET"＞ Name = ＜input type="text" name="name" value="${<br />param['name']}"＞ ＜input type="submit" value="Submit Name"＞<br />　＜/FORM＞ <br />　＜P＞The Name is: ${param.name}<br />＜/BODY＞＜/HTML＞</font><br /><font color="#000000">　　在本例中，当用户输入名字并单击“提交”按钮时，输入的名字就会显示同一页面中的“The Name is:”字样后面，如图2所示。<br /><br />　　同样，运行这个例子只需要把form.jsp复制到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial下并用浏览器打开它。<br /><br /></font><div align="center"><font color="#000000"><img onerror="this.src='/biancheng/UploadFiles_1911/200603/2006358538611.gif';" hspace="3" src="http://www.pcday.cn/biancheng/UploadFiles_1911/200603/2006358538611.gif" align="center" vspace="1" border="1" /><br />图2：表单处理</font></div><p></p><p><font color="#000000"></font></p><p align="center"><b>   <font color="red"></font>        </b></p><center>【字体：大 小】【<font color="#ff0000">报告错误</font>】【<font color="#ff0000">进入软件交流区</font>】【关闭】 
<p></p></center><p></p><p><font color="#000000"><strong>定义和使用函数<br /><br /></strong>　　表达式语言允许你定义可在表达式中调用的函数。函数必须作为public类中的public static方法编写。函数一经定义，它的签名（signature）就映射到标签库描述符（TLD）中。<br /><br />　　为了说明函数的使用，我们举一个简单的例子，把两个数相加。首先要编写求两数之和的Java方法代码，如代码示例3所示，这里定义了一个静态方法，它接收两个字符串参数，把它们解析成整数并返回它们的和。<br /><br />　　代码示例3: Compute.java <br /><br /></font><font color="#000000">package jsp2.examples.el;<br />import java.util.*;<br />public class Compute {<br />　public static int add(String x, String y) {<br />　　int a = 0; <br />　　int b = 0; <br />　　try {<br />　　　a = Integer.parseInt(x);<br />　　　b = Integer.parseInt(y);<br />　　}catch(Exception e) {<br />　　}<br />　　return a + b; <br />　}<br />}</font><br /><font color="#000000">　　用javac把这段代码编译成功后，下一步就要把函数的签名映射到标签库。代码示例4说明了如何把add函数映射到包含函数实现和函数签名的类。后面将说明把这段代码添加到哪儿。<br /><br />　　代码示例4: 函数描述符<br /><br /></font><font color="#000000">＜function＞<br />　＜description＞add x and y＜/description＞<br />　＜name＞add＜/name＞<br />　＜function-class＞jsp2.examples.el.Compute ＜/function-class＞<br />　＜function-signature＞int add(java.lang.String,java.lang.String) ＜/function-signature＞<br />＜/function＞</font><br /><font color="#000000">　　现在我们就可以编写一个JSP页面来使用这个函数。代码示例5是包含两个字段的一个表单，用户输入两个数字并按下“求和”按钮，就会调用上面的函数并把两个数相加，结果在同一个页面中显示出来。<br /><br />　　代码示例5: math.jsp <br /><br /></font><font color="#000000">＜%@ taglib prefix="my" uri="http://jakarta.apache.org/tomcat/jsp2-example-taglib %＞<br />＜HEAD＞＜TITLE＞Functions＜/TITLE＞＜/HEAD＞<br />＜BODY＞<br />＜H3＞Add Numbers＜/H3＞<br />＜P＞<br />＜FORM action="math.jsp" method="GET"＞ X = ＜input type="text" name="x" value="${ param["x"]}"＞<br />＜BR＞<br />Y = ＜input type="text" name="y" value="${param["y"]}"＞<br />＜input type="submit" value="Add Numbers"＞<br />＜/FORM＞<br />＜P＞The sum is: ${my:add(param["x"],param["y"])}<br />＜/BODY＞<br />＜/HTML＞</font><br /><font color="#000000">　　要运行这个例子：<br /><br />　　复制Compute.java并保存到C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\classes\jsp2\examples\el下；使用javac编译Compute.java；编辑文件C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\jsp2\jsp2-example-taglib.tld，把代码示例4中的代码段添加到文件中最后一个＜/function＞标签之后，＜/taglib＞标签之前；复制math.jsp并保存到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial下；用浏览器打开该文件。 <br /><br />　　如果一切正常，应该会看到类似如图3所示的窗口。 <br /><br /></font></p><div align="center"><font color="#000000"><img onerror="this.src='/biancheng/UploadFiles_1911/200603/2006358538827.gif';" hspace="3" src="http://www.pcday.cn/biancheng/UploadFiles_1911/200603/2006358538827.gif" align="center" vspace="1" border="1" /><br />图3：使用函数 </font></div><br /><font color="#000000">　　<b>标签处理器</b><br /><br />　　JSP 1.2中传统的标签处理API由于允许标签体中包含scriptlet而变得复杂，但是现在利用表达式语言可以编写不含scriptlet的JSP网页。最终，JSP 2.0引入了一种新的标签扩展机制，称为“简单标签扩展”，这种机制有两种使用方式：<br /><br />　　Java开发人员可以定义实现接口javax.servlet.jsp.tagext.SimpleTag的类; 不懂Java的网页编写人员则可以使用标签文件。 <br /><br />　　首先来看第一种方式，代码示例6给出了一个简单的标签处理器，它的作用仅仅是打印“This is my first tag! ”。<br /><br />　　代码示例6: HelloTag.java <br /><br /></font><font color="#000000">package jsp2.examples.simpletag;<br />import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;<br />import java.io.IOException;<br />/** * SimpleTag handler that prints "This is my first tag!" */ public class HelloTag extends SimpleTagSupport {<br />　public void doTag() throws JspException, IOException {<br />　　getJspContext().getOut().write("This is my first tag!"); <br />　}<br />}</font><br /><font color="#000000">　　编译成功后，下一步就要在TLD中定义一个标签描述符，下面是标签描述符的例子。 <br /><br />　　代码示例7: 标签描述符 <br /><br /></font><font color="#000000">＜tag＞<br />　＜description＞Prints this is my first tag＜/description＞ <br />　＜name＞hello＜/name＞<br />　＜tag-class＞jsp2.examples.simpletag.HelloTag＜/tag-class＞<br />　＜body-content＞empty＜/body-content＞<br />＜/tag＞</font><br /><font color="#000000">　　最后再编写一个使用上述标签的JSP页面文件，见代码示例8。 <br /><br />　　代码示例8: helloworld.jsp <br /><br /></font><font color="#000000">＜%@ taglib prefix="mytag" uri="/WEB-INF/jsp2/jsp2-example-taglib.tld" %＞<br />＜HTML＞<br />＜HEAD＞<br />＜TITLE＞Simple Tag Handler＜/TITLE＞<br />＜/HEAD＞<br />＜BODY＞<br />＜H2＞Simple Tag Handler＜/H2＞<br />＜P＞<br />＜B＞My first tag prints＜/B＞: ＜mytag:hello/＞<br />＜/BODY＞<br />＜/HTML＞</font><br /><font color="#000000">　　要运行这个例子：<br /><br />　　复制HelloTg.java并保存到C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\classes\jsp2\examples\simpletag下；使用javac编译HelloTag.java；把代码示例7中的标签描述符添加到文件C:\Tomcat5.0\webapps\jsp-examples\WEB-INF\jsp2\jsp2-example-taglib.tld中的＜/taglib＞之前；复制helloworld.jsp并保存到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial目录中；用浏览器打开helloworld.jsp。 <br /><br />　　如果一切正常，应该会看到类似如图4所示的画面。 <br /><br /></font><div align="center"><font color="#000000"><img onerror="this.src='/biancheng/UploadFiles_1911/200603/2006358538651.gif';" hspace="3" src="http://www.pcday.cn/biancheng/UploadFiles_1911/200603/2006358538651.gif" align="center" vspace="1" border="1" /><br />图4：简单标签处理器 <br /><br /><br /></font></div><br /><p><font color="#000000"><strong>标签文件<br /><br /></strong>　　使用简单标签扩展机制的另一种方法是通过标签文件。标签文件是一种资源文件，网页作者可以利用它抽取一段JSP代码，通过定制功能来实现代码的复用。换句话说，标签文件允许JSP网页作者使用JSP语法创建可复用的标签库。标签文件的扩展名必须是“.tag”。<br /><br />　　为说明使用标签文件是多么容易，考虑一下代码示例9。没错，这就是一个标签文件！<br /><br />　　代码示例9: greetings.tag <br /><br /></font><font color="#000000">Hello there. How are you doing?</font><br /><font color="#000000">　　一旦定义了标签文件，就可以在JSP网页的编写中使用这种定制的功能。比如代码示例10中的JSP网页。<br /><br />　　代码示例10: chat.jsp <br /><br /></font><font color="#000000">＜%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %＞<br />＜HTML＞<br />＜HEAD＞<br />＜TITLE＞JSP 2.0 Examples - Hello World Using a Tag File＜/TITLE＞<br />＜/HEAD＞<br />＜BODY＞<br />＜H2＞Tag File Example＜/H2＞<br />＜P＞<br />＜B＞The output of my first tag file is＜/B＞: ＜tags:greetings/＞<br />＜/BODY＞<br />＜/HTML＞</font><br /><font color="#000000">　　要运行这个例子：<br /><br />　　复制标签文件greetings.tags并保存在c:\Tomcat5.0\webapps\jsp-examples\WEB-INF\tags 目录下；复制JSP网页文件char.jsp并保存在c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial 目录下；用浏览器打开chat.jsp文件。 <br /><br />　　如果一切正常，应该会看到类似如图5所示的窗口。 <br /><br /></font></p><div align="center"><font color="#000000"><img onerror="this.src='/biancheng/UploadFiles_1911/200603/2006358538949.gif';" hspace="3" src="http://www.pcday.cn/biancheng/UploadFiles_1911/200603/2006358538949.gif" align="center" vspace="1" border="1" /><br />图5：简单的标签文件</font></div><br /><font color="#000000">　　--------------------------------------------------------------------------------<br /><br />　　注意: 重要的是要注意到这里没有为问候标签编写TLD，而是创建了一个标签文件并放在特殊的目录中，然后用taglib指令导入并直接使用它。<br />　　--------------------------------------------------------------------------------<br /><br />　　<b>另一个标签文件的例子</b><br /><br />　　标签文件可以作为模板使用。考虑代码示例11中的标签文件display.tag，这个例子是根据Tomcat 5.0中的面板的例子改写的。指令attribute类似于TLD中的＜attribute＞元素，允许声明自定义的动作属性。<br /><br />　　代码示例11: display.tag <br /><br /></font><p><font color="#000000">＜%@ attribute name="color" %＞＜%@ attribute name="bgcolor" %＞＜%@ attribute name="title" %＞<br />＜TABLE border="0" bgcolor="${color}"＞<br />＜TR＞<br />＜TD＞＜B＞${title}＜/B＞ ＜/TD＞<br />＜/TR＞ <br />＜TR＞ <br />＜TD＞ bgcolor="${ bgcolor}"＞ ＜jsp:doBody/＞ ＜/TD＞<br />＜/TR＞<br />＜/TABLE＞</font></p><br /><font color="#000000">　　代码示例12给出了使用上述标签的一个简单的JSP页面。<br /><br />　　代码示例12: newsportal.jsp <br /><br /></font><font color="#000000">＜%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %＞<br />＜HTML＞<br />＜HEAD＞<br />＜TITLE＞Another Tag File Example＜/TITLE＞<br />＜/HEAD＞<br />＜BODY＞<br />＜H2＞ News Portal: Another Tag File Example＜/H2＞<br />＜TABLE border="0"＞<br />＜TR valign="top"＞<br />＜TD＞<br />＜tags:display color="#ff0000" bgcolor="#ffc0c0" title="Travel"＞<br />Last French Concorde Arrives in NY<br />＜br/＞ Another Travel Headline<br />＜br/＞ Yet Another Travel Headline<br />＜br/＞ <br />＜/tags:display＞<br />＜/TD＞<br />＜TD＞ <br />＜tags:display color="#00fc00" bgcolor="#c0ffc0" title="Technology"＞ <br />Java for in-flight entertainment<br />＜BR＞ <br />Another Technology Headline<br />＜BR＞<br />Another Technology Headline<br />＜BR＞ <br />＜/tags:display＞<br />＜/TD＞<br />＜TD＞<br />＜tags:display color="#ffcc11" bgcolor="#ffffcc" title="Sports"＞<br />American Football＜BR/＞<br />NBA＜BR/＞ <br />Soccer＜BR/＞<br />＜/tags:display＞ <br />＜/TD＞ <br />＜/TR＞<br />＜/TABLE＞<br />＜/BODY＞<br />＜/HTML＞</font><br /><font color="#000000">　　要运行这个例子：<br /><br />　　复制文件display.tag并保存在c:\Tomcat5.0\webapps\jsp-examples\WEB-INF\tag 下；复制文件newsportal.jsp并保存到c:\Tomcat5.0\webapps\jsp-examples\jsp2-tutorial下；用浏览器打开newsportal文件。 <br /><br />　　结果应该会得到与图6类似的画面。 <br /><br /></font><div align="center"><font color="#000000"><img onerror="this.src='/biancheng/UploadFiles_1911/200603/2006358538443.gif';" hspace="3" src="http://www.pcday.cn/biancheng/UploadFiles_1911/200603/2006358538443.gif" align="center" vspace="1" border="1" /><br />图6：把标签文件用作模板 </font></div><br /><font color="#000000">　　<b>结论</b><br /><br />　　JSP 2.0使得快速开发和维护动态网页比以前更加容易，尽管“Java”一词出现在JSP中，但使用JSP2.0，网页作者无须学习Java程序语言本身，就能开发出全新的动态网页。本文中的例子说明了使用JSP2.0的新特性开发动态网页是多么容易。 </font><img src ="http://www.blogjava.net/zhangrenquan/aggbug/85776.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-12-06 11:01 <a href="http://www.blogjava.net/zhangrenquan/articles/85776.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>tomcat5下设置EL(expression language)</title><link>http://www.blogjava.net/zhangrenquan/articles/85773.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Wed, 06 Dec 2006 02:53:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/85773.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/85773.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/85773.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/85773.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/85773.html</trackback:ping><description><![CDATA[tomcat5下的web应用程序,默认情况下是不支持EL表达式的,如果你想使用EL表达式的话,有以下2种方法：<br /><br />方法一：<br />            在每个jsp页面添加&lt;%@ page isELIgnored="false" %&gt;<br /><br />方法二：<br />            修改web.xml中的&lt;web-app&gt;标记为<br />            &lt;web-app xmlns="<a href="http://java.sun.com/xml/ns/j2ee">http://java.sun.com/xml/ns/j2ee</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" <br />                             xsi:schemaLocation="<a href="http://java.sun.com/xml/ns/j2ee-web-app_2_4.xsd">http://java.sun.com/xml/ns/j2ee-web-app_2_4.xsd</a>" version="2.4"&gt; <br />这样就OK了<img height="1" src="http://java.ccidnet.com/art/3741/20030705/down_info.asp?id=30991" width="1" border="0" /><img src ="http://www.blogjava.net/zhangrenquan/aggbug/85773.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-12-06 10:53 <a href="http://www.blogjava.net/zhangrenquan/articles/85773.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Eclipse 插件安装</title><link>http://www.blogjava.net/zhangrenquan/articles/83181.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Fri, 24 Nov 2006 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/83181.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/83181.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/83181.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/83181.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/83181.html</trackback:ping><description><![CDATA[配置插件有两种方法，一是真接将插件释放到eclipse文件夹，二是写LINK文件，链接，这种方法比较容易管理插件，添加，删除插件都很方便。下面主要说用第二种方法：将所有下载的插件释放到同一文件夹下，假设为e:/eclipse_plugins.以配置vssplugin插件为例：将vssplugins释放到e:/eclipse_plugins下，组织文件夹为：<br /><font style="BACKGROUND-COLOR: #d3d3d3">e:eclipse_plugins<br />        |--vssplugin<br />             |--eclipse<br />                |-plugins(新建，eclipse会自动检查features和plugins文件夹下的内容)<br />                    |---org.vssplugin_1.6.1<br /></font>按上面示例，建好之后，回到eclipse文件夹，新建一个links<nobr>目录</nobr>，在该目录下，新建一个文件vss1_6_1.link(文件名任意)，内容为:<font style="BACKGROUND-COLOR: #d3d3d3">path=e:/eclipse_plugins/vssplugin</font>（让eclipse自动检查vssplugin下的features或plugins文件夹）打开eclipse，即可看到菜单栏上多了vss选项。如果不成功，删除configuration下，除config.ini的所有文件夹，重启eclipse即可。<br /><font style="BACKGROUND-COLOR: #d3d3d3">   </font><font style="BACKGROUND-COLOR: #d3d3d3">e:eclipse<br />       |--links<br />         |---vss1_6_1.link(配置其它插件时，新建相应的link文件)</font><br /><img src ="http://www.blogjava.net/zhangrenquan/aggbug/83181.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-11-24 09:56 <a href="http://www.blogjava.net/zhangrenquan/articles/83181.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>十大最欺骗眼睛的图片</title><link>http://www.blogjava.net/zhangrenquan/articles/81922.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Sat, 18 Nov 2006 06:15:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/81922.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/81922.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/81922.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/81922.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/81922.html</trackback:ping><description><![CDATA[<p>
				<font color="#ff0000" size="4">1.柱子是圆的还是方的？不仔细看还真以为是方的！<br /></font>
		</p>
		<p>
				<img alt="" src="http://yaosansi.com/blog/attachments/month_0610/120061030164152.jpg" />
		</p>
		<p> <font color="#ff0000"><font style="FONT-SIZE: 18px">2.据说能看见9张脸的智商有一百八十了 <br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/q2006103016423.jpg" /><br /><font color="#000000"> </font><font style="FONT-SIZE: 18px"><font color="#ff0000">3.狮子在哪里? </font></font><br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/920061030164219.jpg" /><br />4.那个红衣女人是真实的还是拼图里的??? <br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/p20061030164229.jpg" /><br />5. 十二个人还是十三个人？<br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/920061030164249.gif" /><br /><br /><br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/j20061030164310.gif" /><br />6.有几个黑点??? <br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/w20061030164324.jpg" /><br />7.是静的还是动的? <br /><a title="在新窗口打开图片" href="http://yaosansi.com/blog/attachments/month_0610/9200610301642190458e.jpg" target="_blank"><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/9200610301642190458e.jpg" width="500" /></a><br />8.看得出图里有一张脸吗? <br /><br /><a title="在新窗口打开图片" href="http://yaosansi.com/blog/attachments/month_0610/c2006103016479.jpg" target="_blank"><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/c2006103016479.jpg" width="500" /></a><br /><font color="#000000">　 <br /></font><font style="FONT-SIZE: 18px"><font color="#ff0000">9.一张只要你能在图中找出9颗心就可以许个愿望而且它会马上实现的神奇图片！并且能和自己心爱的人在一起！但是如果你看了这幅图不回帖或半途而废,你将成为天刹孤星 ,孤独终老..希望大家认真观察.能找出几颗算几颗.找的越多.你将来越幸福.千万别看了图不找...后果自负.信不信由你 , 天国神秘的照片 预测你一生的幸福 </font></font><br /><br /><img alt="" src="http://yaosansi.com/blog/attachments/month_0610/v20061030164723.jpg" /><br /><br />10. 看着黑点身体前后移动,发现了什么？<font color="#000000"></font><br /></font></font></p>
		<p> </p>
		<!--NEWSZW_HZH_BEGIN-->
		<a title="在新窗口打开图片" href="http://yaosansi.com/blog/attachments/month_0610/h20061030164732.jpg" target="_blank">
				<img alt="" src="http://yaosansi.com/blog/attachments/month_0610/h20061030164732.jpg" width="500" />
		</a>
		<br clear="all" />
		<br /><img src ="http://www.blogjava.net/zhangrenquan/aggbug/81922.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-11-18 14:15 <a href="http://www.blogjava.net/zhangrenquan/articles/81922.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cvs权限设置</title><link>http://www.blogjava.net/zhangrenquan/articles/54725.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Fri, 23 Jun 2006 08:40:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/54725.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/54725.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/54725.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/54725.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/54725.html</trackback:ping><description><![CDATA[
		<p>假设有用户1：lxw ;用户2：zxh<br />有用户1的模块::lxwdir;用户2的模块:zxhdir<br />要求 lxw 只能访问lxwdir;zxh只能访问zxhdir</p>
		<br />
		<p>第1步，设置CVS的库配置文件（模块CVSROOT）的访问权限<br />方法：建立超级用户的工作目录 WINCVSADMIN<br />       a.以cvsnt服务器超级用户administrtor 登陆 wincvs<br />       b.CHECKOUT 库控制文件 checkout moudel 'cvsroot',此目录下的文件为CVS的高级配置文件，可以在本地进行修改，提交，本身在版本控制之中<br />       c.修改CVSRoot的访问权限，在命令行输入如下命令  #之后为说明，不需要输入 每行命令要单独执行，这是4条命令<br />         cvs chacl default:n          #取消所有用户的默认权限<br />         cvs chacl administrator:rcw  #设置Administrator拥有所有权限 读取;创建和删除;写入<br />         cvs chown administrator      #更改的拥有者Administrator<br />         cvs lsacl                   #察看权限的设置情况<br />第2步，建立CVS的用户<br />       正常可以用WINNT 系统的用户作为CVS 的用户，访问CVS ，但是这种方式安全性太差<br />       可以建立CVS 自己的用户<br />       a.建立WINNT系统用户 CVSUSER，权限设为一般用户就可以，只要能访问WINNT就可以 <br />       b.建立密码文件PASSWD,<br />           直接在服务端 CVSROOT 目录下建立文件就可以 PASSWD<br />           出于安全考虑，不要将 passwd列在 checkoutlist 文件里面。 <br />       C.建立CVS用户 <br />          在WINCVS 命令行下输入命令 <br />          cvs passwd -a -r cvsuser zxh         #建立ZXH用户与系统用户cvsuser有一样的权限,回车后提示输入两次口令<br />          cvs passwd -a -r cvsuser lxw         #建立lxw用户与系统用户cvsuser有一样的权限,回车后提示输入两次口令<br />          cvs passwd -a -r administratro administrator #建立administrator用户与系统用户administrator有一样的权限,回车后提示输入两次口令<br />          可以看到PASSWD 文件多了两行<br />          zxh:CUXQwLMdoZHNs:cvsuser     #中间为加密的密码,密码使用Unix标准的crypt()函数加密<br />          lxw:ZTUCMKUkZ6ap2:cvsuser     <br />          administrator:oN2Stm4NIf31Q:administrator<br /><font color="#333333">第3步, 使用CVS用户登陆<br />       由于CVS 在默认模式下,是采用系统用户登陆的,这就要修改配置文件 CONFIG<br />       设置文件CONFIG为修改状态<br />       加入如下一行<br />       SystemAuth=no  #yes 默认值,表示 如果用户在PASSWD文件中不存在,就用系统用户检查权限是否正确<br />                      #no   表示用PASSWD检查用户密码权限是否正确<br />       之后提交<br />       （在设置CONFIG 文件SystemAuth=no  之后<br />        需要在cvs 控制目录cvsroot\ 下建立admin文件  <br />        这个文件是指定CVSNT的管理员列表的文件，CVSNT根据这个文件来判断一个用户是否是管理员。文件的内容很是一个用户列表。如下：<br />user1<br />  user2<br />  user3<br />这些代表user1,user2,user3都是管理员 ；<br />在此之前 cvs将服务器的管理员用户作为自己的管理员用户的） </font></p>
		<br />
		<p>
		</p>
		<br />
		<p>第4步,加入文件 WRITERS ,READERS   控制用户的读写权限<br />      在cvsroot目录下加入两个文本文件，WRITERS ,READERS<br />      其每行内容为  用户名 回车<br />      只有加入WRITERS中的用户才能进行提交<br />      加入READERS中的用户只能读取<br />      同时在两个文件中的用户只能读取<br />      在writers文件中加入如下<br />          zxh<br />          lxw  <br />          administrator      </p>
		<br />
		<p>
				<font color="#333333">第5步，    配置CVS库模块文件——modules<br />       a.将MODUES文件设为可编辑状态<br />       b.在MOUDES 加入如下3行<br />         CVSRoot            CVSRoot<br />         大狼的工作目录 -a  lxwDIR<br />         开心的工作目录 -a  ZXHDIR<br />       c.保存,提交 COMMIT<br />第6步, 为2个用户分别上传工作目录<br />       选中LXW的工作目录'LXWDIR'       IMPORT MODULE  <br />       选中ZXH的工作目录'ZXHDIR'       IMPORT MODULE          <br />       注意:上传的目录不能为空目录,其下必须有文件(啥文件都行)<br />       上传成功后,删除这2个目录OR 改名<br />(补充一下分组的使用方法：<br />分组：将权限相同的用户划分到一组，这样方便维护。就是角色的意思，分组使用在对模块访问权限的划分。<br />方法：<br />a.在服务器端 cvsroot 目录下新建文件 group<br />b.建立分组 group1,group2 ,group文件内容如下<br />group1:user1 user2 user3<br />  group2:user5 user6 user7<br />c.之后对组进行权限划分，和对单个用户方式一样，就可以使组内用户和组具有相同的权限，如 选中模块，执行如下命令<br />   chacl -R default:n<br />      cvs chacl -R group1:rcw<br />      cvs lsacl   <br />可以使，用户 user1 user2 user3 同时具有对该模块的读写和控制的权限</font>
				<br />
		</p>
		<br />
		<p>
				<font color="#333333">第7步,下载目录目到本地做权限设置 CHECKOUT MODULE<br />       CHECKOUT MODULE        选择 大狼的工作目录  'LXWDIR'<br />       CHECKOUT MODULE        选择 开心的工作目录  'ZXHDIR'<br />    做法是这样的<br />      选择 菜单\remote\checkou moudule<br />            在打开窗口中 点击‘...’ 按钮 <br />      在打开窗口中选择 大狼的工作目录 <br />      ok 按钮<br />      确定 按钮 </font>
		</p>
		<br />
		<p>
		</p>
		<br />
		<p>第8步 分别设置2用户(LXW;ZXH)对各自目录的访问权限 <br />      选中模块 LXW ,在命令行输入如下3条命令,<br />      cvs chacl -R default:n<br />      cvs chacl -R LXW:rcw<br />      cvs lsacl <br />      选中模块 ZXH ,在命令行输入如下3条命令,<br />      cvs chacl -R default:n<br />      cvs chacl -R ZXH:rcw<br />      cvs lsacl <br />说明 加 ‘-R ’参数表示对模块的权限是递归的。解释一下：<br />如目录结构   dira<br />                               |---dira1<br />                               |---dira2<br />命令：cvs chacl default:n 只对 目录 dira 有效，而对子目录无效<br />      cvs chacl -R default:n    对目录dira及其下子目录都有效<br />                              <br />第9步 已经完成了设置   <br />      以用户 LXW OR ZXH 登陆WINCVS 就只能CHECKOU 各自的模块 LXWDIR,ZXHDIR  <br />      进行相应的开发工作了</p>
		<br />
		<p>
				<font color="#333333">在执行命令cvs passwd -a -r cvsuser zxh         的时候<br />在本地目录 CVSROOT 目录下的PASSWD文件里没有生成相关的用户和密码<br />而在服务器 CVSROOT 目录下的PASSWD文件里生成了相关的用户和密码 </font>
		</p>
		<br />
		<p>
		</p>
		<br />
		<p>如果是这样，是一种正常现象<br />原因是你没有把passwd 控制文件加入到 cvs版本 控制之中—文件checkoutlist里</p>
<img src ="http://www.blogjava.net/zhangrenquan/aggbug/54725.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-06-23 16:40 <a href="http://www.blogjava.net/zhangrenquan/articles/54725.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CVS的常用命令速查手册</title><link>http://www.blogjava.net/zhangrenquan/articles/53336.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Fri, 16 Jun 2006 08:43:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/53336.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/53336.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/53336.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/53336.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/53336.html</trackback:ping><description><![CDATA[
		<table cellspacing="1" cellpadding="4" width="100%" border="0">
				<tbody>
						<tr>
								<td valign="top">
										<div class="content">
												<p>
														<a id="init" name="init">
																<b>
																		<font face="Verdana, Arial, Helvetica, sans-serif">CVS环境初始化<br /></font>
																</b>
														</a>
														<b>
																<font face="Verdana, Arial, Helvetica, sans-serif">============</font>
														</b>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">环境设置：指定CVS库的路径CVSROOT</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">tcsh<br />setenv CVSROOT /path/to/cvsroot<br />bash<br />CVSROOT=/path/to/cvsroot ; export CVSROOT</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">后面还提到远程CVS服务器的设置：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">CVSROOT=:ext:$USER@test.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">初始化：中心库版本库的初始化，其实就是一个目录</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs init</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">项目首次导入</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs import -m "write some comments here" project_name vender_tag r_tag</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">项目导出：将代码从CVS库里导出</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs checkout project_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<a id="daily" name="daily">
																<b>
																		<font face="Verdana, Arial, Helvetica, sans-serif">CVS的日常使用</font>
																</b>
														</a>
														<font face="Verdana, Arial, Helvetica, sans-serif">
																<b>  </b>
																<br />
																<b>=============</b>
														</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">确认修改：确认自己的修改并写入到CVS库里</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs commit -m "write some comments here" file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<i>
																<font face="Verdana, Arial, Helvetica, sans-serif">注意：CVS的很多动作都是通过cvs commit进行最后确认并修改的，在确认的前，还需要用户填写修改注释，以帮助其他开发人员了解修改的原因。如果不用写-m "comments"而直接确认`cvs commit file_name` 的话，cvs会自动调用系统缺省的文字编辑器(一般是vi)要求你写入注释。<br />注释的质量很重要：所以不仅必须要写，而且必须写一些比较有意义的内容：以方便其他开发人员能够很好的理解。不好的注释，很难让其他的开发人员快速的理解：比如： -m "bug fixed" 甚至 -m ""。好的注释，甚至可以用中文: -m "在用户注册过程中加入了Email地址校验"</font>
														</i>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">同步最近修改：开始工作前和将自己的工作导入到CVS库里前都要做一次：先同步 后修改</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs update -m "write some comments here" file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<i>
																<font face="Verdana, Arial, Helvetica, sans-serif">注意：不要使用项目首次导出后，以后就要用cvs update在导出的项目目录下进行同步了，而不是每次重新cvs checkout来同步文件了。如果导出后修改了文件，然后再次从导出的项目目录的上一级cvs checkout proj等于是删除了proj目录然后重新导出，上次导出后的修改就全丢了。</font>
														</i>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">修改某个版本注释：每次只确认一个文件到CVS库里是一个很好的习惯，但难免有时候忘了指定文件名，把多个文件以同样注释commit到CVS库里了，以下命令可以允许你修改某个文件某个版本的注释：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs admin -m 1.3:"write some comments here" file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">删除文件：<br />文件删除后，比如：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">rm file_name<br />cvs rm file_name<br />cvs ci -m "write some comments here"</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">以上面前2步合并的方法为：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs rm -f file_name<br />cvs ci -m "why delete file"</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<i>
																<font face="Verdana, Arial, Helvetica, sans-serif">注意：很多cvs命令都有缩写形式：commit=&gt;ci; update=&gt;up; checkout=&gt;co; remove=&gt;rm;</font>
														</i>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">添加文件 文件添加后，比如：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">touch new_file<br />cvs add new_file<br />cvs ci -m "write some comments here"</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">添加目录：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs add dir_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">查看修改历史：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs log file_name<br />cvs history file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">查看当前文件不同版本的区别</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs diff -r1.3 -r1.5 file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">查看当前文件（可能已经修改了）和库中相应文件的区别</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs diff file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">cvs的web界面提供了更方便的定位文件修改和比较版本区别的方法，具体安装设置请看后面的cvsweb使用</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">正确的通过CVS恢复旧版本的方法：<br />如果用</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs update -r1.2 file.name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">这个命令是给file.name加一个STICK TAG： "1.2" ，虽然你的本意只是想将它恢复到1.2版本<br />正确的恢复版本的方法是</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs update -p -r1.2 file_name &gt;file_name</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">如果不小心已经加成STICK TAG的话：用cvs update -A 解决</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">移动文件：文件重命名<br />cvs里没有cvs move或cvs rename，因为这两个操作是先cvs remove old_file_name，然后cvs add new_file_name实现的。</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">删除，移动目录：<br />最方便的方法是让管理员直接移动，删除CVSROOT里相应目录（因为CVS一个项目下的子目录都是独立的，移动到$CVSROOT目录下都可以作为新的独立项目：好比一颗树，其实砍下任意一枝都能独立存活），对目录进行了修改后，要求其开发人员重新导出项目cvs checkout project_name 或者用cvs update -dP同步。</font>
												</p>
												<p>
														<a id="branch" name="branch">
																<b>
																		<font face="Verdana, Arial, Helvetica, sans-serif">CVS Branch：项目多分支同步开发<br /></font>
																</b>
														</a>
														<b>
																<font face="Verdana, Arial, Helvetica, sans-serif">=============================</font>
														</b>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">确认版本里程碑：多个文件各自版本号不一样，项目到一定阶段，可以给所有文件统一指定一个阶段里程碑版本号，方便以后按照这个阶段里程碑版本号导出项目，同时也是项目的多个分支开发的基础。</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs tag release_1_0</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">开始一个新的里程碑：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs commit -r 2</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">标记所有文件开始进入2.x的开发</font>
												</p>
												<p>
														<i>
																<font face="Verdana, Arial, Helvetica, sans-serif">注意：CVS里的revsion和软件包的发布版本可以没有直接的关系。但所有文件使用和发布版本一致的版本号比较有助于维护。</font>
														</i>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">在开发项目的2.x版本的时候发现1.x有问题，但2.x又不敢用，则从先前标记的里程碑：release_1_0导出一个分支release_1_0_patch</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs rtag -b -r release_1_0 release_1_0_patch proj_dir</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">一些人先在另外一个目录下导出release_1_0_patch这个分支：解决1.0中的紧急问题，</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs checkout -r release_1_0_patch</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">而其他人员仍旧在项目的主干分支2.x上开发</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">在release_1_0_patch上修正错误后，标记一个1.0的错误修正版本号</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs tag release_1_0_patch_1</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">如果2.0认为这些错误修改在2.0里也需要，也可以在2.0的开发目录下合并release_1_0_patch_1中的修改到当前代码中：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">cvs update -j release_1_0_patch_1</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<b>
																<font face="Verdana, Arial, Helvetica, sans-serif">CVS的远程认证：</font>
														</b>
														<a id="ssh" name="ssh">
																<b>
																		<font face="Verdana, Arial, Helvetica, sans-serif">通过SSH远程访问CVS<br /></font>
																</b>
														</a>
														<b>
																<font face="Verdana, Arial, Helvetica, sans-serif">================================</font>
														</b>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">使用cvs本身的远程认证很麻烦,需要定义服务器和用户组，用户名，设置密码等，而且不安全，因此和系统本地帐号认证并通过SSH传输是比较好的办法，通过在客户机的/etc/profile里设置一下内容：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">CVSROOT=:ext:$USER@test.server.address#port:/path/to/cvsroot CVS_RSH=ssh; export CVSROOT CVS_RSH</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">所有客户机所有本地用户都可以映射到CVS服务器相应同名帐号了。</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">如果CVS所在服务器的SSH端口不在缺省的22，或者和客户端与CVS服务器端SSH缺省端口不一致，有时候设置了：</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">:ext:$USER@test.server.address#port:/path/to/cvsroot</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">仍然不行，比如有以下错误信息：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">ssh: test.server.address#port: Name or service not known<br />cvs [checkout aborted]: end of file from server (consult above messages if any)</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">解决的方法是做一个脚本指定端口转向（不能使用alias，会出找不到文件错误）：<br />创建一个/usr/bin/ssh_cvs文件：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">#!/usr/bin/sh<br />/path/to/ssh -p 34567 "$@"</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">然后：chmod +x /usr/bin/ssh_cvs<br />并CVS_RSH=ssh_cvs; export CVS_RSH</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">注意：port是指相应服务器SSH的端口，不是cvs pserver的端口</font>
												</p>
												<p>
														<a id="cvsweb" name="cvsweb">
																<b>
																		<font face="Verdana, Arial, Helvetica, sans-serif">CVSWEB：提高程序员比较文件修改效率<br /></font>
																</b>
														</a>
														<b>
																<font face="Verdana, Arial, Helvetica, sans-serif">================================</font>
														</b>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVSWEB就是CVS的WEB界面，可以大大提高程序员定位修改的效率:<br />使用的样例可以看：</font>
														<a href="http://www.freebsd.org/cgi/cvsweb.cgi">
																<font face="Verdana, Arial, Helvetica, sans-serif">http://www.freebsd.org/cgi/cvsweb.cgi</font>
														</a>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVSWEB的下载：CVSWEB从最初的版本已经演化出很多功能界面更丰富的版本，这个是个人感觉觉得安装设置比较方便的：</font>
														<a href="http://www.spaghetti-code.de/software/linux/cvsweb/">
																<font face="Verdana, Arial, Helvetica, sans-serif">http://www.spaghetti-code.de/software/linux/cvsweb/</font>
														</a>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">下载解包：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">tar zxf cvsweb.tgz</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">把配置文件cvsweb.conf放到安全的地方（比如和apache的配置放在同一个目录下），<br />修改：cvsweb.cgi让CGI找到配置文件：</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">$config = $ENV{'CVSWEB_CONFIG'} || '/path/to/apache/conf/cvsweb.conf';</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">转到/path/to/apache/conf下并修改cvsweb.conf：</font>
												</p>
												<ol>
														<li>
																<font face="Verdana, Arial, Helvetica, sans-serif">修改CVSROOT路径设置：<br />%CVSROOT = (<br />'Development' =&gt; '/path/to/cvsroot', #&lt;==修改指向本地的CVSROOT<br />); </font>
														</li>
														<li>
																<font face="Verdana, Arial, Helvetica, sans-serif">缺省不显示已经删除的文档：<br />"hideattic" =&gt; "1",#&lt;==缺省不显示已经删除的文档 </font>
														</li>
														<li>
																<font face="Verdana, Arial, Helvetica, sans-serif">在配置文件cvsweb.conf中还可以定制页头的描述信息，你可以修改$long_intro成你需要的文字</font>
														</li>
												</ol>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVSWEB可不能随便开放给所有用户，因此需要使用WEB用户认证：<br />先生成 passwd:</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">/path/to/apache/bin/htpasswd -c cvsweb.passwd user</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">修改httpd.conf: 增加</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">&lt;Directory "/path/to/apache/cgi-bin/cvsweb/"&gt;<br />AuthName "CVS Authorization"<br />AuthType Basic<br />AuthUserFile /path/to/cvsweb.passwd<br />require valid-user<br />&lt;/Directory&gt;</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<a id="tag" name="tag">
																<b>
																		<font face="Verdana, Arial, Helvetica, sans-serif">CVS TAGS: who? when?<br /></font>
																</b>
														</a>
														<b>
																<font face="Verdana, Arial, Helvetica, sans-serif">====================</font>
														</b>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">将$Id$ 加在程序文件开头的注释里是一个很好的习惯，cvs能够自动更新其中的内容成：file_name version time user_name 的格式，比如：cvs_card.txt,v 1.1 2002/04/05 04:24:12 chedong Exp，可以这些信息了解文件的最后修改人和修改时间</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">几个常用的缺省文件：<br />default.php</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">&lt;?php<br />/*<br />* Copyright (c) 2002 Company Name.<br />* $Id$<br />*/<br /><br />?&gt;</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">Default.java: 注意文件头一般注释用 /* 开始 JAVADOC注释用 /** 开始的区别</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">/*<br />* Copyright (c) 2002 Company Name.<br />* $Id$<br />*/<br /><br />package com.netease;<br /><br />import java.io;<br /><br />/**<br />* comments here<br />*/<br />public class Default {<br />    /**<br />    *<br />    * @param<br />    * @return<br />    */<br />    public toString() {<br /><br />    }<br />}</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">default.pl:</font>
												</p>
												<table class="code" style="BORDER-COLLAPSE: collapse" bordercolor="#111111" cellspacing="1" width="100%" bgcolor="#e0e0e0" border="0">
														<tbody>
																<tr>
																		<td width="100%">
																				<font face="Verdana, Arial, Helvetica, sans-serif" size="2">#!/usr/bin/perl -w<br /># Copyright (c) 2002 Company Name.<br /># $Id$<br /><br /># file comments here<br /><br />use strict;</font>
																		</td>
																</tr>
														</tbody>
												</table>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">相关资源：</font>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVS HOME：<br /></font>
														<a href="http://www.cvshome.org/">
																<font face="Verdana, Arial, Helvetica, sans-serif">http://www.cvshome.org/</font>
														</a>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVS FAQ：<br /></font>
														<a href="http://www.loria.fr/~molli/cvs-index.html">
																<font face="Verdana, Arial, Helvetica, sans-serif">http://www.loria.fr/~molli/cvs-index.html</font>
														</a>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">相关网站:<br /></font>
														<a href="http://directory.google.com/Top/Computers/Software/Configuration_Management/Tools/Concurrent_Versions_System/">
																<font face="Verdana, Arial, Helvetica, sans-serif">Google: CVS</font>
														</a>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVS 免费书:<br /></font>
														<a href="http://cvsbook.red-bean.com/">
																<font face="Verdana, Arial, Helvetica, sans-serif">http://cvsbook.red-bean.com/</font>
														</a>
												</p>
												<p>
														<font face="Verdana, Arial, Helvetica, sans-serif">CVS 命令的速查卡片：<br /></font>
														<a href="http://www.refcards.com/about/cvs.html">
																<font face="Verdana, Arial, Helvetica, sans-serif">http://www.refcards.com/about/cvs.html</font>
														</a>
														<br />
														<br />
												</p>
										</div>
								</td>
						</tr>
						<!-- write by trotter 论坛链接 -->
						<tr>
								<td class="subhead" valign="top">了解更多详情，参与讨论，请进入<b>GBUNIX论坛</b>：<br /><br /><a class="subhead" href="http://www.gbunix.com/bbs/forums.html">http://www.gbunix.com/bbs/forums.html</a></td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/zhangrenquan/aggbug/53336.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-06-16 16:43 <a href="http://www.blogjava.net/zhangrenquan/articles/53336.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Linux下CVS安装及配置</title><link>http://www.blogjava.net/zhangrenquan/articles/53335.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Fri, 16 Jun 2006 08:38:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/53335.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/53335.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/53335.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/53335.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/53335.html</trackback:ping><description><![CDATA[
		<p>[网上摘录，不知道谁是真正的作者]<br />我的现在情况.<br />服务器:红帽子企业4(上已经安装了oracle)<br />cvs为:cvsnt-2.5.03.2151-rh9-rpm.tar.gz ,在<a href="http://www.march-hare.com/cvspro/">http://www.march-hare.com/cvspro/</a>,下载的是最新的</p>
		<p>版本</p>
		<p>我的安装过程:<br />确认是否安装了老版本的cvs,如果有老版本的,就统统删除<br />[root@redhat /]# rpm -qa |grep cvs<br />libbonoboui-2.8.0.99cvs20040929-2<br />cvs-1.11.17-7.RHEL4<br />[root@redhat /]# rpm -e cvs-1.11.17-7.RHEL4<br />[root@redhat /]# rpm -qa | grep cvs<br />libbonoboui-2.8.0.99cvs20040929-2</p>
		<p>将下载的cvs文件解压<br />[root@redhat cvs]# tar zxvf cvsnt-2.5.03.2151-rh9-rpm.tar.gz <br />cvsnt-2.5.03.2151-1.i386.rpm<br />cvsnt-database-mysql-2.5.03.2151-1.i386.rpm<br />cvsnt-database-odbc-2.5.03.2151-1.i386.rpm<br />cvsnt-database-sqlite-2.5.03.2151-1.i386.rpm<br />cvsnt-protocol-gserver-2.5.03.2151-1.i386.rpm<br />cvsnt-protocol-sserver-2.5.03.2151-1.i386.rpm<br />[root@redhat cvs]# ls<br />cvsnt-2.5.03.2151-1.i386.rpm cvsnt-database-sqlite-2.5.03.2151-1.i386.rpm<br />cvsnt-2.5.03.2151-rh9-rpm.tar.gz cvsnt-protocol-gserver-2.5.03.2151-1.i386.rpm<br />cvsnt-database-mysql-2.5.03.2151-1.i386.rpm cvsnt-protocol-sserver-2.5.03.2151-1.i386.rpm<br />cvsnt-database-odbc-2.5.03.2151-1.i386.rpm</p>
		<p>安装相关的rpm包(之后立刻确认安装)<br />[root@redhat cvs]# rpm -ivh cvsnt-2.5.03.2151-1.i386.rpm<br />Preparing... ########################################### [100%]<br />   1:cvsnt ########################################### [100%]<br />[root@redhat cvs]# rpm -qa |grep cvs<br />libbonoboui-2.8.0.99cvs20040929-2<br />cvsnt-2.5.03.2151-1</p>
		<p>[root@redhat src]# cvs -version</p>
		<p>Concurrent Versions System (CVSNT) 2.5.03 (Scorpio) Build 2151 (client/server)</p>
		<p>建立cvs用户组<br />[root@redhat /]# groupadd cvs<br />以上建立组的语句,不会在/home中多出任何目录来.</p>
		<p>建立以后的存放目录<br />[root@redhat /]# mkdir cvs<br />[root@redhat /]# cd cvs<br />[root@redhat cvs]# mkdir src<br />[root@redhat cvs]# cd src<br />[root@redhat src]# pwd<br />/cvs/src<br />[root@redhat src]# </p>
		<p>指定cvs组的cvsroot用户和所属的目录<br />[root@redhat src]# useradd -g cvs -G cvs -d/cvs cvsroot</p>
		<p>为cvsroot用户添加密码<br />[root@redhat cvs]# passwd cvsroot<br />Changing password for user cvsroot.<br />New UNIX password: <br />BAD PASSWORD: it does not contain enough DIFFERENT characters<br />Retype new UNIX password: <br />passwd: all authentication tokens updated successfully.</p>
		<p>改变/cvs的目录属性<br />[root@redhat /]# chmod 775 /cvs<br />drwxrwxr-x 4 root root 4096 Dec 7 14:14 cvs<br />[root@redhat cvs]# chmod 775 src<br />drwxrwxr-x 2 root root 4096 Dec 7 14:06 src</p>
		<p>对cvs进行相关的版本确认<br />[root@redhat /]# cvs version<br />Concurrent Versions System (CVSNT) 2.5.03 (Scorpio) Build 2151 (client/server)</p>
		<p>启动cvs服务器<br />[root@redhat /]# more /etc/services|grep cvspserver<br />cvspserver 2401/tcp # CVS client/server operations <br />cvspserver 2401/udp # CVS client/server operations</p>
		<p>如果上面没有这个内容就<br />[root@redhat /]# vi /etc/services<br />来添加相关的内容</p>
		<p>[root@redhat /]# vi /etc/xinetd.d/cvspserver<br />service cvspserver<br />{<br />disable = no<br />flags = REUSE<br />port = 2401<br />socket_type = stream<br />protocol = tcp<br />wait = no<br />user = root<br />passenv = PATH<br />server = /usr/bin/cvs<br />server_args = -f --allow-root=/cvs pserver<br />log_on_failure += USERID<br />}</p>
		<p>shift+wq!<br />"/etc/xinetd.d/cvspserver" [New] 14L, 225C written<br />[root@redhat src]# ls /etc/xinetd.d/cvspserver<br />/etc/xinetd.d/cvspserver<br />[root@redhat src]# su cvsroot<br />[cvsroot@redhat src]$ pwd<br />/cvs/src<br />[root@redhat /]# service xinetd restart<br />Stopping xinetd: [ OK ]<br />Starting xinetd: [ OK ]<br />[root@redhat /]# netstat -l |grep cvspserver<br />tcp 0 0 *:cvspserver *:* LISTEN</p>
		<p>初始化cvs源码库,新建立一个Repository,此操作生成目录/cvs/CVSROOT(或者/cvs/src/CVSROOT),其下</p>
		<p>为一些初始化文件<br />[root@redhat src]# export CVSROOT=/cvs/src<br />[root@redhat src]# env | grep CVSROOT<br />CVSROOT=/cvs/src</p>
		<p>[root@redhat src]# cvs -d /cvs/src init</p>
		<p>
		</p>
		<p>在服务器端初置口令认证</p>
		<p>首先，你可能需要 <samp><span class="file"><font face="新宋体">$CVSROOT</font></span></samp> 和 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT</font></span></samp> 上设定权限。见 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Password-authentication-security.html#Password-authentication-security">Password authentication security</a>。 </p>
		<p>
				<a name="index-pserver-_0028subcommand_0029-163">
				</a>
				<a name="index-Remote-repositories_002c-port-specification-164">
				</a>
				<a name="index-Repositories_002c-remote_002c-port-specification-165">
				</a>
				<a name="index-Client_002fServer-Operation_002c-port-specification-166">
				</a>
				<a name="index-pserver-_0028client_002fserver-connection-method_0029_002c-port-specification-167">
				</a>
				<a name="index-kserver-_0028client_002fserver-connection-method_0029_002c-port-specification-168">
				</a>
				<a name="index-gserver-_0028client_002fserver-connection-method_0029_002c-port-specification-169">
				</a>
				<a name="index-port_002c-specifying-for-remote-repositories-170">
				</a>
				<a name="index-Password-server_002c-setting-up-171">
				</a>
				<a name="index-Authenticating-server_002c-setting-up-172">
				</a>
				<a name="index-inetd_002c-configuring-for-pserver-173">
				</a>
				<a name="index-xinetd_002c-configuring-for-pserver-174">
				</a>
				<!-- FIXME: this isn't quite right regarding port -->
				<!-- numbers; CVS looks up "cvspserver" in -->
				<!-- /etc/services (on unix, but what about non-unix?). -->在服务器端，需要编辑文件 <samp><span class="file"><font face="新宋体">/etc/inetd.conf</font></span></samp> 让 <code><font face="新宋体">inetd</font></code> 它在正确的端口上收到一个连接的时候运行 <code><font face="新宋体">cvs pserver</font></code> 命令。按照默认，端口号是 2401；当然，如果客户端用 <code><font face="新宋体">CVS_AUTH_PORT</font></code> 重新编译了就会有一些不同。也可以在 CVSROOT 变量(参阅 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Remote-repositories.html#Remote-repositories">Remote repositories</a>)指定或用 CVS_CLIENT_PORT 环境变量(参阅 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Environment-variables.html#Environment-variables">Environment variables</a>)跨越。 </p>
		<p>如果你的 <code><font face="新宋体">inetd</font></code> 在 <samp><span class="file"><font face="新宋体">/etc/inetd.conf</font></span></samp> 中允许原始的端口号定义，那么下面的命令就足够了（所有命令在 <samp><span class="file"><font face="新宋体">inetd.conf</font></span></samp> 中都是单行）： </p>
		<pre class="example">     2401  stream  tcp  nowait  root  /usr/local/bin/cvs
     cvs -f --allow-root=/usr/cvsroot pserver
</pre>
		<p class="noindent">（你也可以使用 `<samp><span class="samp"><font face="新宋体">-T</font></span></samp>' 选项来指定一个临时目录。） </p>
		<p>`<samp><span class="samp"><font face="新宋体">--allow-root</font></span></samp>' 选项指定一个允许的 <span class="sc">cvsroot</span> 目录。试图使用一个另外的 <span class="sc">cvsroot</span> 目录的客户将被拒绝连接。如果你希望设置多个允许的 <span class="sc">cvsroot</span> 目录，重复设置这一选项就行了。（不幸的是，许多版本的 <code><font face="新宋体">inetd</font></code> 对参数的数量和/或命令长度小有限制。通常解决方法是在 <code><font face="新宋体">inetd</font></code> 中运行一个 shell 脚本，然后在脚本中调用 <span class="sc">cvs</span> 所需的参数。） </p>
		<p>如果你希望 <code><font face="新宋体">inetd</font></code> 使用符号服务名称来代替原始端口号，那么把它放进 <samp><span class="file"><font face="新宋体">/etc/services</font></span></samp> 里： </p>
		<pre class="example">     cvspserver      2401/tcp
</pre>
		<p class="noindent">并且在 <samp><span class="file"><font face="新宋体">inetd.conf</font></span></samp> 中使用 <code><font face="新宋体">cvspserver</font></code> 代替 <code><font face="新宋体">2401</font></code>。 </p>
		<p>如果你的系统用 <code><font face="新宋体">xinetd</font></code> 替代 <code><font face="新宋体">inetd</font></code>，步骤有些不同。创建一个叫 <samp><span class="file"><font face="新宋体">/etc/xinetd.d/cvspserver</font></span></samp> 的文件，包含下列内容： </p>
		<pre class="example">     service cvspserver
     {
        port        = 2401
        socket_type = stream
        protocol    = tcp
        wait        = no
        user        = root
        passenv     = PATH
        server      = /usr/local/bin/cvs
        server_args = -f --allow-root=/usr/cvsroot pserver
     }
</pre>
		<p class="noindent">（如果已在 <samp><span class="file"><font face="新宋体">/etc/services</font></span></samp> 中定义 <code><font face="新宋体">cvspserver</font></code>，可以省略 <code><font face="新宋体">port</font></code> 这一行。） </p>
		<p>做了上面的修改之后，需要重新启动你的 <code><font face="新宋体">inetd</font></code>，或者采取其它可以使它重新读取初始化文件手段。 </p>
		<p>如果设置这有麻烦，参阅 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Connection.html#Connection">Connection</a>。 </p>
		<p>
				<a name="index-CVS-passwd-file-175">
				</a>
				<a name="index-passwd-_0028admin-file_0029-176">
				</a>因为客户端以明文存储和传输口令(几乎是—请见 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Password-authentication-security.html#Password-authentication-security">Password authentication security</a>)，通常使用了一个独立的 <span class="sc">cvs</span>CVS 口令文件，这样人们访问仓库的时候不会危及定期口令的安全。这个文件是 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT/passwd</font></span></samp> (参阅 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Intro-administrative-files.html#Intro-administrative-files">Intro administrative files</a>)。除了只用较少的域（<span class="sc">cvs</span> 用户名称，可有可无的口令和服务器的用户名称）以外，它的格式和 Unix 上的 <samp><span class="file"><font face="新宋体">/etc/passwd</font></span></samp> 相似，采用分号分隔。这里是个有五个表项的例子 <samp><span class="file"><font face="新宋体">passwd</font></span></samp> 文件： </p>
		<pre class="example">     anonymous:
     bach:ULtgRLXo7NRxs
     spwang:1sOp854gDF3DY
     melissa:tGX1fS8sun6rY:pubcvs
     qproj:XR4EZcEs0szik:pubcvs
</pre>
		<p class="noindent">（口令使用 Unix 标准的 <code><font face="新宋体">crypt()</font></code> 函数加密，因此它可以直接从常规 Unix <samp><span class="file"><font face="新宋体">/etc/passwd</font></span></samp> 文件粘贴过来。） </p>
		<p>例子中第一行允许任何 <span class="sc">cvs</span> 客户机使用 <code><font face="新宋体">anonymous</font></code> 来访问，口令可以用任意字符还可以用空口令。（这是一个站点允许匿名进行只读访问的典型用法；“只读（read-only）”部分信息的做法，参看 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Read_002donly-access.html#Read_002donly-access">Read-only access</a>。） </p>
		<p>如果他们提供各自的明文口令第二、三行允许对 <code><font face="新宋体">bach</font></code> 和 <code><font face="新宋体">spwang</font></code> 进行访问。 </p>
		<p>
				<a name="index-User-aliases-177">
				</a>如果她提供正确的口令第四行允许对 <code><font face="新宋体">melissa</font></code> 访问，但她的 <span class="sc">cvs</span> 操作将实际运行在服务器侧的 <code><font face="新宋体">pubcvs</font></code> 用户名下。虽然系统上不须有 <code><font face="新宋体">melissa</font></code> 用户名，但 <em>必须</em> 使用 <code><font face="新宋体">pubcvs</font></code>。 </p>
		<p>第五行显示系统用户标识可以共享：作为 <code><font face="新宋体">qproj</font></code> 成功认证的任何客户实际将按 <code><font face="新宋体">pubcvs</font></code> 来运行，和 <code><font face="新宋体">melissa</font></code> 所做的一样。用这种方法你可以在你的仓库中为每个项目创建一单个共享的系统用户，并且在 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT/passwd</font></span></samp> 文件中为每个开发者设置一行。每行的 <span class="sc">cvs</span> 用户名应该不同，而系统用户名应该相同。用不同的 <span class="sc">cvs</span> 用户名目的是在 <span class="sc">cvs</span> 将在其名字下记录其动作： 当 <code><font face="新宋体">melissa</font></code> 提交了项目中的一个修改，检入被纪录在项目历史中的 <code><font face="新宋体">melissa</font></code> 名下，而不是 <code><font face="新宋体">pubcvs</font></code> 下。而共享一个系统用户的原因是可以安排仓库中相关区域的权限，只有那个帐户有写权限。 </p>
		<p>如果系统用户域存在的时候，全部口令鉴定 <span class="sc">cvs</span> 命令按该用户运行；如果没有指定系统用户，<span class="sc">cvs</span> 简单地取 <span class="sc">cvs</span> 用户名作为系统用户名并且按此户名运行命令。无论哪种情况，如果系统上没有这样的用户，于是 <span class="sc">cvs</span> 操作会失败(不管客户机是否提供了正确的口令)。 </p>
		<p>口令和系统用户字段都可以省略（如果系统用户字段省略，那么与口令分隔的冒号也省略）。例如，这将是有效的 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT/passwd</font></span></samp> 文件： </p>
		<pre class="example">     anonymous::pubcvs
     fish:rKa5jzULzmhOo:kfogel
     sussman:1sOp854gDF3DY
</pre>
		<p class="noindent">当口令字段为空，客户的认证可以用包括空字符串在内的任何口令。但 <span class="sc">cvs</span> 用户名后的分隔冒号必需存在，即使口令为空。 </p>
		<p>
				<span class="sc">cvs</span> 还可借助于系统认证。认证口令的时候，服务器先检查 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT/passwd</font></span></samp> 文件中的用户。如果找到用户，就按上面说的方法使用该项进行认证。如果没有找到，或 <span class="sc">cvs</span><samp><span class="file"><font face="新宋体">passwd</font></span></samp> 文件不存在，服务器将采用操作系统的用户认证机制（这种机制可以通过设置 <span class="sc">cvs</span><samp><span class="file"><font face="新宋体">config</font></span></samp> 文件中的 <code><font face="新宋体">SystemAuth=no</font></code> 来禁止，参阅 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/config.html#config">config</a>）。 </p>
		<p>除非系统中有 PAM(Pluggable Authentication Modules)，或者 <span class="sc">cvs</span> 服务器端编译的时候配置 (使用 <code><font face="新宋体">./configure --enable-pam</font></code> - 参考 INSTALL 中的说明)，否则默认的回调(callback)是查找 <samp><span class="file"><font face="新宋体">/etc/passwd</font></span></samp> 中的口令。在此情况下，将磋商以 PAM 代替。这意味着可以配置 <span class="sc">cvs</span> 使用 PAM 提供的各种口令认证方式(可能是 UNIX password，NIS，LDAP，或其他)，这取决于 PAM 的全局配置文件(通常在 <samp><span class="file"><font face="新宋体">/etc/pam.conf</font></span></samp> 或可能是 <samp><span class="file"><font face="新宋体">/etc/pam.d/cvs</font></span></samp>)。详细配置 PAM 的方法请参考 PAM 的文档。 </p>
		<p>注意，PAM 是 <span class="sc">cvs</span> 中使用的实验特性，鼓励反馈信息。如果你使用了 PAM 支持，请发邮件到 <span class="sc">cvs</span> 的邮件列表(<code><font face="新宋体">info-cvs@gnu.org</font></code> 或 <code><font face="新宋体">bug-cvs@gnu.org</font></code>)。 </p>
		<p>
				<strong>警告：采用 PAM 可以给系统管理员更多的 </strong>
				<span class="sc">cvs</span>
				<strong>认证灵活性，但并不比别的方法有更高的安全性。详见下。</strong>
		</p>
		<p>CVS 在 PAM 配置文件里需要“auth”，“account”和“session”模块。因此典型的 PAM 配置是在文件 <samp><span class="file"><font face="新宋体">/etc/pam.conf</font></span></samp> 里模拟标准的 <span class="sc">cvs</span> 系统 <samp><span class="file"><font face="新宋体">/etc/passwd</font></span></samp> 认证： </p>
		<pre class="example">     cvs	auth	    required	pam_unix.so
     cvs	account	    required	pam_unix.so
     cvs	session	    required	pam_unix.so
</pre>
		<p>对等的 <samp><span class="file"><font face="新宋体">/etc/pam.d/cvs</font></span></samp> 文件里包括 </p>
		<pre class="example">     auth	    required	pam_unix.so
     account	    required	pam_unix.so
     session	    required	pam_unix.so
</pre>
		<p>一些系统要求给出模块的完整路径，因此 <samp><span class="file"><font face="新宋体">pam_unix.so</font></span></samp> (Linux) 改为类似 <samp><span class="file"><font face="新宋体">/usr/lib/security/$ISA/pam_unix.so.1</font></span></samp> (Sun Solaris)。参考 <span class="sc">cvs</span> 源码发布子目录 <samp><span class="file"><font face="新宋体">contrib/pam</font></span></samp> 中更多的配置例子。 </p>
		<p>PAM 中指出的服务名“cvs”是默认配置中的服务名，也可以在编译前使用 <code><font face="新宋体">./configure --with-hardcoded-pam-service-name=&amp;lt;pam-service-name&amp;gt;</font></code> 重新设置。 <span class="sc">cvs</span> 也可以被设置成调用其他的名字 <code><font face="新宋体">./configure --without-hardcoded-pam-service-name</font></code>，但这个特性只有你有权控制 <span class="sc">cvs</span> 用什么名字时才有效。 </p>
		<p>要知道，在使用系统认证时会有安全漏洞：<span class="sc">cvs</span> 操作时是使用系统中用户的正规注册口令，而该口令网络传输中是采用明码方式。见 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Password-authentication-security.html#Password-authentication-security">Password authentication security</a>。这点对使用 PAM 认证会有更多的问题，因为系统口令的源头是某些像 LDAP 的中心服务，而 LDAP 它还被用于认证别的服务。 </p>
		<p>另一方面，PAM 使得定期地修改口令非常容易。如果对全部活动给用户一个口令系统的选项，用户经常定期改变他们的口令。 </p>
		<p>在非 PAM 的配置中，口令是保存在 <samp><span class="file"><font face="新宋体">CVSROOT/passwd</font></span></samp> 文件里面，因为只有管理员用户(或有等同的权限)才有此文件的修改访问权限，所以想用定期改变口令会很困难。可以采用设计的网页程序或 set-uid 程序来更新文件，或者是提交请求让管理员进行手动修改来更新。第一种情况下，必须记住去定期更新各自的口令可能是很困难的。第二种情况下，手工的本性将是只有绝对必要时才会去修改口令。 </p>
		<p>注意，PAM 管理员应避免在 <span class="sc">cvs</span> 证明/授权(authentication/authorization)中采用配置一次性口令 OTP。如果用 OTP，管理员最好考虑其他的 Client/Server 访问方式。参阅 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/Remote-repositories.html#Remote-repositories">Remote repositories</a> 获得其他方法的列表。 </p>
		<p>现在，<span class="sc">cvs</span><samp><span class="file"><font face="新宋体">passwd</font></span></samp> 文件里加入口令的唯一方法是从别处粘贴而来。也许有一天，会有一条命令 <code><font face="新宋体">cvs passwd</font></code>。 </p>
		<p>不像其他在 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT</font></span></samp> 目录下的文件，可以在不是通过 <span class="sc">cvs</span>来编辑 <samp><span class="file"><font face="新宋体">passwd</font></span></samp> 的地方进行编辑。这是因为使 <samp><span class="file"><font face="新宋体">passwd</font></span></samp> 文件检出为人们的工作副本可能的安全风险。如果你的确需要将 <samp><span class="file"><font face="新宋体">$CVSROOT/CVSROOT</font></span></samp> 中的 <samp><span class="file"><font face="新宋体">passwd</font></span></samp> 检出，参看 <a href="http://man.chinaunix.net/develop/cvsdoc_zh/checkoutlist.html#checkoutlist">checkoutlist</a>。</p>
<img src ="http://www.blogjava.net/zhangrenquan/aggbug/53335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-06-16 16:38 <a href="http://www.blogjava.net/zhangrenquan/articles/53335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STV-深蓝卫星网络电视(直播世界杯) V3.80 Build 0428 注册码</title><link>http://www.blogjava.net/zhangrenquan/articles/48926.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Tue, 30 May 2006 04:14:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/48926.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/48926.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/48926.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/48926.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/48926.html</trackback:ping><description><![CDATA[STV-深蓝卫星网络电视(直播世界杯) V3.80 Build 0428（2006年04月28日发布）<br />http://www.stvcn.net/download/STV.exe<br /><br />注册名：<a href="http://www.cniso.org">www.cniso.org</a><br />注册码：個|vndYJ9-XQRJ@4-WSUG@5-XSOI@2<img src ="http://www.blogjava.net/zhangrenquan/aggbug/48926.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-05-30 12:14 <a href="http://www.blogjava.net/zhangrenquan/articles/48926.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ANT十五大最佳实践 (摘录)</title><link>http://www.blogjava.net/zhangrenquan/articles/42394.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Fri, 21 Apr 2006 10:35:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/42394.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/42394.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/42394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/42394.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/42394.html</trackback:ping><description><![CDATA[
		<p>Ant出现之前，构建和部署Java应用需要使用包括特定平台的脚本、Make文件、各种版本的IDE甚至手工操作的“大杂烩”。现在，几乎所有的开源Java项目都在使用Ant，大多数公司的内部项目也在使用Ant。Ant在这些项目中的广泛使用自然导致了读者对一整套Ant最佳实践的迫切需求。 
</p>
		<p>本文总结了我喜爱的Ant技巧或最佳实践，多数是从我亲身经历的项目错误或我听说的其他人经历的 “恐怖”故事中得到灵感的。比如，有人告诉我有个项目把XDoclet 生成的代码放入带有锁定文件功能的版本控制工具中。当开发者修改源代码时，他必须记住手工检出（Check out）并锁定所有将要重新生成的文件。然后，手工运行代码生成器，只到这时他才能够让Ant编译代码，这一方法还存在如下一些问题：</p>
		<ul>
				<li>生成的代码无法存储在版本控制系统中。 
</li>
				<li>Ant（本案例中是Xdoclet）应该自动确定下一次构建涉及的源文件，而不应由程序员手工确定。 
</li>
				<li>Ant的构建文件应该定义好正确的任务依赖关系，这样程序员就不必为了完成构建而不得不按照特定顺序调用任务。 </li>
		</ul>
		<p>当我开始一个新项目时，我首先编写Ant构建文件。Ant文件明确地定义构建的过程，并被团队中的每个程序员使用。本文所列的技巧基于这样的假定：Ant构建文件是一个必须仔细编写的重要文件，它应在版本控制系统中得到维护，并被定期进行重构。下面是我的十五大Ant最佳实践。</p>
		<h3>1. 采用一致的编码规范</h3>
		<p>Ant用户有的喜欢有的痛恨其构建文件的XML语法。与其跳进这一令人迷惑的争论中，不如让我们先看一些能保持XML构建文件简洁的方法。</p>
		<p>首先也是最重要的，花费时间格式化你的XML让它看上去很清晰。不论XML是否美观，Ant都可以工作。但是丑陋的XML很难令人读懂。倘若你在任务之间留出空行，有规则的缩进，每行文字不超过90列左右，那么XML令人惊讶地易读。再加上使用能够高亮XML语法的优秀编辑器或IDE工具，你就不会有阅读的麻烦。</p>
		<p>同样，精选含意明确、容易读懂的词汇来命名任务和属性。比如，<em>dir.reports</em>就比<em>rpts</em>好<em>。</em>特定的编码规范并不重要，只要拿出一套规范并坚持使用就行。</p>
		<h3>2. 将<em>build.xml</em>放在项目根目录中</h3>
		<p>Ant构建文件<em>build.xml</em>可以放在任何位置，但是放在项目顶级目录中可以保持项目简洁。这是最常用的规范，开发者能够在顶级目录中找到预期的<em>build.xml</em>。把构建文件放在根目录中，也能够使人容易了解项目目录树中不同目录之间的逻辑关系。以下是一个典型的项目目录层次：</p>
		<p>[root dir]<br />  | build.xml  <br />  +--src <br />  +--lib (包含第三方 JAR包) <br />  +--build (由 build任务生成)  <br />  +--dist (由 build任务生成) </p>
		<p>当<em>build.xml</em>在顶级目录时，假设你处于项目某个子目录中，只要输入：ant -find compile 命令，不需要改变工作目录就能够以命令行方式编译代码。参数-find告诉Ant寻找存在于上级目录中的<em>build.xml</em>并执行。</p>
		<h3>3. 使用单一的构建文件</h3>
		<p>有人喜欢将一个大项目分解成几个小的构建文件，每个构建文件分担整个构建过程的一小部分工作。这确实是看法不同的问题，但是应该认识到，将构建文件分割会增加对整体构建过程的理解难度。要注意在单一构建文件能够清楚表现构建层次的情况下不要过工程化(over-engineer)。</p>
		<p>即使你把项目划分为多个构建文件，也应使程序员能够在项目根目录下找到核心<em>build.xml</em>。尽管该文件只是将实际构建工作委派给下级构建文件，也应保证该文件可用。</p>
		<h3>4. 提供良好的帮助说明</h3>
		<p>应尽量使构建文件自文档化。增加任务描述是最简单的方法。当你输入ant -projecthelp时，你就可以看到带有描述的任务清单。比如，你可以这样定义任务：</p>&lt;target name="compile"  <br />   description="Compiles code, output goes to the build dir."&gt; 
<p>最简单的规则是把所有你想让程序员通过命令行就可以调用的任务都加上描述。对于一般用来执行中间处理过程的内部任务，比如生成代码或建立输出目录等，就无法使用描述属性。</p><p>这时，可以通过在构建文件中加入XML注释来处理。或者专门定义一个help任务，当程序员输入ant help时来显示详细的使用说明。</p>&lt;target name="help" description="Display detailed usage information"&gt;<br />  &lt;echo&gt;Detailed help...&lt;/echo&gt;&lt;/target&gt; 
<h3>5. 提供清除任务</h3><p>每个构建文件都应包含一个清除任务，用来删除所有生成的文件和目录，使系统回到构建文件执行前的初始状态。执行清空任务后还存在的文件都应处在版本控制系统的管理之下。比如：</p>&lt;target name="clean" <br />    description="Destroys all generated files and dirs."&gt;<br />  &lt;delete dir="${dir.build}"/&gt;<br />  &lt;delete dir="${dir.dist}"/&gt;<br />&lt;/target&gt; 
<p>除非是在产生整个系统版本的特殊任务中，否则不要自动调用clean任务。当程序员仅仅执行编译任务或其他任务时，他们不需要构建文件事先执行既令人讨厌又没有必要的清空任务。要相信程序员能够确定何时需要清空所有文件。</p><h3>6. 使用ANT管理任务从属关系</h3><p>假设你的应用由Swing GUI组件、Web界面、EJB层和公共应用代码组成。在大型系统中，你需要清晰地定义每个Java包属于系统的哪一层。否则任何一点修改都要被迫重新编译成百上千个文件。糟糕的任务从属关系管理会导致过度复杂而脆弱的系统。改变GUI面板的设计不应造成Servlet和EJB的重编译。</p><p>当系统变得庞大后，稍不注意就可能将依赖于客户端的代码引入到服务端。这是因为典型的IDE项目文件编译任何文件都使用单一的classpath。而Ant能让你更有效地控制构建活动。</p><p>设计你的Ant构建文件编译大型项目的步骤：首先，编译公共应用代码，将编译结果打成JAR包文件。然后，编译上一层的项目代码，编译时依靠第一步产生的JAR文件。不断重复这一过程，直到最高层的代码编译完成。</p><p>分步构建强化了任务从属关系管理。如果你工作在底层Java框架上，偶然引用到高层的GUI模板组件，这时代码不需要编译。这是由于构建文件在编译底层框架时在源路径中没有包含高层GUI面板组件的代码。</p><h3>7. 定义并重用文件路径</h3><p>如果文件路径在一个地方一次性集中定义，并在整个构建文件中得到重用，那么构建文件更易于理解。以下是这样做的一个例子：</p>&lt;project name="sample" default="compile" basedir="."&gt;<br />  &lt;path id="classpath.common"&gt;<br />    &lt;pathelement location="${jdom.jar.withpath}"/&gt;<br />    ...etc  &lt;/path&gt;<br />  &lt;path id="classpath.client"&gt;<br />    &lt;pathelement location="${guistuff.jar.withpath}"/&gt;<br />    &lt;pathelement location="${another.jar.withpath}"/&gt;<br />    &lt;!-- reuse the common classpath --&gt;<br />    &lt;path refid="classpath.common"/&gt;<br />  &lt;/path&gt;<br />  &lt;target name="compile.common" depends="prepare"&gt;<br />    &lt;javac destdir="${dir.build}" srcdir="${dir.src}"&gt;<br />          &lt;classpath refid="classpath.common"/&gt;<br />          &lt;include name="com/oreilly/common/**"/&gt;<br />    &lt;/javac&gt;<br />  &lt;/target&gt;<br />&lt;/project&gt; 
<p>当项目不断增长构建日益复杂时，这一技术越发体现出其价值。你可能需要为编译不同层次的应用定义各自的文件路径，比如运行单元测试的、运行应用程序的、运行Xdoclet的、生成JavaDocs的等等不同路径。这种组件化路径定义的方法比为每个任务单独定义路径要优越得多。否则，很容易丢失任务从属关系的轨迹。</p><h3>8. 定义恰当的任务从属关系</h3><p>假设dist任务从属于jar任务，那么哪个任务从属于compile任务哪个任务从属于prepare任务呢？Ant构建文件最终定义了任务的从属关系图，它必须被仔细地定义和维护。</p><p>应该定期检查任务的从属关系以保证构建工作得到正确执行。大的构建文件随着时间推移趋向于增加更多的任务，所以到最后可能由于不必要的从属关系导致构建工作非常困难。比如，你可能发现在程序员只需编译一些没有使用EJB的GUI代码时又重新生成了EJB代码。</p><p>以“优化”的名义忽略任务的从属关系是另一种常见的错误。这种错误迫使程序员为了得到恰当的结果必须记住并按照特定的顺序调用一串任务。更好的做法是：提供描述清晰的公共任务，这些任务包含正确的任务从属关系；另外提供一套“专家”任务让你能够手工执行个别的构建步骤，这些任务不提供完整的构建过程，但是让那些专家用户在快速而恼人的编码期间能够跳过某些步骤。</p><h3>9.使用属性</h3><p>任何需要配置或可能发生变化的信息都应作为Ant属性定义下来。对于在构建文件中多次出现的值也同样处理。属性既可以在构建文件头部定义，也可以为了更好的灵活性而在单独的属性文件中定义。以下是在构建文件中定义属性的样式：</p>&lt;project name="sample" default="compile" basedir="."&gt;<br />  &lt;property name="dir.build" value="build"/&gt;<br />  &lt;property name="dir.src" value="src"/&gt;<br />  &lt;property name="jdom.home" value="../java-tools/jdom-b8"/&gt;<br />  &lt;property name="jdom.jar" value="jdom.jar"/&gt;<br />  &lt;property name="jdom.jar.withpath"<br />                    value="${jdom.home}/build/${jdom.jar}"/&gt;<br />    etc...<br />&lt;/project&gt; 
<p>或者你可以使用属性文件：</p>&lt;project name="sample" default="compile" basedir="."&gt;<br />  &lt;property file="sample.properties"/&gt;<br />   etc...<br />&lt;/project&gt; 
<p>在属性文件 <em>sample.properties</em>中:</p>dir.build=build<br />dir.src=src<br />jdom.home=../java-tools/jdom-b8<br />jdom.jar=jdom.jarjdom.jar.withpath=${jdom.home}/build/${jdom.jar} 
<p>用一个独立的文件定义属性是有好处的，它可以清晰地定义构建中的可配置部分。另外，在开发者工作在不同操作系统的情况下，你可以在不同的平台上提供该文件的不同版本。</p><h3>10. 保持构建过程独立</h3><p>为了最大限度的扩展性，不要应用外部路径和库文件。最重要的是不要依赖于程序员的CLASSPATH设置。取而代之的是，在构建文件中使用相对路径并定义自己的路径。如果你引用了绝对路径如<em>C:\java\tools</em>，其他开发者未必使用与你相同的目录结构，所以就无法使用你的构建文件。</p><p>如果你部署开放源码项目，应该提供包含编译代码所需的所有JAR文件的发行版本。当然，这是在遵守许可协议的基础上。对于内部项目，相关的JAR文件都应在版本控制系统的管理中，并捡出（check out）到大家都知道的位置。</p><p>当你必须引用外部路径时，应将路径定义为属性。使程序员能够用适合他们自己的机器环境的参数重载这些属性。你也可以使用以下语法引用环境变量：</p>&lt;property environment="env"/&gt;<br />&lt;property name="dir.jboss" value="${env.JBOSS_HOME}"/&gt; 
<h3>11. 使用版本控制系统</h3><p>构建文件是一个重要的制品，应该像代码一样进行版本控制。当你标记你的代码时，也应用同样的标签标记构建文件。这样当你需要回溯到旧版本并进行构建时，能够使用相应版本的构建文件。</p><p>除构建文件之外，你还应在版本控制中维护第三方JAR文件。同样，这使你能够重新构建旧版本的软件。这也能够更容易保证所有开发者拥有一致的JAR文件，因为他们都是同构建文件一起从版本控制系统中捡出的。</p><p>通常应避免在版本控制系统中存放构建成果。倘若你的源代码很好地得到了版本控制，那么通过构建过程你能够重新生成任何版本的产品。</p><h3>12. 把Ant作为“最小公分母”</h3><p>假设你的开发团队使用IDE工具，当程序员通过点击图标就能够构建整个应用时为什么还要为Ant而烦恼呢？</p><p>IDE的问题是一个关于团队一致性和重现性的问题。几乎所有的IDE设计初衷都是为了提高程序员的个人生产率，而不是开发团队的持续构建。典型的IDE要求每个程序员定义自己的项目文件。程序员可能拥有不同的目录结构，可能使用不同版本的库文件，还可能工作在不同的平台上。这将导致出现这种情况：在Bob那里运行良好的代码，到Sally那里就无法运行。</p><p>不管你的开发团队使用何种IDE，一定要建立所有程序员都能够使用的Ant构建文件。要建立一个程序员在将新代码提交版本控制系统前必须执行Ant构建文件的规则。这将确保代码是经过同一个Ant构建文件构建的。当出现问题时，要使用项目标准的Ant构建文件，而不是通过某个IDE来执行一个干净的构建。</p><p>程序员可以自由选择任何他们习惯使用的IDE工具或编辑器。但是Ant应作为公共基线以保证代码永远是可构建的。</p><h3>13. 使用zipfileset属性</h3><p>人们经常使用Ant产生WAR、JAR、ZIP和 EAR文件。这些文件通常都要求有一个特定的内部目录结构，但其往往与你的源代码和编译环境的目录结构不匹配。</p><p>一个最常用的方法是写一个Ant任务，按照期望的目录结构把一大堆文件拷贝到临时目录中，然后生成压缩文件。这不是最有效的方法。使用zipfileset属性是更好的解决方案。它让你从任何位置选择文件，然后把它们按照不同目录结构放进压缩文件中。以下是一个例子：</p>&lt;ear earfile="${dir.dist.server}/payroll.ear"<br />    appxml="${dir.resources}/application.xml"&gt;<br />  &lt;fileset dir="${dir.build}" includes="commonServer.jar"/&gt;<br />  &lt;fileset dir="${dir.build}"&gt;<br />    &lt;include name="payroll-ejb.jar"/&gt;<br />  &lt;/fileset&gt;<br />  &lt;zipfileset dir="${dir.build}" prefix="lib"&gt;<br />    &lt;include name="hr.jar"/&gt;<br />    &lt;include name="billing.jar"/&gt;<br />  &lt;/zipfileset&gt;<br />  &lt;fileset dir="."&gt;<br />    &lt;include name="lib/jdom.jar"/&gt;<br />    &lt;include name="lib/log4j.jar"/&gt;<br />    &lt;include name="lib/ojdbc14.jar"/&gt;<br />  &lt;/fileset&gt;<br />  &lt;zipfileset dir="${dir.generated.src}" prefix="META-INF"&gt;<br />    &lt;include name="jboss-app.xml"/&gt;<br />  &lt;/zipfileset&gt;<br />&lt;/ear&gt; 
<p>在这个例子中，所有JAR文件都放在EAR文件包的<em>lib</em>目录中。hr.jar和billing.jar是从构建目录拷贝过来的。因此我们使用zipfileset属性把它们移动到EAR文件包内部的<em>lib</em>目录。prefix属性指定了其在EAR文件中的目标路径。</p><h3>14. 测试Clean任务</h3><p>假设你的构建文件中有clean和compile的任务，执行以下的测试。第一步，执行ant clean；第二步，执行ant compile；第三步，再执行ant compile。第三步应该不作任何事情。如果文件再次被编译，说明你的构建文件有问题。</p><p>构建文件应该只在与输出文件相关联的输入文件发生变化时执行任务。一个构建文件在不必执行诸如编译、拷贝或其他工作任务的时候执行这些任务是低效的。当项目规模增长时，即使是小的低效工作也会成为大的问题。</p><h3>15. 避免特定平台的Ant封装</h3><p>不管什么原因，有人喜欢用简单的、名称叫做<em>compile</em>之类的批文件或脚本装载他们的产品。当你去看脚本的内容你会发现以下内容：</p><p>ant compile</p><p>其实开发人员都很熟悉Ant，并且完全能够自己键入ant compile。请不要仅仅为了调用Ant而使用特定平台的脚本。这只会使其他人在首次使用你的脚本时增加学习和理解的烦扰。除此之外，你不可能提供适用于每个操作系统的脚本，这是真正烦扰其他用户的地方。</p><h3>总结</h3><p>太多的公司依靠手工方法和特别程序来编译代码和生成软件发布版本。那些不使用Ant或类似工具定义构建过程的开发团队，花费了太多的时间来捕捉代码编译过程中出现的问题：在某些开发者那里编译成功的代码，到另一些开发者那里却失败了。</p><p>生成并维护构建脚本不是一项富有魅力的工作，但却是一项必需的工作。一个好的Ant构建文件将使你能够集中到更喜欢的工作——写代码中去！</p><img src ="http://www.blogjava.net/zhangrenquan/aggbug/42394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-04-21 18:35 <a href="http://www.blogjava.net/zhangrenquan/articles/42394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Tomcat5的数据库连接池配置</title><link>http://www.blogjava.net/zhangrenquan/articles/39378.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Wed, 05 Apr 2006 06:08:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/39378.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/39378.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/39378.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/39378.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/39378.html</trackback:ping><description><![CDATA[本文主要介绍Tomcat5.0.25这个版本下数据库连接池的配置，及程序对连接池的JNDI查找，并提供相应测试代码。最后指出配置及应用过程中的常见问题及解决方法。<br /><br />1 .该文的配置环境：Tomcat5.0.25 + jdk1.4+ Sql Server 2000+Win2000<br /><br />2.配置步骤：<br /><br />第一步：<br /><br />启动Tomcat，打开IE在地址栏内输入<a href="http://localhost:8080/admin"><font color="#002c99">http://localhost:8080/admin</font></a>  进入Tomcat的管理界面；点击右边的Data Sources 在右上角的下拉菜单中选择Create New Data Source 在下边的输入框中输入需要的配置信息。<br /><br />JNDI Name:jdbc/XXX（XXX为自己所命的名字）<br /><br />Data Source URL：jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=tempdb（连接的数据名）<br /><br />JDBC Driver Class: com.microsoft.jdbc.sqlserver.SQLServerDriver<br /><br />User Name:连接数据库的用户名 <br /><br />Password: 数据库密码<br /><br />Max. Active Connections: 最大连接数<br /><br />Max. Idle Connections: 是最大的空闲连接数<br /><br />Max. Wait for Connection: 最大等待连接数<br /><br /> <br /><br />第二步：配置web.xml<br />打开webapps/ROOT/WEB-INF下web.xml，加入如下内容：   <br />&lt;resource-ref&gt;<br />  &lt;description&gt;SqlServer Datasource example&lt;/description&gt;<br />  &lt;res-ref-name&gt;jdbc/SqlServerDB&lt;/res-ref-name&gt;<br />  &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />  &lt;res-auth&gt;Container&lt;/res-auth&gt;<br />  &lt;/resource-ref&gt;<br /><br />第三步：配置tomcat（添加类）<br /><br />首先要下载安装sqlserver-jdbc-驱动，然后将其lib下的三个jar文件放到<br /><br />tomcat/common/lib下。<br /><br /> <br /><br />注意事项：<br /><br />如果是单个JSP页面我们将它放在TOMCAT_HOME/webapps/ROOT下边，同时还须修改TOMCAT_HOME/conf/Catalina/localhost/下的ROOT.xml文件，在<br /><br />&lt;Resource auth="Container" description="SqlServer Datasource example" name="jdbc/SqlServerDB" type="javax.sql.DataSource"/&gt;下边加入：<br /><br />&lt;ResourceLink global="jdbc/test" name="jdbc/test" type="javax.sql.DataSource"/&gt;<br /><br />来引用所配置的JNDI数据源。同时将&lt;Resource auth="Container" description="SqlServer Datasource example" name="jdbc/SqlServerDB" type="javax.sql.DataSource"/&gt;注释掉<br /><br />    如果我们要部署的是个WEB应用程序，我们将该应用程序放在TOMCAT_HOME/webapps目录下，有两种方式可以引用我们所配置的JNDI数据源。<br /><br />A:可以在TOMCAT_HOME/conf/Catalina/localhost下新建XXX.xml文件，XXX为所发布的WEB应用的名字，如我所发布的WEB应用是JndiTest，.xml文件命名为JndiTest.xml在该文件内加：<br /><br />&lt;?xml version='1.0' encoding='utf-8'?&gt;<br /><br />&lt;Context debug="1" docBase="E:/Tomcat 5.0/webapps/JndiTest" path="/JndiTest" reloadable="true" workDir="work\Catalina\localhost\JndiTest"&gt;<br /><br />  &lt;Resource name="jdbc/test" type="javax.sql.DataSource"/&gt;<br /><br />  &lt;ResourceParams name="jdbc/test"&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;factory&lt;/name&gt;<br /><br />      &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;password&lt;/name&gt;<br /><br />      &lt;value&gt;jsjrj&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;maxActive&lt;/name&gt;<br /><br />      &lt;value&gt;4&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;maxWait&lt;/name&gt;<br /><br />      &lt;value&gt;5000&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;url&lt;/name&gt;<br /><br />      &lt;value&gt;jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=tempdb&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;driverClassName&lt;/name&gt;<br /><br />      &lt;value&gt;com.microsoft.jdbc.sqlserver.SQLServerDriver&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;username&lt;/name&gt;<br /><br />      &lt;value&gt;sa&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />    &lt;parameter&gt;<br /><br />      &lt;name&gt;maxIdle&lt;/name&gt;<br /><br />      &lt;value&gt;2&lt;/value&gt;<br /><br />    &lt;/parameter&gt;<br /><br />  &lt;/ResourceParams&gt;<br /><br />&lt;/Context&gt;<br /><br />其中E:/Tomcat 5.0/webapps/JndiTest为你所发布应用程序的目录，这样就可以进行测试了。<br /><br />这样做就是每个WEB应用程序都须创建一个象JndiTest.xml这样的文件。<br /><br />B;为了避免每个WEB应用程序都创建XXX.xml文件，我们可以修改TOMCAT_HOME/conf下的server.xml文件，修改如下：<br /><br />在&lt;Host&gt;&lt;/Host&gt;之间加入：<br /><br />&lt;Context path="/JndiTest" docBase="E:/Tomcat 5.0/webapps/JndiTest" debug="1" reloadable="true"&gt;<br /><br />    &lt;Resource name="jdbc/test" type="javax.sql.DataSource"/&gt;<br /><br />    &lt;ResourceParams name="jdbc/test"&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;url&lt;/name&gt;<br /><br />        &lt;value&gt;jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=tempdb&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;driverClassName&lt;/name&gt;<br /><br />        &lt;value&gt;com.microsoft.jdbc.sqlserver.SQLServerDriver&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;maxWait&lt;/name&gt;<br /><br />        &lt;value&gt;5000&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;maxActive&lt;/name&gt;<br /><br />        &lt;value&gt;4&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;password&lt;/name&gt;<br /><br />        &lt;value&gt;jsjrj&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;maxIdle&lt;/name&gt;<br /><br />        &lt;value&gt;2&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;username&lt;/name&gt;<br /><br />        &lt;value&gt;sa&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt; <br /><br />        &lt;name&gt;factory&lt;/name&gt; <br /><br />        &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt; <br /><br />      &lt;/parameter&gt; <br /><br />    &lt;/ResourceParams&gt;<br /><br />   &lt;/Context&gt;<br /><br />&lt;Resource auth="Container" description="User database that can be updated and saved" name="UserDatabase" type="org.apache.catalina.UserDatabase"/&gt;下的<br /><br />&lt;Resource name="jdbc/test" type="javax.sql.DataSource"/&gt;<br /><br />同时移去上边的这段：（也可以不移去）&lt;ResourceParams name="jdbc/test"&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;url&lt;/name&gt;<br /><br />        &lt;value&gt;jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=tempdb&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;driverClassName&lt;/name&gt;<br /><br />        &lt;value&gt;com.microsoft.jdbc.sqlserver.SQLServerDriver&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;maxWait&lt;/name&gt;<br /><br />        &lt;value&gt;5000&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;maxActive&lt;/name&gt;<br /><br />        &lt;value&gt;4&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;password&lt;/name&gt;<br /><br />        &lt;value&gt;jsjrj&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;maxIdle&lt;/name&gt;<br /><br />        &lt;value&gt;2&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt;<br /><br />        &lt;name&gt;username&lt;/name&gt;<br /><br />        &lt;value&gt;sa&lt;/value&gt;<br /><br />      &lt;/parameter&gt;<br /><br />      &lt;parameter&gt; <br /><br />        &lt;name&gt;factory&lt;/name&gt; <br /><br />        &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt; <br /><br />      &lt;/parameter&gt; <br /><br />&lt;/ResourceParams&gt;<br /><br />注意要在每个WEB应用程序的web.xml文件中都加入<br /><br />&lt;resource-ref&gt;<br />  &lt;description&gt;SqlServer Datasource example&lt;/description&gt;<br />  &lt;res-ref-name&gt;jdbc/SqlServerDB&lt;/res-ref-name&gt;<br />  &lt;res-type&gt;javax.sql.DataSource&lt;/res-type&gt;<br />  &lt;res-auth&gt;Container&lt;/res-auth&gt;<br />  &lt;/resource-ref&gt;<br /><br />3．测试<br /><br />编写jsp文件：<br /><br />&lt;%@ page contentType="text/html;charset=gb2312"%&gt; <br /><br />&lt;%@ page import="java.sql.*"%&gt;<br /><br />&lt;%@ page import="javax.sql.*"%&gt;  <br /><br />&lt;%@ page import="javax.naming.*"%&gt;  <br /><br />&lt;html&gt; <br /><br />&lt;body&gt; <br /><br />&lt;%<br /><br /> <br /><br />Context ctx = new InitialContext();<br /><br />Connection conn=null;<br /><br />          ctx = new InitialContext();<br /><br />          DataSource ds =(DataSource)ctx.lookup("java:comp/env/jdbc/test");<br /><br />          conn = ds.getConnection();<br /><br />Statement stmt=conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE); <br /><br />String sql="select * from T_Student"; <br /><br />ResultSet rs=stmt.executeQuery(sql); <br /><br />while(rs.next()) {%&gt;<br /><br />&lt;% <br /><br />out.print(rs.getString(1));<br /><br />out.print(rs.getString(2));<br /><br />out.print(rs.getString(3));<br /><br />}%&gt; <br /><br />&lt;% <br /><br />out.print("数据库操作成功，恭喜你");<br /><br />rs.close(); <br /><br />stmt.close(); <br /><br />conn.close(); <br /><br />%&gt; <br /><br />&lt;/body&gt; <br /><br />&lt;/html&gt;<br /><img src ="http://www.blogjava.net/zhangrenquan/aggbug/39378.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-04-05 14:08 <a href="http://www.blogjava.net/zhangrenquan/articles/39378.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JSTL改进JSP来简化网页的实现过程</title><link>http://www.blogjava.net/zhangrenquan/articles/27357.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Tue, 10 Jan 2006 04:07:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/27357.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/27357.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/27357.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/27357.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/27357.html</trackback:ping><description><![CDATA[<P>[摘录]:http://www.javafan.net/article/20051229115558915.html<BR><BR><STRONG><FONT color=#330099>概述</FONT></STRONG> <BR>　　Java Server Pages (JSP) 标准标记库 (JSTL)的版本的发布对于JSP/servlet开发者来说是一个重大的进展。有了一个表达语言（EL）和一组四种强大的、易于学习的标准标记库，JSTL极有可能不久后成为实现动态的、基于Java的站点的主要方法。 <BR>　　1996年对JSP servlet的介绍使得Java成为动态网页开发的合理的选择。随后出现的Java服务器页(JSP)是走向快速的、可维护的Java网页实现过程的合理进化的一步，紧接着就出现了JSP标记的支持。但是2002中期的JSTL(JSP标准标记库)的发布才是进一步加速和简化开发过程最大的一步。 <BR>　　在本文中，我解释了JSTL的功能，也涵盖了你启动JSTL所需的每件事情。假设你有了对Java、JSP、XML和安装一个Web容器的基本理解。如果你对这些主题感到陌生，你可以在Resources（<A href="http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resourcesresources" target=_blank>http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resourcesresources</A>）上浏览一下背景参考。在下面的阐述中，假定你有XML和SQL的知识。 <BR><B><FONT color=#330099>　　安装JSTL支持</FONT></B> <BR>　　对于我们的JSTL安装例子来说，我们使用Tomcat 4.1（尽管任意支持Servlet 2.3和JSP1.2说明的servlet容器都应该能工作）。首先，下载Tomcat 4.1并且按指示进行安装（注意：JSTL需要一个JSP1.2 Web容器）。 <BR><BR>　　用tomcat4 start程序启动Tomcat，并且运行index.html页来确保Tomcat是激活的、且运行良好。 <BR><BR>　　接下来，安装JSTL支持，你可以从Jakarta站点下载JSTL支持，（<A href="http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resourcesresources" target=_blank>http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resourcesresources</A>）并按照下面步骤： <BR><BR>　　1.从Jakarta站点下载JSTL检索、解压/脱档该文件。（<A href="http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resources" target=_blank>http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl.html?#resources</A>） <BR><BR>　　2.复制你已经解压为common/lib的jar文件到你的Tomcat安装路径中（尽管我们的项目不需要所有的jar文件）；这使得JSTL文件适用于你的任意Web应用。 <BR><BR>　　3.对于任意你想使用JSTL的Web应用来说，复制.tld文件到你的Web应用的WEB-INF目录下。 <BR><BR>　　4.对于你的JSTL的Web应用，编辑web.xml并添加下列输入： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;taglib&gt;
  &lt;taglib-uri&gt;http://java.sun.com/jstl/fmt&lt;/taglib-uri&gt;
  &lt;taglib-location&gt;/WEB-INF/fmt.tld&lt;/taglib-location&gt;
  &lt;/taglib&gt;
  &lt;taglib&gt;
   &lt;taglib-uri&gt;http://java.sun.com/jstl/core&lt;/taglib-uri&gt;
   &lt;taglib-location&gt;/WEB-INF/c.tld&lt;/taglib-location&gt;
  &lt;/taglib&gt;
  &lt;taglib&gt;
   &lt;taglib-uri&gt;http://java.sun.com/jstl/sql&lt;/taglib-uri&gt;
   &lt;taglib-location&gt;/WEB-INF/sql.tld&lt;/taglib-location&gt;
  &lt;/taglib&gt;
  &lt;taglib&gt;
   &lt;taglib-uri&gt;http://java.sun.com/jstl/x&lt;/taglib-uri&gt;
   &lt;taglib-location&gt;/WEB-INF/x.tld&lt;/taglib-location&gt;
  &lt;/taglib&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　这些输入让你的Web应用可使用JSTL标记库的表达语言（EL）版本。这些输入的位置有关系！如果你不肯定将他们输入到何处，关于web.xml选项和顺序的权威性指导在文档类型定义（DTD）中定义过：<A href="http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">http://java.sun.com/j2ee/dtds/web-app_2_2.dtd</A>。 <BR><BR>　　5.当你创建了一个使用JSTL的JSP页时，将他输入到你的Web应用的主目录下，就像其它JSP和HTML页一样。你可以为该页任意取名，但是它必须有一个.jsp的扩展名。 <BR><BR><B><FONT color=#330099>　　基础原理</FONT></B> <BR>　　首先，所有的JSTL也是JSP页，JSTL只是JSP功能的一个超集。 <BR><BR>　　同样，所有的JSTL标记是有效的XML。这意味着：如果你将JSTL标记之外的内容当作临时文本（通常是HTML）时，剩下的JSTL标记必须当作合法的XML来解释。这里有一些隐含的规则，它要求大部分XML语法都是正确的。 <BR><BR>　　JSTL提供一组四个标准标记库（core核心、internationalization/format国际标准化/格式、XML和SQL）并支持EL。JSTL和EL的基本设计目的是简化网页开发和实现。 <BR><BR>　　在本文中，我们遵循JSTL说明书的命名规则，并且把JSTL标记当作动作。一个JSTL标记对应于某个动作；调用动作明确的提醒我们：他们添加动态行为到一个另外的静态页上。 <BR><BR>　　JSTL标记库有两个版本：一个用你以前使用的方法将JSP表达式插入，如&lt;%= . . . %&gt;，另一个使用一个JSTL EL.我会在后面进一步讨论在JSTL中的EL支持。 <BR><BR><B><FONT color=#330099>　　EL支持</FONT></B> <BR>　　要理解当前JSTL对EL支持的状态，让我们检查相关的说明书是怎样处理的。Java说明书请求（JSR）专家组成员决定：由于某种原因，EL规范说明应该是JSP说明书的一部份，而不是JSTL说明书的一部分。EL完整的说明书成为JSP2.0的一部分。因为JSTL1.0在JSP1.3之前已经完成，JSTL作者不得不对用于JSTL1.0的EL支持实现做一个合理的猜测（结果可能是相当好的）。一个JSTL维护版本将与JSP1.3说明书保持一致，并为了使EL适合JSP1.3说明书，JSTL维护版本做了一些修正。 <BR><BR>　　本文描述的EL概要可能在即将发布的JSTL版本中有一点改动，但是任何改动都是微小的。 <BR><BR>　　EL用于简单的语法定义了一套功能强大的语言，它很容易学习。它融合着JavaScript语言和Perl语言较好的部分的一些风格。EL表达式，集成了来自四种标准标记库的JSTL标记，提供了一个巨大的、灵活的属性集。 <BR><BR>　　所有的EL表达式都被${}括起来。JSTL中的表达式总是JSTL标记中的属性值的一部分。表达式可以是属性的一部分或者合并和嵌入到一个字符串直接量中。JSTL属性也可以包含简单的字符串直接量。在接下来的JSTL中，我们在一个来自核心库的c:out动作中说明每种情况，这个核心库将它的value属性值送到JSP输出上： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:out value="${anExpression}"/&gt;
&lt;c:out value="literalText${anExpression}${anotherExpression}"/&gt;
&lt;c:out value="literalText"/&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　EL也定义了一套规则用于强制表达式中的值转换为上下文相对应的类型。我们在这里不详细讨论这些规则；然而，它的方法与用Perl语言定义的方式非常相似（就像Perl语言中的做法一样，该方法理所当然的运行良好，但是，偶尔，也会出现可能不是你十分想要的那种结果，但你可以接受）。 <BR><BR>　　EL为访问对象属性、集合元素、一组隐藏对象以及使用相关的、逻辑的和算术的操作符提供了支持。对于索引的属性来说，包括数组和java.util.List类在内，元素可用下列语法访问： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>${alist[4]}
${aList[someVariable]}</PRE></TD></TR></TBODY></TABLE><BR>　　JavaBean属性和java.util.Map元素（它代表一系列名字/值对）都可以使用下列方法的一个访问得到。在以下的开头两个表达式里，我们可以访问到一个用JavaBean语言命名为aProperty的属性或者用关键字aProperty访问到一个Map实体。在第三个表达式中（注意：我已经省略了引号），我们用保存在变量aVariableContainingPropertyName中的一个名字访问了在anObject之内的一个元素: <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>${anObject.aProperty}
${anObject["aPropertyName"]}
${anObject[aVariableContainingPropertyName]}</PRE></TD></TR></TBODY></TABLE></P>
<P>　　在EL中定义了许多隐藏变量： <BR>　　● pageContext：用于该网页的pageContext对象 <BR>　　● pageScope, requestScope, sessionScope, 和 applicationScope：这些是映射这些范围的每一个变量到值上的Map集。 <BR>　　● param 和 paramValues：用页访问传递的参数，与在JSP中一样 <BR>　　● header 和 headerValues：用页请求传递的头，与在JSP中一样 <BR>　　● cookie：Map映射cookie程序到特定的cookie对象上 <BR><BR>　　EL定义了全套与你在Java中非常熟悉的那些完全对应的操作符。算法操作符包括+、 -、 *、 / (或 div)、 和% (或 mod)。相关的操作符包括==、！=、&lt;、&gt;、&lt;=、&gt;=，它分别对应于eq、ne、lt、gt、le、和ge。我不想详细阐述这些操作符，因为他们都能自我说明。 </P>
<P><STRONG><FONT color=#330099>　　JSTL标记库</FONT></STRONG> <BR>　　至此，我已经解释了一些基本原理并且涵盖了EL语法。我要专门讨论四种JSTL标记库。我主要讨论核心库，因为它是你一定要使用的；但是，我也会详细的讨论其余几个，以便你能启动它。 <BR><BR>　　首先，尽管我应该更多地谈论JSTL标记库的两种风格，我上面提到的每个JSTL标记库以两个版本出现：一个支持使用EL的表达式；另一个支持标准JSP表达式。当你引入任何标记库到一个JSP页时，你要定义一个前缀，该前缀指定了与库中标记相对应的命名空间。 <BR><BR>　　四种标准标记库，和他们的JSTL规范定义的前缀常规，列表如下。记住：你可以定义自己的前缀，但是这绝对没有什么好处。</P>
<CENTER>四种标准标记库<BR><IMG src="http://www.javafan.net/uploadfiles/20051229115558915.jpg"></CENTER>
<P>　　为了使用页中的核心标记库（ 实际上，你使你的页对标记库的命名空间可见），在你的页首包含下列例子中的指令： 
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;%@ taglib prefix="c" uri=http://java.sun.com/jstl/core %&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　为了使用该标记库的标记，用你在你的包含语句中设计好的前缀，在你的页中给每个标记加上前缀： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:out value="${anExpression}"/&gt;</PRE></TD></TR></TBODY></TABLE><BR><B><FONT color=#330099>　　</FONT></B><B><FONT color=#330099>核心数据库</FONT></B> <BR><BR>　　让我们更详细的测试核心数据库，先看看他最通用的功能。 <BR><BR><B>　　显示/设定值和异常处理</B> <BR><BR>　　核心库的最基本的标记是c:out标记，它在页中显示一个EL表达式的值。一个使用c:out的表达式通常是这样： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>We have &lt;c:out value="${applicationScope.product.inventoryCount}" 
escapeXml="true" default="0"  /&gt; of those items in stock.</PRE></TD></TR></TBODY></TABLE><BR>　　上例中，value属性是我们送到页输出的表达式。我也说明了选项escapeXml的属性和默认属性。escapeXml的属性指定了XML字符(&lt;、&gt;、 &amp;、 和 .)是否应该转化为相应的字符实体代码（这样他们可以让这些字符出现在一个HTML页中）；默认属性用于EL不能估算出数值或者数值计算出来为空的情况。 <BR><BR>　　注意：当EL支持完全贯穿整个JSP2.0的时候，你不需要使用c:out动作；你可以仅嵌套JSP表达式直接在页中。 <BR><BR>　　另一个普遍使用的核心动作是c:set，它在页中设定一个变量。你可以用两种方法使用c:set动作，第一种方法设定在var属性中定义的变量到在value属性中定义的值上，方法如下： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:set var="customerID" value="$param:customerNumber" scope="session" /&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　上述的选择项scope属性指定了我们要在会话期范围内设定变量customerID；如果范围没有制定，范围默认为页。 <BR><BR>　　c:set另一个强大的用途就是将c:set标记的体的内容赋给一个指定的变量： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:set var="cellContents"&gt;
&lt;td&gt;
&lt;c:out value="${myCell}"/&gt;
&lt;/td&gt;
&lt;/c:set&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　在上例中，c:set动作定义了名为cellContents（在页的范围内）的变量，该变量拥有在标记的体中定义的内容。在这种情况下，体定义了一个HTML表格单元格元素，计算体中的c:out动作，并且该计算的结果包括在体中的字符串直接量值。 <BR><BR>　　就像你预想的那样，JSTL进行异常处理有点早。在典型的JSP页中，你有两种异常处理的方法：试图/捕捉直接嵌入到页中的小脚本代码中的块；或者用一个JSP errorPage指令。JSP errorPage指令提供一个良好的捕捉所有异常的方法来处理页中任何可能的异常。JSTL用一个c:catch动作提供一个好的可选择的方式。这个c:catch动作提供一个更细粒度的有效方法来处理异常。而且没有嵌入Java代码到页中。一个c:catch动作是这样的： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:catch&gt;
 &lt;!--. . . some set of nested JSTL tags below which would be hit on an exception--&gt;
&lt;/c:catch&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　c:catch动作有一个可选的属性，即一个指向抛出异常的变量。 <BR><BR>　　你可能不怎么愿意使用c:remove标记。这个标记有用于变量名和范围的属性，并且可从指定的范围内删除指定的变量。 </P>
<P><STRONG><FONT color=#330099>　　流程控制</FONT></STRONG> <BR>　　让我们转为讨论JSTL的流程控制和条件标记。如果你已经用任何一种语言使用了条件和流程控制语句，理论上这里没什么新鲜的东西。 <BR><BR>　　c:if动作处理简单条件语句的测试。计算测试属性中的Boolean表达式的值，如果表达式为真的话，计算体的内容。在下面的动作中，我们也说明了备选项var属性。为了以后的使用，var属性保存测试结果在页（如果没有指定其他scope属性的话）中。</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:if test="${status.totalVisits == 1000000}" var="visits"&gt;
   You are the millionth visitor to our site!  Congratulations!
&lt;/c:if&gt;</PRE></TD></TR></TBODY></TABLE>
<P>　　下面我们展示了用c:choose、 c:when、 和 c:otherwise交换逻辑的JSTL的支持。一组c:when动作可能包括在一个备选的标记内，如果在c:when块中任何表达式计算值为真的话，就不用计算c:choose动作内的测试。如果c:when块中没有一个测试计算值为真的时候：如果出现c:otherwise动作内容时，则计算c:otherwise动作的内容：</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:choose&gt;
&lt;c:when test="${item.type == 'book'}"&gt;
...
&lt;/c:when&gt;
&lt;c:when test="${item.type == 'electronics'}"&gt;
...
&lt;/c:when&gt;
&lt;c:when test="${item.type == 'toy'}"&gt;
...
&lt;/c:when&gt;
&lt;c:otherwise&gt;
...
&lt;/c:otherwise&gt;
&lt;/c:choose&gt;</PRE></TD></TR></TBODY></TABLE>
<P>　　c:foreach动作提供一个容易的方法来迭代一个集合的元素。如果你想只迭代集合的一部分的话，你可以分别用begin、 end、 和 step属性指定起点、终点和一个递增值。在下面的例子中，我们在变量customerNames中迭代一个集合的内容；在每个循环中，下一个元素输入到变量名内并在c:foreach动作的体内计算：</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;table&gt;
&lt;c:forEach var="name" items="${customerNames}"&gt;
&lt;tr&gt;&lt;td&gt;&lt;c:out value="${name}"/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　 记得Java的StringTokenizer类吗？有了c:forTokens动作，你可以用JSTL获得类似的功能。这个程序片断可使用在delims属性中定义的定界符通过items String属性中的条目迭代。注意，items 属性不必是一个字符直接量；它可以是任何有效的EL表达式: <BR>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;table&gt;
&lt;c:forTokens items="47,52,53,55,46,22,16,2" delim="," var="dailyPrice"&gt;
&lt;tr&gt;&lt;td&gt;&lt;c:out value="${dailyPrice}"/&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/c:forTokens&gt;
&lt;/table&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　在接下来的完整的JSTL页中，我列出了已经传递到该页的所有参数。param 和paramValues对象是映射关键字到一个或多个值的Java Map集。在本例中，我们找出了用于集合的每个MapEntry的关键字即参数名，并且使用关键字来查找所有与关键字关联的参数值：<BR>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %&gt;
&lt;html&gt;
&lt;body&gt;
&lt;head&gt;
&lt;title&gt;Parameter Listing Example&lt;/title&gt;
&lt;/head&gt;
&lt;br&gt;
&lt;b&gt;Parameter values passed to this page for each parameter: &lt;/b&gt;
&lt;table border="2"&gt;
&lt;c:forEach var="current" items="${param}"&gt;
    &lt;tr&gt;
    &lt;td&gt;
    &lt;b&gt;&lt;c:out value="${current.key}" /&gt;&lt;/b&gt;
    &lt;/td&gt;
    &lt;c:forEach var="aVal" items="${paramValues[current.key]}"&gt;
     &lt;td&gt;
     &lt;c:out value="${aVal}" /&gt;
      &lt;/td&gt;
   &lt;/c:forEach&gt;
  &lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;</PRE></TD></TR></TBODY></TABLE>
<P><B><FONT color=#330099>　　其他动作</FONT></B> <BR>　　我们也需要讨论一些其他重要的核心标记库动作。在网页实现中一个潜在的问题范围与URL编码有关。没有URL编码，在网页中传递的URL的某个字符如空格，可能会迷惑Web服务器。URL编码确保这些特殊的字符用不引起迷惑的字符代替。下列例子在变量myUrl中定义了一个URL,该变量myUrl由一个URL和一系列参数组成。URL动作（注意，这里只在JSTL意义上的动作）保证所有字符都正确的编码: </P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:url value="http://acme.com/exec/register" var="myUrl"&gt;
&lt;c:param name="name" value="${param.name}"/&gt;
&lt;c:param name="country" value="${param.country}"/&gt;
&lt;/c:url&gt;
&lt;a href='&lt;c:out value="${myUrl}"/&gt;'&gt;Register&lt;/a&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　在上面的代码中，param动作简单的定义了一组名值对。 <BR><BR>　　JSP允许设计者用 &lt;JSP:INCLUDE&gt;&lt;/JSP:INCLUDE&gt; <?XML:NAMESPACE PREFIX = JSP /><JSP:INCLUDE></JSP:INCLUDE>
<P><JSP:INCLUDE></JSP:INCLUDE>　　&lt;JSP:INCLUDE&gt;指令包括其他页的内容。JSTL用JSTL c:import动作扩展了这个概念。c:import的主要优势是：你能指定一个任意的URL；也可以包含你的Web应用之外（W3C的任何地方）的页的内容或者你的服务器上的另一个Web应用内的页的内容。 <BR><BR>　　对于一组与HTTP相关的标记来说，没有一个方法处理HTTP重定向是不完整的。JSTL用c:redirect动作支持它。 <BR><BR><B><FONT color=#330099>　　国际化标记库</FONT></B> <BR><BR>　　在讨论了JSTL支持国际化中，我假设你已经有了对下列主题的合理的理解： <BR><BR>　　●资源包和Java如何找到它们 <BR>　　●Locale类 <BR>　　●资源包查找和MessageFormat类 <BR>　　●局部编码以及它与Java国际化的关系 <BR>　　●Java文本和数据格式化</P>
<P>　　如果你需要这些主题的更多的信息，请阅读Resources (<A href="http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl-p4.html#resources#resources" target=_blank>http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl-p4.html#resources#resources</A>)上的参考部分与国际化有关的参考文章。 <BR><BR>　　我在下面的两个部分讨论了国际化标记库。在第一部分，我包括了你可能使用的格式化和解释相关的动作（它最初对应于java.text封装包中的类），尽管你没有开发过完全的国际化应用程序，可能你也要用到它。在第二部分，我说明了更针对于国际化的动作。 <BR><BR>　　如果存在一个远程的可能性，你的应用程序会在你本国之外使用。如果你从一开始就建立在国际化的支持上，那么开发就会更加容易。无论你使用何种方法来开发，即使像JSTL一样容易使用的方法，一开始建立在国际化支持上也是十分有益的。 </P>
<P><STRONG><FONT color=#330099>　　格式标记库：格式动作</FONT></STRONG> <BR>　　如果你已经使用了Java的 DateFormat 和NumberFormat类，在下面的标记中使用的方法应该看起来眼熟，因为JSTL格式化动作是在这些类之上建立的。这些Java类普遍提供一个format( )函数，它将一个Java类型转化为一个格式化的String和创建对应于该String的Java对象。 <BR><BR>　　fmt:formatNumber动作有一个value属性和一个pattern属性。value属性是一个与我们看到的其它value属性类似的EL表达式或者变量。pattern属性与在NumberFormat类中定义的模式一样。下列动作发送一个格式化的String到JSP页的输出上： 
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;fmt:formatNumber value="1000.001" pattern="#,#00.0#"/&gt;</PRE></TD></TR></TBODY></TABLE>
<P><BR>　　在这个fmt:formatNumber动作里，我们使用了type属性来指定：格式化我们需要格式化的值为一个货币值。我们保存格式化的结果在一个变量名为dollars中。在一个美国的locale类中，下面的程序生成一个字符串$3456.79（注意，它将使用的货币值四舍五入了）：</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;fmt:formatNumber value="3456.789" type="currency" var="dollars"/&gt;</PRE></TD></TR></TBODY></TABLE></P>
<P><BR>　　用于上面的type属性的可能值包括currency、 number、 和percent。 <BR><BR>　　在例中，我们使用了另一种方法——使用了一个包括在value属性中的一个格式化的域（currency，每type属性）的一个文本字符串。并且解析它来获取一个数字。结果储存在由var属性指定的一个变量内。尽管这个属性是可选的，还是会经常使用它。另外，解析的值送到页输出上：</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;fmt:parseNumber value="${currencyInput}" type="currency"
 var="parsedNumber"/&gt;
fmt:formatDate动作有一个value属性、一个format属性、
一个指向处理格式化的格式类的属性（典型的，如java.util.Date）：
&lt;jsp:useBean id="now" class="java.util.Date" /&gt;
&lt;fmt:formatDate value="${now}" timeStyle="long"
dateStyle="long"/&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　像数字格式化一样，JSTL页提供一个机制来解析一个代表日期的、进入Date对象的字符串： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;fmt:parseDate value="${dateInput}" pattern="MM dd, YYYY" /&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　查看java.util.DateFormat类，了解如何处理格式化和模式的更多详细的资料。 <BR><BR><B><FONT color=#330099>　　格式标记库：国际化动作</FONT></B> <BR>　　Java本地化的一个关键点是ResourceBundle类。JSTL动作允许你用这个类简单的工作。这个例子使用了fmt:bundle动作来得到与当前Locale 和 fmt:message动作对应的一个ResourceBundle动作，从而查看该资源包中的本地化的字符串： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;fmt:bundle basename="myBundle"&gt;
&lt;%-- Use values in myBundle --%&gt;
&lt;fmt:message key="Introduction"&gt;
   &lt;fmt:param value="${loginName}"/&gt;
   &lt;fmt:param value="${loginCount}"/&gt;
&lt;/fmt:message&gt;
&lt;fmt:formatDate value="${now}" var="parsedDate"/&gt;
&lt;/fmt:bundle&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　经常，fmt:message动作简单的查看了对应于一个关键词的字符串。在上面的例子中，在ResourceBundle中的字符串包含了取代两个值的占位符。这些值在fmt:param动作中定义过，这就像Java MessageFormat类使用的方法。 <BR><BR>　　有一些类似的动作可指定一个时区，时区可应用到在标记的体中计算的任何事上： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;fmt:timeZone value="someTimeZone"&gt;
&lt;!-- actions in this context will be evaluated using someTimeZone  --&gt;
&lt;/fmt:timeZone&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　上述的fmt:bundle 和 fmt:timeZone动作有分别对应的fmt:setBundle和fmt:setTimeZone的动作。这些动作添加了可选的scope属性；因此，你可以使用这些动作在任何等同于应用范围的范围内设定一个资源捆绑或者一个时区。 <BR><BR>　　如果你用非欧洲的locale类工作的话，你可能得担心编码的问题，JSTL支持用fmt:requestEncoding动作编码。 <BR><BR><B><FONT color=#330099>　　SQL标记库</FONT></B> <BR><BR>　　JSTL 允许容易的数据库的集成。但是，值得注意的是：沙箱之外的JSTL的执行有一些限制。主要的问题与连接池有关。建立并维护到数据库的连接是很消耗资源的。JSTL SQL动作使得许多数据库连接建立起来，通常的，每个用户至少有一个。因此，JSTL SQL标记对于原型开发的或低容量的、基于Web的应用程序意义重大。但是它不适合于大规模的应用程序。一个可缩放的产品应用程序一般是在一个页面内处理数据库访问如隐藏数据库访问和处理像连接池之类的细节。但是，还是有方法允许你实现连接池和用一点自定义码来使用JSTL SQL动作（请看："JSTL 1.0: What JSP Applications Need, Part 2" in Resources ：http://www.javaworld.com/javaworld/jw-02-2003/jw-0228-jstl-p5.html#resources#resources). <BR><BR>　　我们看一些简单的例子。这些例子使用来自SQL库的JSTL标记。如果你熟悉SQL基础的话，你应该能够改编这些例子用在你的应用程序上。 <BR><BR>　　在下面的程序片断中，我们建立了一条到一个数据库的连接，选择一组匹配一个订单ID的订单项目，并且在一个表格中显示item属性： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;sql:setDataSource
      driver="com.cheapDrivers.jdbcDriver"
      url="jdbc:cheapDrivers:."
      user="guest"
      password="password"
      var="dataSource" /&gt;

&lt;sql:query var="orderItems" dataSource="${dataSource}"&gt;
SELECT * FROM items
WHERE order_id = &lt;cout value="${orderID}"/&gt; 
ORDER BY price
&lt;/sql:query&gt;
&lt;table&gt;
&lt;c:forEach var="row" items="${orderItems.rows}"&gt;
&lt;tr&gt;
&lt;td&gt;&lt;c:out value="${row.itemName}"/&gt;&lt;/td&gt;
&lt;td&gt;&lt;c:out value="${row.price}"/&gt;&lt;/td&gt;
&lt;td&gt;&lt;c:out value="${row.weight}"/&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/c:forEach&gt;
&lt;/table&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　在下一个例子中，我会说明JSTL是如何支持数据库事务的，在数据库中，许多包含对表格多个改动的操作必须是对所有的，或者什么也不做：如果出现一个问题时，改动必须为空操作。在下面例子中，sql:update动作包含在一个sql:transaction动作内，如果在事务处理过程中，存在任何SQL错误的话，在事务范围内执行的所有操作都得重来。 <BR><BR>　　sql:update动作的命名有一点误导：除了SQL UPDATE外，sql:update也支持INSERT 和 DELETE，甚至是SQL CREATE。实际上，它支持不产生结果的任何一条SQL操作。在下面的例子中，sql:update通过插入变量值到一个PreparedStatement中来执行一个UPDATE动作。在这个代码片断中，我们在两个账户之间传送钱（需要预先包装在一个事务中的某些东西的一个经典的例子）： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;sql:transaction dataSource="${dataSource}"&gt;
&lt;sql:update&gt;
UPDATE account
SET account_balance =account_balance -?
WHERE accountNo = ?
&lt;sql:param value="${transferAmount}"/&gt;
&lt;sql:param value="${sourceAccount}"/&gt;
&lt;/sql:update&gt;
&lt;sql:update&gt;
UPDATE account
SET account_balance =account_balance +?
WHERE accountNo = ?
&lt;sql:param value="${transferAmount}"/&gt;
&lt;sql:param value="${destAccount}"/&gt;
&lt;/sql:update&gt;
&lt;/sql:transaction&gt;</PRE></TD></TR></TBODY></TABLE><BR><B><FONT color=#330099>　　</FONT></B><B><FONT color=#330099>XML标记库</FONT></B> <BR>　　使用标准的XML标记库，你所能做的完整的处理，特别是可扩展性单一语言变换说明（XSLT）的处理，对于另一篇文章来说是一个很好的主题。下面我会涵盖足够的让你开始的知识。 <BR><BR>　　在JSTL的XML支持遵循XPath规范。XPath的重要功能之一是为访问XML著名的分层的信息提供一个清晰的语法。也许看到每件是如何工作的最容易的方法就是看看我们如何使用来自于一个真实JSTL页的一个片断里的标记： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>!-- Find and parse our XML document (somewhere on the WWW) --&gt;
&lt;c:import url="http://www.cheapstuff.com/orderStatus?id=2435" var="xml"/&gt;
&lt;x:parse xml="${xml}" var="doc"/&gt;
&lt;!-- access XML data via XPath expressions --&gt;
&lt;x:out select="$doc/name"/&gt;
&lt;x:out select="$doc/shippingAddress"/&gt;
&lt;x:out select="$doc/deliveryDate"/&gt;
&lt;!-- Set a scoped variable --&gt;
&lt;x:set var="custName" scope="request" select="$doc/name"/&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　在上面的输入和解析动作中，我们装载和解析了一个指定的XML文档到一个变量doc里。在上面的每个x:out动作中，我们使用了一个XPath表达式访问了解析的XML文档的元素，并且发送结果到JSP页输出中。 <BR><BR>　　上面的设置表达式计算了一个XPath表达式并且将结果输入到一个限定范围的变量里（在上述例子中，它指在一个请求范围内）。 <BR><BR>　　x:out 和x:set动作可以输出一个JspTagException。如果他们没有成功的话（极有可能因为XPath表达式指向并不存在的标记），你的页，像在所有其他情况下一样，应该智能的处理这些异常（要么通过传统的JSP errorPage指令，要么使用JSTL的c:catch动作）， <BR><BR>　　JSTL容易处理XSLT转换。在下面的示范页中，我们使用来自XML标记库中的x:transform动作，用一个XSLT stylesheet创建一个来自于XML源文档的一个格式化的页。x:transform动作最重要的属性是XML和XSLT属性，在下面的例子中，我们设置了一个来自于我们在同一页初始化的变量的xslt属性；我们也在动作的体中设置了XML属性。该动作默认为x:transform动作。 <BR><BR>　　默认的，转换的结果送到页输出上；你也可以保存结果到一个带x:var属性的变量内： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %&gt;
&lt;%@ taglib uri="http://java.sun.com/jstl/xml" prefix="x" %&gt;
&lt;c:set var="xsltSource"&gt; 
&lt;?xml version="1.0"?&gt;
&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt;
&lt;xsl:template match="/"&gt;
      &lt;xsl:apply-templates/&gt;
&lt;/xsl:template&gt;
&lt;xsl:template match="music"&gt;
&lt;html&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body marginheight="0" marginwidth="0" topmargin="0" leftmargin="0"&gt;
&lt;table cellpadding="0" cellspacing="0" border="1" bgcolor="#ffffff"&gt;
      &lt;tr&gt;
      &lt;td&gt;&lt;STRONG&gt;Artist&lt;/STRONG&gt;&lt;/td&gt;
      &lt;td&gt;&lt;STRONG&gt;Album&lt;/STRONG&gt;&lt;/td&gt;
      &lt;td&gt;&lt;STRONG&gt;Year&lt;/STRONG&gt;&lt;/td&gt;
      &lt;td&gt;&lt;STRONG&gt;Genre&lt;/STRONG&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;!---Set up for loop to collect all the artist information //--&gt;
      &lt;!-- &lt;xsl:for-each select="./*[name()='artists']"&gt; --&gt;
      &lt;xsl:for-each select="artists"&gt;
        &lt;tr&gt;
          &lt;td&gt;&lt;xsl:value-of select="artist"/&gt;&lt;/td&gt;
          &lt;td&gt;&lt;xsl:value-of select="album"/&gt;&lt;/td&gt;
          &lt;td&gt;&lt;xsl:value-of select="year"/&gt;&lt;/td&gt;
         &lt;td&gt;&lt;xsl:value-of select="genre"/&gt;&lt;/td&gt;
        &lt;/tr&gt;
     &lt;/xsl:for-each&gt;
&lt;/table&gt;
&lt;/body&gt;
&lt;/html&gt;
&lt;/xsl:template&gt;
&lt;/xsl:stylesheet&gt;
&lt;/c:set&gt; 
&lt;x:transform xslt="${xsltSource}" &gt;
&lt;music&gt;
&lt;artists&gt;
    &lt;artist&gt;Jonny B&lt;/artist&gt;
    &lt;album&gt;Feedback and Distortion&lt;/album&gt;
    &lt;year&gt;2001&lt;/year&gt;
     &lt;genre&gt;Rock&lt;/genre&gt;
      &lt;/artists&gt; 
     &lt;artists&gt;
      &lt;artist&gt;Harmony's Nieces&lt;/artist&gt;
      &lt;album&gt;Sappy Pop Ballads&lt;/album&gt;
      &lt;year&gt;2002&lt;/year&gt;
      &lt;genre&gt;Pop&lt;/genre&gt;
      &lt;/artists&gt; 
&lt;/music&gt;
&lt;/x:transform&gt;</PRE></TD></TR></TBODY></TABLE><BR>　　你也能使用c:import动作再定义一个额外的源文档和stylesheet，就好像在这个示范的代码片断展示的一样：： <BR><BR>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE>&lt;c:import var="${xmlSource}" url="${someDocumentURL}" /&gt;
&lt;c:import var="${xsltSource}" url="${anotherDocumentURL}" /&gt;
&lt;x:transform xml="${xmlSource}" xslt="${xsltSource}" &gt;</PRE></TD></TR></TBODY></TABLE><BR><B><FONT color=#330099>　　</FONT></B><B><FONT color=#330099>结束语</FONT></B> <BR>　　至此，你应该对JSTL、它的四种标准标记库、和它如何使网页开发更为容易 有了很好的理解。现在你开始写一些JSTL! <BR></P><img src ="http://www.blogjava.net/zhangrenquan/aggbug/27357.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-01-10 12:07 <a href="http://www.blogjava.net/zhangrenquan/articles/27357.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RMI一步一步来</title><link>http://www.blogjava.net/zhangrenquan/articles/27354.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Tue, 10 Jan 2006 03:51:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/27354.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/27354.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/27354.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/27354.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/27354.html</trackback:ping><description><![CDATA[[摘录]:http://www.javafan.net/article/20051229144530549.html<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp; RMI，远程方法调用（Remote Method Invocation）是Enterprise JavaBeans的支柱，是建立分布式Java应用程序的方便途径。RMI是非常容易使用的，但是它非常的强大。<BR>　　RMI的基础是接口，RMI构架基于一个重要的原理：定义接口和定义接口的具体实现是分开的。下面我们通过具体的例子，建立一个简单的远程计算服务和使用它的客户程序<BR><BR>　　一个正常工作的RMI系统由下面几个部分组成： 
<UL>
<LI>远程服务的接口定义 
<LI>远程服务接口的具体实现 
<LI>桩（Stub）和框架（Skeleton）文件 
<LI>一个运行远程服务的服务器 
<LI>一个RMI命名服务，它允许客户端去发现这个远程服务 
<LI>类文件的提供者（一个HTTP或者FTP服务器） 
<LI>一个需要这个远程服务的客户端程序 </LI></UL>
<P>　　下面我们一步一步建立一个简单的RMI系统。首先在你的机器里建立一个新的文件夹，以便放置我们创建的文件，为了简单起见，我们只使用一个文件夹存放客户端和服务端代码，并且在同一个目录下运行服务端和客户端。<BR><BR>　　如果所有的RMI文件都已经设计好了，那么你需要下面的几个步骤去生成你的系统：<BR><BR>　　1、&nbsp;&nbsp;编写并且编译接口的Java代码<BR>　　2、&nbsp;&nbsp;编写并且编译接口实现的Java代码<BR>　　3、&nbsp;&nbsp;从接口实现类中生成桩（Stub）和框架（Skeleton）类文件<BR>　　4、&nbsp;&nbsp;编写远程服务的主运行程序<BR>　　5、&nbsp;&nbsp;编写RMI的客户端程序<BR>　　6、&nbsp;&nbsp;安装并且运行RMI系统<BR><BR>　　1、&nbsp;&nbsp;接口<BR>　　第一步就是建立和编译服务接口的Java代码。这个接口定义了所有的提供远程服务的功能，下面是源程序：<BR><BR>//Calculator.java<BR>//define the interface<BR>import java.rmi.Remote;<BR><BR>public interface Calculator extends Remote<BR>{<BR>&nbsp;&nbsp;&nbsp;&nbsp;public long add(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException; <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long sub(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException; <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long mul(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException; <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long div(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException; <BR>} <BR>　　注意，这个接口继承自Remote，每一个定义的方法都必须抛出一个RemoteException异常对象。<BR><BR>　　建立这个文件，把它存放在刚才的目录下，并且编译。<BR><BR>　　&gt;javac Calculator.java<BR><BR>　　2、&nbsp;&nbsp;接口的具体实现<BR><BR>　　下一步，我们就要写远程服务的具体实现，这是一个CalculatorImpl类文件：<BR><BR>//CalculatorImpl.java<BR>//Implementation<BR>import java.rmi.server.UnicastRemoteObject<BR><BR>public class CalculatorImpl extends UnicastRemoteObject implements Calculator <BR>{ <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;// 这个实现必须有一个显式的构造函数，并且要抛出一个RemoteException异常 <BR>&nbsp;&nbsp;&nbsp;&nbsp;public CalculatorImpl() <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;super(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long add(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a + b; <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long sub(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a - b; <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long mul(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a * b; <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public long div(long a, long b) <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws java.rmi.RemoteException { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a / b; <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>} <BR>　　同样的，把这个文件保存在你的目录里然后编译他。<BR><BR>　　这个实现类使用了UnicastRemoteObject去联接RMI系统。在我们的例子中，我们是直接的从UnicastRemoteObject这个类上继承的，事实上并不一定要这样做，如果一个类不是从UnicastRmeoteObject上继承，那必须使用它的exportObject()方法去联接到RMI。<BR><BR>　　如果一个类继承自UnicastRemoteObject，那么它必须提供一个构造函数并且声明抛出一个RemoteException对象。当这个构造函数调用了super()，它久激活UnicastRemoteObject中的代码完成RMI的连接和远程对象的初始化。<BR><BR>　　3、&nbsp;&nbsp;桩（Stubs）和框架（Skeletons）<BR><BR>　　下一步就是要使用RMI编译器rmic来生成桩和框架文件，这个编译运行在远程服务实现类文件上。<BR><BR>　　&gt;rmic CalculatorImpl<BR><BR>　　在你的目录下运行上面的命令，成功执行完上面的命令你可以发现一个Calculator_stub.class文件，如果你是使用的Java2SDK，那么你还可以发现Calculator_Skel.class文件。<BR><BR>　　4、&nbsp;&nbsp;主机服务器<BR><BR>　　远程RMI服务必须是在一个服务器中运行的。CalculatorServer类是一个非常简单的服务器。<BR><BR>//CalculatorServer.java<BR>import java.rmi.Naming;<BR><BR>public class CalculatorServer {<BR><BR>&nbsp;&nbsp;&nbsp;public CalculatorServer() {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculator c = new CalculatorImpl();<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Naming.rebind("rmi://localhost:1099/CalculatorService", c);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (Exception e) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Trouble: " + e);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<BR>&nbsp;&nbsp;&nbsp;}<BR><BR>&nbsp;&nbsp;&nbsp;public static void main(String args[]) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new CalculatorServer();<BR>&nbsp;&nbsp;&nbsp;}<BR>}<BR>　　建立这个服务器程序，然后保存到你的目录下，并且编译它。<BR><BR>　　5、&nbsp;&nbsp;客户端<BR><BR>　　客户端源代码如下：<BR><BR>//CalculatorClient.java<BR><BR>import java.rmi.Naming; <BR>import java.rmi.RemoteException; <BR>import java.net.MalformedURLException; <BR>import java.rmi.NotBoundException; <BR><BR>public class CalculatorClient { <BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;public static void main(String[] args) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Calculator c = (Calculator)<BR>&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;Naming.lookup(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"rmi://localhost<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/CalculatorService"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println( c.sub(4, 3) ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println( c.add(4, 5) ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println( c.mul(3, 6) ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println( c.div(9, 3) ); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (MalformedURLException murle) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"MalformedURLException"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(murle); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (RemoteException re) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"RemoteException"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(re); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (NotBoundException nbe) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"NotBoundException"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(nbe); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch (<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;java.lang.ArithmeticException<BR>&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;ae) { <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"java.lang.ArithmeticException"); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(ae); <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <BR>&nbsp;&nbsp;&nbsp;&nbsp;} <BR>} <BR>　　保存这个客户端程序到你的目录下（注意这个目录是一开始建立那个，所有的我们的文件都在那个目录下），并且编译他。<BR><BR>　　6、&nbsp;&nbsp;运行RMI系统<BR><BR>　　现在我们建立了所有运行这个简单RMI系统所需的文件，现在我们终于可以运行这个RMI系统啦！来享受吧。<BR><BR>　　我们是在命令控制台下运行这个系统的，你必须开启三个控制台窗口，一个运行服务器，一个运行客户端，还有一个运行RMIRegistry。<BR><BR>　　首先运行注册程序RMIRegistry，你必须在包含你刚写的类的那么目录下运行这个注册程序。<BR><BR>　　&gt;rmiregistry<BR><BR>　　好，这个命令成功的话，注册程序已经开始运行了，不要管他，现在切换到另外一个控制台，在第二个控制台里，我们运行服务器CalculatorService，因为RMI的安全机制将在服务端发生作用,所以你必须增加一条安全策略。以下是对应安全策略的例子 <BR>grant {<BR>permission java.security.AllPermission "", "";<BR>};<BR>　　注意:这是一条最简单的安全策略,它允许任何人做任何事,对于你的更加关键性的应用,你必须指定更加详细安全策略。<BR>　　现在为了运行服务端，你需要除客户类(CalculatorClient.class)之外的所有的类文件。确认安全策略在policy.txt文件之后,使用如下命令来运行服务器。</P>
<P>　　&gt; java -Djava.security.policy=policy.txt CalculatorServer<BR><BR>　　这个服务器就开始工作了，把接口的实现加载到内存等待客户端的联接。好现在切换到第三个控制台，启动我们的客户端。<BR>　　为了在其他的机器运行客户端程序你需要一个远程接口(Calculator.class) 和一个stub(CalculatorImpl_Stub.class)。 使用如下命令运行客户端</P>
<P>　　 prompt&gt; java -Djava.security.policy=policy.txt CalculatorClient<BR><BR>如果所有的这些都成功运行，你应该看到下面的输出：<BR>　　1<BR>　　9<BR>　　18<BR>　　3<BR>　　如果你看到了上面的输出，恭喜你，你成功了，你已经成功的创建了一个RMI系统，并且使他正确工作了。即使你运行在同一个计算机上，RMI还是使用了你的网络堆栈和TCP/IP去进行通讯，并且是运行在三个不同的Java虚拟机上。这已经是一个完整的RMI系统。</P><img src ="http://www.blogjava.net/zhangrenquan/aggbug/27354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-01-10 11:51 <a href="http://www.blogjava.net/zhangrenquan/articles/27354.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习用Google做搜索</title><link>http://www.blogjava.net/zhangrenquan/articles/27302.html</link><dc:creator>kelven</dc:creator><author>kelven</author><pubDate>Mon, 09 Jan 2006 11:44:00 GMT</pubDate><guid>http://www.blogjava.net/zhangrenquan/articles/27302.html</guid><wfw:comment>http://www.blogjava.net/zhangrenquan/comments/27302.html</wfw:comment><comments>http://www.blogjava.net/zhangrenquan/articles/27302.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/zhangrenquan/comments/commentRss/27302.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/zhangrenquan/services/trackbacks/27302.html</trackback:ping><description><![CDATA[[摘录于]: http://www.matrix.org.cn/thread.shtml?view_id=971&amp;forum_id=19<BR><BR>1，前言<BR>2，摘要<BR>3，如何使用本文<BR>4，Google简介<BR>5，搜索入门<BR>6，初阶搜索<BR>　　6.1，搜索结果要求包含两个及两个以上关键字<BR>　　6.2，搜索结果要求不包含某些特定信息<BR>　　6.3，搜索结果至少包含多个关键字中的任意一个<BR>7，杂项语法<BR>　　7.1，通配符问题<BR>　　7.2，关键字的字母大小写<BR>　　7.3，搜索整个短语或者句子<BR>　　7.4，搜索引擎忽略的字符以及强制搜索<BR>8，进阶搜索<BR>　　8.1，对搜索的网站进行限制<BR>　　8.2，查询某一类文件<BR>　　8.3，搜索的关键字包含在URL链接中<BR>　　8.4，搜索的关键字包含在网页标题中<BR>　　8.5，搜索的关键字包含在网页“锚”内<BR>9，其他罕用语法<BR>　　9.1，搜索所有链接到某个URL地址的网页<BR>　　9.2，查找与某个页面结构内容相似的页面<BR>　　9.3，从Google服务器上缓存页面中查询信息<BR>10，图片搜索<BR>11，目录检索<BR>12，新闻组搜索<BR>13，Google的其他杰出功能<BR>　　13.1，网页快照<BR>　　13.2，集成化的工具条<BR>　　13.3，单词英文解释<BR>　　13.4，网页翻译<BR>　　13.5，单词纠错<BR>　　13.6，搜索结果过滤<BR>14，Google尚未发布的一些新特性和功能<BR>　　14.1，对网页更新日期做出限定<BR>　　14.2，新闻搜索<BR>　　14.3，分类广告搜索<BR>　　14.4，其它Google的最新发展动态<BR>　　14.5，一个有趣的地方<BR>15，后记<BR><BR>——————————————————————————————————<BR><BR>[B]1，前言[/B]<BR><BR>　　我是在2000年上半年知道Google的。在这之前，我搜索英文信息通常用AltaVista，而搜索中文信息则常用Sina。但自使用了Google之后，它便成为我的Favorite Search engine了。这也得感谢新浪网友曹溪，因为当初正是因为他的大力推介，才使我识得了Google。<BR><BR>　　记得1996年夏季的时候，当我第一次接触Internet，便被扑面而来的魔力征服了。那种天涯咫尺的感觉，真是妙不可言。在经历了疯狂的WWW冲浪和如痴如醉的BBS沉迷之后，我意识到Internet对我影响至深的还是在于学习方式的变迁。<BR><BR>　　如何来描述这种变迁呢？以前的学习，一般需要预先在肚子里存储下足够的知识，必要时，就从海量的信息中提取所需的部分。这种学习方式造就了很多“才高八斗，学富五车”的大才子。但是，到了信息领域大大超出“四书五经”的新时期，预先无目的的吞下海量信息的学习方式就有些不合时宜了。比方说，我们到了大型的图书城，往往有一种不知所措的感觉。旧有的学习方式需要变更以适应这个信息爆炸的年代。目的明确的去学习，即先知道要学什么，然后有目的的去寻找答案，这种方式看上去更加有效率。我不妨把这称为“即学式”，相应的，旧有的称为“预学式”。<BR><BR>　　不过，“即学式”的实施是有前提的。首先，要求学习者拥有一个包罗万象的信息库，以供随时抽取各种目的信息；其次，是需要一个强劲的信息检索工具，以便高效率的从信息库中提取信息。很明显，Internet可以充当那个海量的信息库，而搜索引擎，则正是寻找光明之火的绝好工具。<BR><BR>　　“公欲善其事，必先利其器”。Internet只有一个，而搜索引擎则有N多个。有搜索高手说，所谓搜索，就是“在正确的地方使用正确的工具和正确的方法寻找正确的内容”。但是，对于普通人而言，掌握诸多搜索引擎的可能性似乎不大。用一两个相对强劲的具代表性的工具达到绝大多数搜索目的更为人们所迫切希望。不同的时期，涌现出不同的强者。就目前而言，我们非常幸运的有了： *****Google******<BR><BR><BR>[B]2，摘要[/B]<BR><BR>　　本文简要的介绍了Google的历史和特点，Google的基本搜索语法和高级搜索语法，Google的特色功能，包括图片搜索、新闻组搜索和集成工具条等。尽管本文名为“Google搜索从入门到精通”，但事实上，本文只能算是对Google的一个并不十分完全的介绍而已。:)<BR><BR><BR><B>3，如何使用本文</B><BR><BR>　　阅读本文最好具备一些最基本的布尔代数基础，如“与”、“或”、“非”等。不过，即便你没有这方面的知识，也不必在意。对那些实例进行练习，你的疑惑就会迎刃而解。对于刚刚接触网络搜索的读者而言，也许你应该从头到尾的阅读本文；但对于那些有一定搜索基础的读者而言，只需要跳跃着寻找自己所需要的信息就可以了。此外，你也可以参考中文Google大全：http://www.Google.com/intl/zh-CN/about.html，以及搜索帮助：http://www.google.com/intl/zh-CN/help.html，那是官方Google使用手册以及问题解答中心。<BR><BR><BR><B>4，Google简介</B><BR><BR>　　Google（www.Google.com）是一个搜索引擎，由两个斯坦福大学博士生Larry Page与Sergey Brin于1998年9月发明，Google Inc. 于1999年创立。2000年7月份，Google替代Inktomi成为Yahoo公司的搜索引擎，同年9月份，Google成为中国网易公司的搜索引擎。98年至今，Google已经获得30多项业界大奖。到Google的新闻中心（http://www.Google.com/press/index.html），你可以找到关于一切关于Google的历史和新闻资料。<BR><BR>　　Google的成功得益于其强大的功能和独到的特点：<BR><BR>Google检索网页数量达24亿，搜索引擎中排名第一；<BR>Google支持多达132种语言，包括简体中文和繁体中文；<BR>Google网站只提供搜索引擎功能，没有花里胡哨的累赘；<BR>Google速度极快，年初时据说有15000多台服务器，200多条T3级宽带；<BR>Google的专利网页级别技术PageRank能够提供准确率极高的搜索结果； <BR>Google智能化的“手气不错”功能，提供可能最符合要求的网站；<BR>Google的“网页快照”功能，能从Google服务器里直接取出缓存的网页。<BR>Google具有独到的图片搜索功能；<BR>Google具有强大的新闻组搜索功能；<BR>Google具有二进制文件搜索功能（PDF，DOC，SWF等）；<BR>Google还有很多尚在开发阶段的令人吃惊的设想和功能。<BR>等等<BR><BR><BR><B>5，搜索入门</B><BR><BR>　　要用Google做搜索，当然首先要进Google网站--www.Google.com；不过，163.com和yahoo.com.cn使用的实际上也是Google搜索引擎，只是对搜索结果进行了编排，而且无法提供一些特色功能，如图片搜索等。因此，如果你要搜索网页的话，就直接使用Google.com吧。<BR><BR>　　第一次进入Google，它会根据你的操作系统，确定语言界面。需要提醒的是，Google是通过cookie来存储页面设定的，所以，如果你的系统禁用cookie，就无法对Google界面进行个人设定了。<BR><BR>　　Google的首页很清爽，LOGO下面，排列了四大功能模块：网站、图像、新闻组和目录服务。默认是网站搜索。现在进行第一次搜索实践，假定你是个搜索新手，想要了解一下搜索引擎的来龙去脉和搜索技巧。在搜索框内输入一个关键字“搜索引擎”， 选中“搜索中文(简体)网页”选项，然后点击下面的“Google搜索”按钮（或者直接回车），结果就出来了。 搜索：“搜索引擎”<BR>结果：已搜索有关搜索引擎的中文(简体)网页。 共约有707,000项查询结果，这是第1-10项 。 搜索用时0.08秒。<BR><BR>　　仔细看一下搜索结果的前十项，就会发现绝大部分链接是搜索引擎本身，而不是对搜索引擎的或者搜索技巧方面的介绍。<BR><BR>　　注意：文章中搜索语法外面的引号仅起引用作用，不能带入搜索栏内。<BR><BR><BR><B>6，初阶搜索</B><BR><BR>　　上例是最基本的搜索，即查询包含单个关键字的信息。但是，你可以发现，上例中，单个关键字“搜索引擎”，搜索得的信息浩如烟海，而且绝大部分并不符合自己的要求，怎么办呢？我们需要进一步缩小搜索范围和结果。<BR><BR><SPAN style="COLOR: limegreen">6.1，搜索结果要求包含两个及两个以上关键字</SPAN><BR><BR>　　一般搜索引擎需要在多个关键字之间加上“ ”，而Google无需用明文的“ ”来表示逻辑“与”操作，只要空格就可以了。现在，我们需要了解一下搜索引擎的历史，因此期望搜得的网页上有“搜索引擎”和“历史”两个关键字。<BR><BR>示例：搜索所有包含关键词“搜索引擎”和“历史”的中文网页<BR>搜索：“搜索引擎 历史”<BR>结果：已搜索有关搜索引擎 历史的中文(简体)网页。 共约有78,600项查询结果，这是第1-10项 。 搜索用时0.36秒。 <BR><BR>　　用了两个关键字，查询结果已经从70多万项减少到7万多项。但查看一下搜索结果，发现前列的绝大部分结果还是不符合要求，大部分网页涉及的“历史”，并不是我们所需要的“搜索引擎的历史”。 怎么办呢？删除与搜索引擎不相关的“历史”。我们发现，这部分无用的资讯，总是和“文化”这个词相关的，另外一些常见词是“中国历史”、“世界历史”、“历史书籍”等。<BR><BR><SPAN style="COLOR: limegreen">6.2，搜索结果要求不包含某些特定信息</SPAN><BR><BR>　　Google用减号“-”表示逻辑“非”操作。“A –B”表示搜索包含A但没有B的网页。<BR><BR>示例：搜索所有包含“搜索引擎”和“历史”但不含“文化”、“中国历史”和“世界历史”的中文网页<BR>搜索：“搜索引擎 历史 -文化 -中国历史 -世界历史”<BR>结果：已搜索有关搜索引擎 历史 -文化 -中国历史 -世界历史的中文(简体)网页。 共约有36,800项查询结果，这是第1-10项 。 搜索用时0.22秒。 <BR><BR>　　我们看到，通过去掉不相关信息，搜索结果又减少了将近一半。第一个搜索结果是：<BR><BR>搜索引擎直通车≡搜索引擎发展历史<BR>搜索引擎直通车, ... 搜索引擎专业介绍站点. ... <BR>www.se-express.com/about/about.htm - 14k - 网页快照 - 类似网页<BR><BR>非常符合搜索要求。另外，第八项搜索结果：<BR><BR>463搜索王<BR>本站检索 整个网站 在此输入关键词. 你的当前<BR>位置：首页 &gt;&gt; Internet搜索手册 &gt;&gt; 搜索引擎的历史. ... <BR>www.cnco.net/search/history.htm - 21k - 网页快照 - 类似网页<BR><BR>　　也符合搜索要求。但是，10个结果只有两个符合要求，未免太少了点。不过，在没有更好的策略之前，不妨先点开一个结果看看。点开se-express.com的这个名为“搜索引擎发展历史”的网页，我们发现，搜索引擎的历史，是与互联网早期的文件检索工具“Archie”息息相关的。此外，搜索引擎似乎有个核心程序，叫“蜘蛛”，而最早成型的搜索引擎是“Lycos”，使搜索引擎深入人心的是“Yahoo”。了解了这些信息，我们就可以进一步的让搜索结果符合要求了。<BR><BR>　　注意：这里的“ ”和“-”号，是英文字符，而不是中文字符的“＋”和“－”。此外，操作符与作用的关键字之间，不能有空格。比如“搜索引擎 - 文化”，搜索引擎将视为关键字为“搜索引擎”和“文化”的逻辑“与”操作，中间的“-”被忽略。<BR><BR><SPAN style="COLOR: teal">6.3，搜索结果至少包含多个关键字中的任意一个。</SPAN><BR><BR>　　Google用大写的“OR”表示逻辑“或”操作。搜索“A OR B”，意思就是说，搜索的网页中，要么有A，要么有B，要么同时有A和B。在上例中，我们希望搜索结果中最好含有“archie”、“lycos”、“蜘蛛”等关键字中的一个或者几个，这样可以进一步的精简搜索结果。<BR><BR>示例：搜索如下网页，要求必须含有“搜索引擎”和“历史”，没有“文化”，可以含有以下关键字中人任何一个或者多个：“Archie”、“蜘蛛”、“Lycos”、“Yahoo”。<BR>搜索：“搜索引擎 历史 archie OR 蜘蛛 OR lycos OR yahoo -文化”<BR>结果：已搜索有关搜索引擎 历史 archie OR 蜘蛛 OR lycos OR yahoo -文化的中文(简体)网页。 共约有8,400项查询结果，这是第1-10项 。 搜索用时0.16秒。<BR><BR>　　我们看到，搜索结果缩小到8千多项，前20项结果中，大部分都符合搜索要求。如果你想了解一下解搜索引擎的历史发展，就不妨研究一下现在搜索到的结果吧。 注意：“与”操作必须用大写的“OR”，而不是小写的“or”。<BR><BR>　　在上面的例子中，我介绍了搜索引擎最基本的语法“与”“非”和“或”，这三种搜索语法Google分别用“ ”（空格）、“-”和“OR”表示。顺着上例的思路，你也可以了解到如何缩小搜索范围，迅速找到目的资讯的一般方法：目标信息一定含有的关键字（用“ ”连起来），目标信息不能含有的关键字（用“-”去掉），目标信息可能含有的关键字（用“OR”连起来）。<BR><BR><BR><B>7，杂项语法</B><BR><BR><SPAN style="COLOR: limegreen">7.1，通配符问题</SPAN><BR><BR>　　很多搜索引擎支持通配符号，如“*”代表一连串字符，“?”代表单个字符等。Google对通配符支持有限。它目前只可以用“*”来替代单个字符，而且包含“*”必须用""引起来。比如，“"以*治国"”，表示搜索第一个为“以”，末两个为“治国”的四字短语，中间的“*”可以为任何字符。<BR><BR><SPAN style="COLOR: teal">7.2，关键字的字母大小写</SPAN><BR><BR>　　Google对英文字符大小写不敏感，“GOD”和“god”搜索的结果是一样的。<BR><BR><SPAN style="COLOR: limegreen">7.3，搜索整个短语或者句子</SPAN><BR><BR>　　Google的关键字可以是单词（中间没有空格），也可以是短语（中间有空格）。但是，用短语做关键字，必须加英文引号，否则空格会被当作“与”操作符。<BR><BR>示例：搜索关于第一次世界大战的英文信息。 <BR>搜索：“"world war I"”<BR>结果：已向英特网搜索"world war i". 共约有937,000项查询结果，这是第1-10项 。 搜索用时0.06秒。 <BR><BR><SPAN style="COLOR: teal">7.4，搜索引擎忽略的字符以及强制搜索</SPAN><BR><BR>　　Google对一些网路上出现频率极高的英文单词，如“i”、“com”、“www”等，以及一些符号如“*”、“.”等，作忽略处理。<BR><BR>示例：搜索关于www起源的一些历史资料。<BR>搜索：“www的历史 internet”<BR>结果：以下的字词因为使用过于频繁，没有被列入搜索范围: www 的. 已搜索有关www的历史 internet的中文(简体)网页。 共约有75,100项查询结果，这是第1-10项 。 搜索用时0.22秒。 <BR><BR>　　我们看到，搜索“www的历史 internet”，但搜索引擎把“www”和“的”都省略了。于是上述搜索只搜索了“历史”和“internet”。这显然不符合要求。这里我顺便说一点搜索引擎分词的知识。当我们在搜索“www的历史”的时候，搜索引擎实际上把这个短语分成三部分，“www”、“的”和“历史”分别来检索，这就是搜索引擎的分词。所以尽管你输入了连续的“www的历史”，但搜索引擎还是把这个短语当成三个关键字分别检索。<BR><BR>　　如果要对忽略的关键字进行强制搜索，则需要在该关键字前加上明文的“+”号。<BR>搜索：“+www +的历史 internet”<BR>结果：已搜索有关+www +的历史 internet的中文(简体)网页。 共约有25,000项查询结果，这是第1-10项 。 搜索用时0.05秒。 <BR><BR>　　另一个强制搜索的方法是把上述的关键字用英文双引号引起来。在上例“”world war I””中，“I”其实也是忽略词，但因为被英文双引号引起来，搜索引擎就强制搜索这一特定短语。<BR><BR>搜索：“"www的历史" internet”<BR>结果：已搜索有关"www的历史" internet的中文(简体)网页。 共约有7项查询结果，这是第1-6项 。 搜索用时0.26秒。 <BR><BR>　　我们看到，这一搜索事实上把“www的历史”作为完整的一个关键字。显然，包含这样一个特定短语的网页并不是很多，不过，每一项都很符合要求。<BR><BR>　　注意：大部分常用英文符号（如问号，句号，逗号等）无法成为搜索关键字，加强制也不行。<BR><BR><BR><B>8，进阶搜索</B><BR><BR>　　上面已经探讨了Google的一些最基础搜索语法。通常而言，这些简单的搜索语法已经能解决绝大部分问题了。不过，如果想更迅速更贴切找到需要的信息，你还需要了解更多的东西。<BR><BR>8.1，对搜索的网站进行限制<BR><BR>　　“site”表示搜索结果局限于某个具体网站或者网站频道，如“www.sina.com.cn”、“edu.sina.com.cn”，或者是某个域名，如“com.cn”、“com”等等。如果是要排除某网站或者域名范围内的页面，只需用“-网站/域名”。<BR><BR>示例：搜索中文教育科研网站（edu.cn）上关于搜索引擎技巧的页面。<BR>搜索：“搜索引擎 技巧 site:edu.cn”<BR>结果：已搜索有关搜索引擎 技巧 site:edu.cn的中文(简体)网页。 共约有608项查询结果，这是第1-10项 。 搜索用时0.05秒。<BR><BR>示例：上著名IT门户网站ZDNET和CNET搜索一下关于搜索引擎技巧方面的资讯。<BR>搜索：“"search engine" tips site:www.zdnet.com OR site:www.cnet.com”<BR>结果：已在www.zdnet.com内搜索有关"search engine" tips OR site:www.cnet.com的网页。 共约有1,040项查询结果，这是第1-10项 。 搜索用时0.09秒。<BR><BR>　　注意，在这里Google有个小BUG。“已在www.zdnet.com内搜索…”，其实应该表述成“已在www.zdnet.com和www.cnet.com内搜索…”。<BR><BR>示例：搜索新浪科技频道中关于搜索引擎技巧的信息。<BR>搜索：“搜索引擎 技巧 site:tech.sina.com.cn”<BR>结果：已在tech.sina.com.cn搜索有关搜索引擎 技巧 的中文(简体)网页。 共约有163项查询结果，这是第1-10项 。 搜索用时0.07秒。 <BR><BR>　　注意：site后的冒号为英文字符，而且，冒号后不能有空格，否则，“site:”将被作为一个搜索的关键字。此外，网站域名不能有“http://”前缀，也不能有任何“/”的目录后缀；网站频道则只局限于“频道名.域名”方式，而不能是“域名/频道名”方式。<BR><BR><SPAN style="COLOR: teal">8.2，在某一类文件中查找信息</SPAN><BR><BR>　　“filetype:”是Google开发的非常强大实用的一个搜索语法。也就是说，Google不仅能搜索一般的文字页面，还能对某些二进制文档进行检索。目前，Google已经能检索微软的Office文档如.xls、.ppt、.doc，.rtf，WordPerfect文档，Lotus1-2-3文档，Adobe的.pdf文档，ShockWave的.swf文档（Flash动画）等。其中最实用的文档搜索是PDF搜索。PDF是ADOBE公司开发的电子文档格式，现在已经成为互联网的电子化出版标准。目前Google检索的PDF文档大约有2500万左右，大约占所有索引的二进制文档数量的80％。PDF文档通常是一些图文并茂的综合性文档，提供的资讯一般比较集中全面。<BR><BR>示例：搜索几个资产负债表的Office文档。<BR>搜索：“资产负债表 filetype:doc OR filetype:xls OR filetype:ppt”<BR>结果：已搜索有关资产负债表 filetype:doc OR filetype:xls OR filetype:ppt的中文(简体)网页。 共约有481项查询结果，这是第1-10项 。 搜索用时0.04秒。 <BR><BR>　　注意，下载的Office文件可能含有宏病毒，谨慎操作。<BR><BR>示例：搜索一些关于搜索引擎知识和技巧方面的PDF文档<BR>搜索：?quot;search engine" tips OR tutorial filetype:pdf”<BR>结果：已向英特网搜索"search engine" tips OR tutorial filetype:pdf. 共约有12,600项查询结果，这是第1-10项 。 搜索用时0.22秒。<BR><BR>　　我们来看其中的一个结果：<BR><BR>[PDF]Search Engines Tips<BR>文档类型: PDF/Adobe Acrobat - HTML 版<BR>... http://www.google.com/press/zeitgeist.html See what people are searching on at Google.com<BR>* Search Engine Watch http://searchenginewatch.com/ Some free tips ... <BR>www.allvertical.com/PromoKits/SearchEngineTips.pdf - 类似网页<BR><BR>　　可以看到，Google用[PDF]来标记这是一个PDF的文档检索，另外，它还给出了该PDF文档的HTML版本，该HTML版保留了文档的文字内容和结构，但没有图片。<BR><BR><SPAN style="COLOR: limegreen">8.3，搜索的关键字包含在URL链接中</SPAN><BR><BR>　　“inurl”语法返回的网页链接中包含第一个关键字，后面的关键字则出现在链接中或者网页文档中。有很多网站把某一类具有嗤?属性的资源名称显示在目录名称或者网页名称中，比如“MP3”、“GALLARY”等，于是，就可以用INURL语法找到这些相关资源链接，然后，用第二个关键词确定是否有某项具体资料。INURL语法和基本搜索语法的最大区别在于，前者通常能提供非常精确的专题资料。 示例：查找MIDI曲“沧海一声笑”。<BR>搜索：“inurl:midi “沧海一声笑””<BR>结果：已搜索有关inurl:midi "沧海一声笑"的中文(简体)网页。 共约有27项查询结果，这是第1-10项 。 搜索用时0.34秒。 <BR><BR>　　注意：“inurl:”后面不能有空格，Google也不对URL符号如“/”进行搜索。例如，Google会把“cgi-bin/phf”中的“/”当成空格处理。<BR><BR>　　“allinurl”语法返回的网页的链接中包含所有作用关键字。这个查询的关键字只集中于网页的链接字符串。<BR><BR>示例：查找可能具有PHF安全漏洞的公司网站。通常这些网站的CGI-BIN目录中含有PHF脚本程序（这个脚本是不安全的），表现在链接中就是“域名/cgi-bin/phf”。<BR>搜索：“allinurl:"cgi-bin" phf +com”<BR>结果：已向英特网搜索allinurl:"cgi-bin" phf +com. 共约有51项查询结果，这是第1-10项 。 搜索用时0.11秒。<BR><BR><SPAN style="COLOR: teal">8.4，搜索的关键字包含在网页标题中</SPAN><BR><BR>　　“intitle”和“allintitle”的用法类似于上面的inurl和allinurl，只是后者对URL进行查询，而前者对网页的标题栏进行查询。网页标题，就是HTML标记语言title中之间的部分。网页设计的一个原则就是要把主页的关键内容用简洁的语言表示在网页标题中。因此，只查询标题栏，通常也可以找到高相关率的专题页面。 示例：查找日本明星藤原纪香的照片集。<BR>搜索：“intitle:藤原纪香 "写真集"”<BR>结果：已搜索有关intitle:藤原纪香 "写真集"的中文(简体)网页。 共约有315项查询结果，这是第1-10项 。 搜索用时0.15秒。<BR><BR><SPAN style="COLOR: limegreen">8.5，搜索的关键字包含在网页的“锚”（anchor）链点内</SPAN><BR><BR>　　所谓“锚”，就是在同一个网页中快速切换链接点。与URL和TITLE类似，Google提供了两种对anchor的检索，“inanchor”和“allincnchor”。对此不作详述。<BR><BR><BR><B>9，其他罕用语法</B><BR><BR><SPAN style="COLOR: limegreen">9.1，搜索所有链接到某个URL地址的网页</SPAN><BR><BR>　　如果你拥有一个个人网站，估计很想知道有多少人对你的网站作了链接。而“link”语法就能让你迅速达到这个目的。<BR><BR>示例：搜索所有含指向华军软件园“www.newhua.com”链接的网页。<BR>搜索：“link:www.newhua.com”<BR>结果：搜索有链接到www.newhua.com的网页 。 共约有920项查询结果，这是第1-10项 。 搜索用时0.12秒。<BR><BR>　　注意：“link”不能与其他语法相混合操作，所以“link:”后面即使有空格，也将被Google忽略。另外还要说明的是，link只列出Google索引链接很小一部分，而非全部，所以如果你用Google没有搜到链到你的主页的链接，也不必灰心丧气。<BR><BR>　　除了上述功能，link语法还有其它妙用。一般说来，做友情链接的网站都有相似地方。这样，你可以通过这些友情链接，找到一大批具有相似内容的网站。比如说，你是个天文爱好者，你发现某网站非常不错，那么，可以用link语法查一下与之做链接的网站，也许可以找到更多符合你兴趣的内容。<BR><BR><SPAN style="COLOR: teal">9.2，查找与某个页面结构内容相似的页面</SPAN><BR><BR>　　“related”用来搜索结构内容方面相似的网页。例：搜索所有与中文新浪网主页相似的页面（如网易首页，搜狐首页，中华网首页等），“related:wwwsina.com.cn/index.shtml”。我到现在也不明白这个语法有什么作用，如果有谁知道，请不吝指教。预先感谢。:)<BR><BR><SPAN style="COLOR: limegreen">9.3，从Google服务器上缓存页面中查询信息</SPAN><BR><BR>　　“cache”用来搜索Google服务器上某页面的缓存，通常用于查找某些已经被删除的死链接网页，相当于使用普通搜索结果页面中的“网页快照”功能。<BR><BR>　　其它罕用语法如info、stock等不一一介绍，有兴趣的读者可以参阅Google大全。<BR><BR><BR><B>10，图片搜索</B><BR><BR>　　Google自称可以检索390,000,000张图片，并称自己为“互联网上最好用的图像搜索工具”。从使用结果来看，Google的图片搜索的确不错，但个人以为比AltaVista的还是要差一些，主要体现在检索图片数量比不上AV，匹配度比AV的图片搜索器也差了些。但AltaVista国内用户无法正常访问，因此对中国用户而言，Google的图片搜索引擎已经是最好的了。<BR><BR>　　Google首页点击“图像”链接就进入了Google的图像搜索界面“images.Google.com”。你可以在关键字栏位内输入描述图像内容的关键字，如“britney spears”，就会搜索到大量的小甜甜布兰妮的图片。我目前尚不是很清楚图片的排列标准，不过以观察来看，似乎图片文件名完全符合关键字的结果排列比较考前，然后才按照普通的页面搜索时的标准排列。<BR><BR>　　Google给出的搜索结果具有一个直观的缩略图（THUMBNAIL），以及对该缩略图的简单描述，如图像文件名称，以及大小等。点击缩略图，页面分成两祯，上祯是图像之缩略图，以及页面链接，而下祯，则是该图像所处的页面。屏幕右上角有一个“Remove Frame”的按钮，可以把框架页面迅速切换到单祯的结果页面，非常方便。<BR><BR>　　Google图像搜索目前支持的语法包括基本的搜索语法如“ ”、“-”、“OR”、“site”和 “filetype:”。其中“filetype:”的后缀只能是几种限定的图片类似，如JPG，GIF等。<BR><BR>示例：查找新浪网上本拉登的图片<BR>搜索：“拉登 OR 拉丹 site:sina.com.cn”<BR>结果：搜索有关 拉登 OR 拉丹 site:sina.com.cn 的图片。 共有6项查询结果，这是第1-6项。 搜索用时0.36秒。<BR><BR>　　这里我想说明一点的是，images.google.com作为专门的图片搜索引擎，实际上有其特殊的用途。<BR><BR>　　举个例子，互联网上本拉登的照片成千上万，但是，它们都是分散的，往往随机的分布于各种新闻报道中。如果用搜索图片库的方式（最容易想到的如“Ben Ladin photo”），来搜索本拉登的照片，显然是不恰当的，因为很少有人专门为拉登建一个在线相册。在这个时候，images.google.com就派上用场了。<BR><BR>　　但是，如果查找的图片在网上有很多主题“gallary”，如诸多电影电视明星的照片，则明显就不适合用images.google.com来查找了。<BR><BR>　　images.google.com对于很多报纸杂志的编辑，绝对是一个雪中送炭式的工具。比如要在某个版面上插一张专题图片，用google的图片搜索功能几秒钟就可以搞定。<BR><BR>　　综上，可以有这样的一般性结论：如果要搜索的图片是分散的，则用google图片搜索；如果要搜索的图片通常是处于某个图片集合中的，则不适合用google图片搜索。<BR><BR><BR><B>11，目录检索</B><BR><BR>　　如果不想搜索广泛的网页，而是想寻找某些专题网站，可以访问Google的分类目录“http://directory.Google.com/”，中文目录是“http://directory.Google.com/Top/World/Chinese_Simplified/”。分类的网站目录一般由专人负责，分类明确，信息集中。因此读者应该养成这样的习惯：首先考虑所需要的信息能否在一个专门主题的网站上找到。不过需要说明的是，用目录检索，往往需要用户对查询的领域很熟悉。否则，连查询的内容属于哪个类目都不知道，目录浏览也就无从谈及了。 目前Google使用的分类目录采用了ODP的内容。“Open Directory Project”是网景公司所主持的一项大型公共网页目录。由全世界各地的义务编辑人员来审核挑选网页，并依照网页的性质及内容来分门别类。因此，在某一目录门类中进行搜索往往能有更高的命中率。另外，Google根据其专业的“网页级别”（PageRank）技术对目录中登录的网站进行了排序，可以让一般的检索更具高效率。<BR><BR>示例：查找一下介绍搜索引擎方面的中文网站<BR>搜索：先进入中文简体分类目录，再进入“计算机”目录，再进入“互联网络”子目录，再进入“搜寻”子目录。我们看到在“World &gt; Chinese Simplified &gt; 计算机 &gt; 互联网络 &gt; 搜寻”下，还有两个子目录“分类目录 (33) 搜索引擎 (10)”，以及6个相关网站。显然，这些都是我们所需要的信息。<BR><BR>　　除了用鼠标层层点入，也可以在目录中检索。比如，在上例的“互联网络”目录下，选中“只在互联网络中搜索”选项，在搜索栏内填入“搜索引擎”进行搜索。<BR>结果：在分类Google 网页目录项中搜索搜索引擎。 共约有387项查询结果，这是第11-20项 。 搜索用时0.09秒。 <BR><BR>　　可以看到，上述查询结果比普通的检索更有效，因为在分类“互联网络”下进行搜索剔除了很多不相关的诸如新闻之类的无效信息。不过，对于中文用户而言，现在最大的问题是志愿的中文目录编辑太少，导致收录站点太少，因此搜索结果范围显得过于狭隘。但愿这个问题能随着Google以及ODP项目在国内名声的响亮而能得到改观。<BR><BR><BR><B>12，新闻组搜索</B><BR><BR>　　新闻组有详尽的分类主题，某些主题还有专人管理和编辑，具有大量的有价值信息。由于新闻组包含的信息实在是海量，因此不利用工具进行检索是不大可能的。DEJA一直是新闻组搜索引擎中的佼佼者。2001年2月份，Google将DEJA收购并提供了所有DEJA的功能。现在，除了搜索之外，Google还支持新闻组的WEB方式浏览和张贴功能。<BR><BR>　　进入Google新闻组“http://groups.Google.com/”，你有两种信息查找方式。一种是一层层的点击进入特定主题讨论组，另一种则是直接搜索。现在，我们进行一个最简单的搜索试验，查找一下新闻组中关于山顶洞人的讨论信息。<BR><BR>搜索：“山顶洞人”<BR>结果：在各群组内搜索 山顶洞人 共约有2,400项查询结果，这是第1-10项 。 搜索用时0.94秒。 搜索结果默认按照“留言内容”排列，但是你也可以点击“依照日期”按钮，让帖子按照发布日期排列。<BR><BR>　　因为新闻组中的帖子实在是多，而且又涉及一些普通搜索所没有的语法，所以建议使用“高级群组搜寻”进入高级搜索界面。新闻组高级搜索提供留言内容、分类主题、标题、留言者、留言代码、语言和发布日期作为条件进行搜索。其中作者项指作者发帖所用的唯一识别号电子信箱。<BR><BR><BR><B>13，Google的其他杰出功能</B><BR><BR><SPAN style="COLOR: blue">13.1网页快照</SPAN><BR><BR>　　网页快照是Google抓下来缓存在服务器上的网页。它有三个作用：<BR><BR>第一， 如果原地址打开很慢，那么可以直接查看Google缓存页面，因为Google服务器速度极快。<BR><BR>第二， 如果原链接已经死掉或者因为网络的原因暂时链接不通，那么可以通过Google快照看到该页面信息。当然，快照内容不是该页最新页面。<BR><BR>第三， 如果打开的页面信息量巨大，一下子找不到关键词所在位置，那么可以通过Google快照，因为快照中Google用黄色表明关键字位置。<BR><BR><SPAN style="COLOR: limegreen">13.2，集成化的工具条</SPAN><BR><BR>　　为了方便搜索者，Google提供了工具条，集成于浏览器中，用户无需打开Google主页就可以在工具条内输入关键字进行搜索。此外，工具条还提供了其他许多功能，如显示页面PageRank等。最方便的一点在于用户可以快捷的在Google主页、目录服务、新闻组搜索、高级搜索和搜索设定之间切换。欲安装Google的工具条，可以访问“http://toolbar.Google.com/”，按页面提示可以自动下载并安装。不过，Google工具条目前只支持IE5.0以上版本。<BR><BR>　　对于经常进行网络搜索者而言，Google工具条实在是必备的东西！！<BR><BR><SPAN style="COLOR: teal">13.3，单词英文解释</SPAN><BR><BR>　　写英文文章的时候，最头疼的事情就是对某个英文单词的用法不确定。现在有了Google，一切就迎刃而解了！无论你是想查找某个生词的意思还是想了解某个单词的用法，均可使用在线词典。<BR><BR>　　进入英文Google，输入你要查的单词。举个例子，我想查一下suggest的用法。结果如下：“Searched the web for suggest. Results 1 - 10 of about 8,000,000. Search took 0.08 seconds. ”注意看上面句子中，单词suggest下出现了一个横线，点击这个链接，就跳转到另外一个网站“http://www.dictionary.com/”，Google已经把单词提交给该网站的查询脚本。看看这个网站所提供的详尽解释吧。:)<BR><BR><SPAN style="COLOR: limegreen">13.4，网页翻译</SPAN><BR><BR>　　你懂英文，但是你不见得就懂德文、法文、拉丁文。如果搜索出来的页面是这些语言怎么办？呵呵，Google提供了网页翻译功能！！虽然目前只支持有限的拉丁语、法语、西班牙语、德语和葡萄牙文，但是我不得不承认，这是个杰出功能。<BR><BR>　　试着做以下搜索：“big bang site:fr”。这个表示查找关于宇宙大爆炸的法文网页。看第一条结果：<BR><BR>The Big Bang Website - [ Translate this page ]<BR>... A propos de Big Bang. Le dernier numéro en date. Les anciens numéros. Autres<BR>activités. Concerts progressifs en France. Emissions de radio. Liens. <BR>perso.club-internet.fr/calyx/bigbang/ - 3k - Cached - Similar pages<BR><BR>　　有点晕。没关系，点击“Translate this page”按钮。再看结果，嗯，大致能看明白，这原来是个叫“big bang”的乐队的网站，与大爆炸无关...<BR><BR>　　机器翻译是一个很前沿的人工智能课题，想指望翻译出来的结果跟专门用英语撰写的内容是不可能的。但西文间的互相转译比中英文机译强得多得多了。至少能看明白。<BR><BR><SPAN style="COLOR: teal">13.5，单词纠错</SPAN><BR><BR>　　笔者记忆力很差，英文单词经常拼写错误。但Google有纠错功能。比如在写上文的时候，我要用到英文单词“tutorial”，我只是依稀记得好像是“tatorial”的样子，但不肯定，于是用Google查了一下，它马上提醒：“您要找的会不会是： tutorial ”，呵呵，正是这个单词。<BR><BR><SPAN style="COLOR: limegreen">13.6，繁简转换</SPAN><BR><BR>　　对中文用户而言，常希望能同时检索繁体和简体信息。Google能做到这一点。Google默认使用繁简自动转换功能，因此你输入的简体关键字也将被转换成繁体做检索。这样省了不少力气。当然，如果你不希望这样的话，也可以在“使用偏好”中把这个选项关掉。<BR><BR><SPAN style="COLOR: teal">13.7，搜索结果过滤</SPAN><BR><BR>　　网络上的成人内容浩如烟海，而且很多站点具有欺骗或者其他不良企图，浏览者很容易掉入其中的陷阱。为此，Google新设立了成人内容过滤功能，见Google的设置页面，http://www.Google.com/preferences，最底下有一个选项SafeSearch Filtering。不过，中文状态下的Google尚没有这个功能。<BR><BR><BR><B>14，Google尚未发布的一些新特性和功能</B><BR><BR><SPAN style="COLOR: limegreen">14.1，对网页更新日期做出限定“daterange:”</SPAN><BR><BR>　　评价一个搜索引擎的好坏，更新频率是一个很关键因素。通常情况下，我们总希望能找到最新的网页。Google已经开发了对更新日期做限定的搜索语法，但目前还未公布。而且比较麻烦的是，Google现在支持的日期格式为julian（凯撒日）格式，把通用日期数值切换成julian格式需要借助第三方网站：http://www.tesre.bo.cnr.it/~mauro/JD/。不过，在下面这个自称是“Google终极搜索界面”的网页上，你已经可以利用Google的这项新特性了，它自动提供日期转换功能。<BR><BR>Google Ultimate Interface：http://www.faganfinder.com/google.html<BR><BR>　　Google为什么要这样做呢？也许是在测试阶段，不想让太多人使用吧。:)<BR><BR><SPAN style="COLOR: teal">14.2，新闻搜索“http://news.google.com/”</SPAN><BR><BR>　　Google的新闻搜索尚在B测试阶段，但使用起来已经非常不错了。新闻首页按头条新闻，各国新闻，以及不同领域做了分类。你可以通过Google搜索各大门户和新闻网站的新闻，简单、快捷、方便。遗憾的是，目前Google新闻只检索英文信息。<BR><BR><SPAN style="COLOR: limegreen">14.3，分类广告搜索“http://catalogs.google.com/”</SPAN><BR><BR>　　这也在B测试阶段。主要是对电子分类广告做检索。广告页为JPG图片格式。<BR><BR><SPAN style="COLOR: teal">14.4，其它Google的最新发展动态</SPAN><BR><BR>　　想了解Google公司的工程师们都在忙些什么吗？去看一下Google实验室（http://labs.google.com/）吧。Google的最新设想都在这个地方向访问者展现出来。现在处于发展和试验阶段的新功能有：术语查询、语音查询、键盘查询等等。<BR><BR>　　网络工程师和程序员可以看看这个地方：http://www.google.com/apis/，我想可以让你喜出望外的。<BR><BR><SPAN style="COLOR: limegreen">14.5，一个有趣的地方</SPAN><BR><BR>　　想看看世界各国网民都用Google搜索什么信息么？到http://www.google.com/press/zeitgeist.html看一下就知道了。从这些资讯中，你大致可以了解到世界热点和流行时尚走向。:)<BR><BR><BR><B>15，后记</B><BR><BR>　　这个文章4.0版本与3.0版本相比，变更很大，主要把一些与Google无关的东西删除了，另外随Google的变化作了一些修正，并增加了一些Google尚未发布的新功能。关于搜索技巧和搜索实例，是各个搜索引擎共通的东西，是搜索者长期的经验积累，要写出来，是件工程很浩大的事情，因此在这个小文章中我就不献丑了。<BR><BR>　　随着时间的推移，我发现搜索已经成为网络生活的一部分。工作需要搜索技术文档、客户信息；购物需要搜索商品信息和指南；娱乐需要搜索相关背景资料和图片。搜索已经变得无处不在，而Google则相应的成了工作和生活中的一个必备工具。套用雅虎的一句广告词，我们也许应该这样说：“今天你Google了吗？”<BR><img src ="http://www.blogjava.net/zhangrenquan/aggbug/27302.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/zhangrenquan/" target="_blank">kelven</a> 2006-01-09 19:44 <a href="http://www.blogjava.net/zhangrenquan/articles/27302.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>