﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-飞翔吧</title><link>http://www.blogjava.net/ytfei/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 03 May 2026 04:32:15 GMT</lastBuildDate><pubDate>Sun, 03 May 2026 04:32:15 GMT</pubDate><ttl>60</ttl><item><title>ubuntu 安装 jdk5</title><link>http://www.blogjava.net/ytfei/archive/2010/07/18/326474.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Sun, 18 Jul 2010 14:29:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2010/07/18/326474.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/326474.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2010/07/18/326474.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/326474.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/326474.html</trackback:ping><description><![CDATA[http://hi.baidu.com/zjd168/blog/item/6ac8ca9585614140d0135e4d.html<br />
<img src ="http://www.blogjava.net/ytfei/aggbug/326474.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2010-07-18 22:29 <a href="http://www.blogjava.net/ytfei/archive/2010/07/18/326474.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ubuntu 安装字体</title><link>http://www.blogjava.net/ytfei/archive/2010/07/18/326472.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Sun, 18 Jul 2010 14:05:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2010/07/18/326472.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/326472.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2010/07/18/326472.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/326472.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/326472.html</trackback:ping><description><![CDATA[http://www.fwolf.com/blog/post/170<br />
<img src ="http://www.blogjava.net/ytfei/aggbug/326472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2010-07-18 22:05 <a href="http://www.blogjava.net/ytfei/archive/2010/07/18/326472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Ubuntu 安装、卸载软件的命令 apt-get/dpkg</title><link>http://www.blogjava.net/ytfei/archive/2010/07/18/326471.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Sun, 18 Jul 2010 14:04:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2010/07/18/326471.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/326471.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2010/07/18/326471.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/326471.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/326471.html</trackback:ping><description><![CDATA[<h3 class="post-title entry-title">
<a href="http://hellwenwu.blogspot.com/2009/02/ubuntu-apt-getdpkg.html">Ubuntu
安装、卸载软件的命令 apt-get/dpkg</a>
</h3>
<div class="post-header">
</div>
<span class="Apple-style-span" style="color: #2a2a2a; line-height: 25px; font-family: Tahoma; font-size: 14px;">
<div><span class="Apple-style-span" style="font-size: medium;">更新软件信息数据库 apt-get
update<br />
进行系统升级 apt-get upgrade<br />
搜索软件包 apt-cache search softname1
softname2 softname3&#8230;&#8230;</span></div>
<div><span class="Apple-style-span" style="font-size: 130%;"><span class="Apple-style-span" style="font-size: 16px;"><br />
</span></span></div>
<div><span class="Apple-style-span" style="font-size: medium;">安装软件 apt-get install
softname1 softname2 softname3&#8230;&#8230;</span></div>
<span class="Apple-style-span" style="font-size: medium;">卸载软件 apt-get remove
softname1 softname2 softname3&#8230;&#8230;<br />
卸载并清除配置 apt-get remove --purge
softname1<br />
<br />
安装deb软件包 dpkg -i xxx.deb<br />
删除软件包 dpkg -r xxx.deb<br />
连同
配置文件一起删除 dpkg -r --purge xxx.deb</span></span>
<div><span class="Apple-style-span" style="color: #2a2a2a; line-height: 25px; font-family: Tahoma;"><span class="Apple-style-span" style="font-size: medium;"><br />
查看软件包信息 dpkg -info xxx.deb<br />
查看文件拷贝详情
dpkg -L xxx.deb<br />
查看系统中已安装软件包信息 dpkg -l<br />
重新配置软件包 dpkg-reconfigure xxx</span></span></div>
<img src ="http://www.blogjava.net/ytfei/aggbug/326471.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2010-07-18 22:04 <a href="http://www.blogjava.net/ytfei/archive/2010/07/18/326471.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>install (set up) linux ftp </title><link>http://www.blogjava.net/ytfei/archive/2007/04/07/109047.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Fri, 06 Apr 2007 16:34:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2007/04/07/109047.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/109047.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2007/04/07/109047.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/109047.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/109047.html</trackback:ping><description><![CDATA[http://www.linuxhomenetworking.com/wiki/index.php/Quick_HOWTO_:_Ch15_:_Linux_FTP_Server_Setup<br>
<br>
http://rimuhosting.com/howto/ftp.jsp<br>
<br>
<br>
<p>FTP (File Transfer Protocol) is a common way of moving files between
computers.&nbsp; By default your RimuHosting server will not have FTP enabled.</p>
<p>Do you really need to run FTP?  For example, if you are going to be the only person
moving files to and from your server, then you may not need it.&nbsp; Try our <a  href="http://rimuhosting.com/howto/scp.jsp">scp howto</a> instead.</p>
<p>To enable FTP, first edit the vsftpd.conf file (e.g. <code>vi /etc/vsftpd/vsftpd.conf</code>).&nbsp; Then:</p>
<ul>
    <li>Consider changing anonymous_enable=YES to anonymous_enable=NO</li>
    <li>Uncomment the "nopriv_user=ftpsecure" line</li>
    <li>Uncomment the "write_enable=YES" line (else you'll get an error
    like '550 Permission denied.' from your FTP client when you upload a
    file or create a directory)</li>
    <li>Uncomment the "local_enable=YES" line (else you'll get an error
    like '500 OOPS: vsftpd: both local and anonymous access disabled!')</li>
    <li>Add a "chroot_local_user=YES" line. This will trap your FTP users
    in their own /home/username directory. Otherwise they will be able to
    see and update some files outside their home directory.</li>
</ul>
<p>Then create a non-super user that vsftp will run as.&nbsp; Note: this is not the FTP username you'll use
when logging into your FTP server.</p>
<pre class="codebox"><code><br># create an unpriviledged user that will run the vsftpd service<br>adduser -s /sbin/nologin ftpsecure<br>sed --in-place 's/^anonymous_enable=YES/anonymous_enable=NO/ig' /etc/vsftpd/vsftpd.conf<br>sed --in-place 's/^anon_upload_enable=YES/anon_upload_enable=NO/ig' /etc/vsftpd/vsftpd.conf<br></code></pre>
<p>Then, most redhat distributions you can then run: </p>
<p><code>chkconfig --level 35 vsftpd on &amp;&amp; /etc/init.d/vsftpd start</code></p>
<p>Or, on a RedHat 8 distribution:</p>
<pre class="codebox"><code><br>vi /etc/xinetd.d/vsftpd<br># ... and change the disable = yes to disable = no<br><br># then restart xinetd<br>/etc/init.d/xinetd restart<br></code></pre>
<p>The ftp daemon will not let you log in as root (?why?).&nbsp; Try a log in as
a non-super user.&nbsp; To create such a user:</p>
<pre class="codebox"><code><br># add the user, use the -s (shell) option if you do not want the <br># user to be able to ssh into the server (else skip it)<br>adduser -s /sbin/nologin yourusername<br>passwd yourusername<br># you will be prompted for a password<br># now, log in to your ftp server using this username and password<br></code></pre>
<h1>Locking FTP Users Into Their Home Directories</h1>
<p>By default FTP users can read and write files any files on the server, provided they have
access to read/write those files.</p>
<p>You can also set things up so that FTP users only see files under their home
directory.&nbsp; This can often be a more secure setup.&nbsp; To do this just
add <code>chroot_local_user=YES</code> in vsftpd.conf (and restart vsftpd). e.g. </p>
<pre class="codebox"><code><br>sed --in-place 's/^anonymous_enable=YES/anonymous_enable=NO/ig' /etc/vsftpd/vsftpd.conf<br>sed --in-place 's/^anon_upload_enable=YES/anon_upload_enable=NO/ig' /etc/vsftpd/vsftpd.conf<br>if ! test -e /etc/vsftpd/vsftpd.conf; then <br>    echo /etc/vsftpd/vsftpd.conf not found<br>elif grep -qai chroot_local_user=YES /etc/vsftpd/vsftpd.conf; then <br>    echo "chroot_local_user directive already existed"<br>else <br>    echo "Adding the chroot_local_user directive"<br>    echo "chroot_local_user=YES" &gt;&gt; /etc/vsftpd/vsftpd.conf<br>fi<br>/etc/init.d/vsftpd restart<br></code></pre>
<p>When a user logs in, if there directory was /home/user/html, they
would see /html. They're locked into /home/user, and
/home/user becomes their root (/) directory.</p>
<br>
<br><img src ="http://www.blogjava.net/ytfei/aggbug/109047.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2007-04-07 00:34 <a href="http://www.blogjava.net/ytfei/archive/2007/04/07/109047.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ant 的使用</title><link>http://www.blogjava.net/ytfei/archive/2006/10/20/76397.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Fri, 20 Oct 2006 07:48:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2006/10/20/76397.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/76397.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2006/10/20/76397.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/76397.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/76397.html</trackback:ping><description><![CDATA[
		<blockquote>转自:http://www.csbus.com/forum/ShowDetail.asp?Ici_ID=849&amp;ForumID=5&amp;ForumName=%D4%B1%B9%A4%D6%AE%BC%D2<br /><br /><br />本文主要介绍 Ant 在多用户开发的情况下，如何用 Eclipse，并且根据不同的目标环境编译不同的部署包。文中首先介绍一个场景，给出在开发、编译、部署过程中遇到的问题；然后介绍如何用 Eclipse 来简化你的 Ant 开发过程；文章的最后解释如何通过编写有效的 Ant 脚本来提高你的工作效率。</blockquote>
		<!--START RESERVED FOR FUTURE USE INCLUDE FILES-->
		<!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters -->
		<!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
		<p>读者定位为具有 Java 和 Ant 使用经验的开发人员。</p>
		<p>读者可以学习到如何使用 Ant 解决一些多用户开发环境中，根据不同的目标环境编译成不同部署包的问题。</p>
		<p>
				<a name="N10061">
						<span class="atitle">
								<font face="Arial" size="4">工作场景</font>
						</span>
				</a>
		</p>
		<p>现在有一个 web 项目，是多人进行开发的，通过 CVS 来管理。另外该项目还有一些测试人员，他们测试部署在测试服务器上的应用程序，发现 bug 后通过 bug 管理系统通知开发人员，在开发人员修复 bug 并经过本地测试后，由专门的人负责检出（check out）代码，编译打包后部署到测试服务器上。</p>
		<p>该项目的成员小A就是负责检出代码、编译打包，并部署到服务器上的人。除了这个任务之外，他还是该项目的编程人员。在项目进入测试阶段后，小A在得到组中别的成员修复了 bug 并且检入（check in）了代码的消息后（也有可能是小A自己检入了代码），小A首先更新本地的代码，先在本地做测试，确认修复了 bug 后打成 WAR 包部署到测试服务器上，并通知测试人员已经修复了 bug，让测试人员继续进行测试。</p>
		<p>
				<a name="N1006C">
						<span class="smalltitle">
								<strong>
										<font face="Arial" size="3">小A的烦恼</font>
								</strong>
						</span>
				</a>
		</p>
		<p>在该项目中，有一些为测试方便开发而写的代码和页面，比如跳过用户认证，但是在部署到测试机环境的时候，需要删除这些代码和页面；另外作为一个具有灵活性和扩展性的应用程序，又有一些配置文件，配置文件中的值会根据环境的改变而变动。例如，在项目中使用了 Log4j 记录日志，需要给 Log4j 指定日志文件的保存路径，本地程序员开发的时候用的是 Windows 系统，给 Log4j 指定的也是 Windows 的文件系统，在测试阶段的时候，需要部署到 Linux 系统中，那么日志的保存路径也需要做相应的改动。部署到测试服务器上的时候，除了 Log4j 需要改之外，还有很多别的配置项目也需要变动，并且分散在各个 package 中。小A的烦恼也随之而来，每次他在做完本地测之后，就根据测试机的需要逐个找配置文件，更改相应的值，并删除那些为测试方便写的代码和页面，每天可能根据需要做好几次这样的事情，最烦的是他在快做完对测试机环境更改的时候，某开发人员突然通知小A说：“我又改了一点代码，刚检入，你再重打一个包吧。”，小A又不得不从头开始做新一轮的检出代码、本地测试、更改配置文件、删除不需要的文件、打包部署的工作。另外小A在测试阶段的后期被通知要求除了每次生成一个测试环境的 WAR 包外还必须生成一个在产品环境下的 WAR 包，他做的事情就更多了。</p>
		<p>从上面的场景可以看出，小A的工作效率低而且容易出错，甚至有可能导致整个项目的工作效率低下。其实可以通过 Ant 来帮助小A快速而且有效地完成这个工作。在 Ant 中，根据目标环境的需要，可以把所有要更改的配置文件的项目集中写到某个配置文件中。这样根据不同的目标环境得到不同的配置文件，Ant 在编译包时根据不同的目标环境切换不同的配置文件即可。比如小A现在碰到的有 3 中环境：开发环境、测试环境以及产品环境，根据这三种环境可以生成三个不同的配置文件：develop_deploy.property、test_deploy. property和product_deploy. property，当小A想生成不同的包时只需在这三个配置文件之间切换就可以了。</p>
		<p>在正式开始编写脚本之前，我们需要下载安装相应的软件。</p>
		<ul>
				<li>Eclipse：为了使 Ant 的开发更加简单，我们选择了 Eclipse3.1 作为开发环境。当然你可以使用任何你喜欢的文本编辑工具来开发你的 Ant。Eclipse 的最新版本可以在 <a href="http://eclipse.org/"><u><font color="#5c81a7">http://eclipse.org/</font></u></a> 上下载。 
</li>
				<li>Ant：Ant 是基于 Java 的编译工具，它就像 C/C++ 中的 make，但是没有 make 那样难用。Ant 的最新版本可以在 <a href="http://ant.apache.org/bindownload.cgi"><u><font color="#5c81a7">http://ant.apache.org/bindownload.cgi</font></u></a> 上下载。如果你用 Eclipse 来开发 Ant，则不用去单独下载 Ant，因为在 Eclipse 中已经集成了 Ant。 
</li>
				<li>CVS 客户端（cvs.exe）：CVS 可以在 <a href="http://www.nongnu.org/cvs/"><u><font color="#5c81a7">http://www.nongnu.org/cvs/</font></u></a> 上下载 </li>
		</ul>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10092">
						<span class="atitle">
								<font face="Arial" size="4">用 Eclipse3.1 来创建 Ant 脚本</font>
						</span>
				</a>
		</p>
		<p>如果你使用 Eclipse 来编写 Ant，建议使用 Eclipse 3.1 以后的版本。除了以前 Ant 编辑器提供的语法高亮，提示语法错误等功能外，Eclipse3.1 版本增加了许多新的功能。比如：脚本代码的折叠；快速定位某属性或者目标（target）段的定义；在同一 builder 文件中重构属性名和目标名（快捷方式Alt + Shift +R）；调试 Ant 脚本等。</p>
		<p>下面我们就来看看 Eclipse 3.1 中对 Ant 的支持</p>
		<ul>
				<li>
						<p>打开“File”－“New”－“Project”－“Simple”－“Project”，点击“Next”，输入工程名“Ant”，然后点击直到“Finish”</p>
				</li>
				<li>
						<p>在新建的 Ant 工程中，新建 Test.xml，并且拷贝下面的脚本。该段脚本的内容就不做介绍了，我们主要看 Eclipse 提供了哪些功能。注意这时候打开的并不是 Ant 编辑器，将内容拷贝进去之后，关掉打开的“Test.xml”，然后再重新打开它，这样 Eclipse 就会用 Ant 编辑器打开它，并且也语法高亮了。</p>
						<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
								<tbody>
										<tr>
												<td>
														<code>
																<pre class="section">&lt;?xml version='1.0' encoding='UTF-8'?&gt;
&lt;project name='Test' default='init' basedir='.'&gt;
&lt;property name='test' value='test'/&gt;
&lt;target name='init'&gt;
	&lt;echo&gt;${test}&lt;/echo&gt;
&lt;/target&gt;
&lt;/project&gt;
</pre>
														</code>
												</td>
										</tr>
								</tbody>
						</table>
						<br />
				</li>
				<li>
						<p>自动提示和代码折叠功能。如果是 Ant 内置的命令或者前面已经定义的变量，编辑器会自动提示；编辑器右边的加/减号可以代码折叠。如下所示：</p>
						<img alt="图1：编辑器右边的加/减号可以代码折叠" src="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/image001.jpg" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
				</li>
				<li>
						<p>快速定位目标（target）或者定义变量处。在上图中，将鼠标移至 default=”init” 中的 init 上之后，按下 ctrl 键，鼠标变成手状，单击就可以定位到定义该目标的地方</p>
				</li>
				<li>
						<p>快速重构目标名或者属性名。选中目标/属性名，按下 Alt + Shift + R，然后键入你要修改后的值，所有引用到的地方都会随之改动。如下图所示，选中 init 后，按下快捷键，改成 initial：</p>
						<img alt="图2：改成 initial" src="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/image002.jpg" onload="javascript:if(this.width&gt;500)this.width=500" />
				</li>
				<li>
						<p>调试 Ant 脚本。在标签“&lt;target name=..”的左边设置一断点，然后在编辑器中右击，出现的菜单中选“Debug As”－“Ant Build”，出现后的窗口与调试 Java 程序的界面差不多。</p>
						<p>这是调试窗口，这里可以选择单步跟进、跳出等：</p>
						<img alt="图3：选择单步跟进、跳出等" src="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/image003.jpg" onload="javascript:if(this.width&gt;500)this.width=500" />
						<p>下面是运行时变量窗口。可以看到 test 变量的值是“test”：</p>
						<img alt="图4：test 变量的值是 test" src="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/image004.jpg" onload="javascript:if(this.width&gt;500)this.width=500" />
						<p>运行结果窗口：</p>
						<img alt="图5：运行结果窗口" src="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/image005.jpg" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
				</li>
		</ul>
		<p>由此可见，如果使用好 Eclipse Ant 编辑器所提供强大的功能的话能大大提高写 Ant 脚本的效率。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100DD">
						<span class="atitle">
								<font face="Arial" size="4">Ant 中使用 property（属性）文件</font>
						</span>
				</a>
		</p>
		<p>刚开始写 Ant 的初学者可能会把所有的信息都放在 build.xml 中，下面就是这样的一个例子。</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;project name='testBuild' default='compile' basedir='.'&gt;
&lt;target name='init'&gt;
	&lt;mkdir dir='c:/temp/dest/testProj' /&gt;
&lt;/target&gt;
&lt;target name='compile' depends='init'&gt;
	&lt;javac srcdir='c:/temp/src/testProj' destdir='c:/temp/dest/testProj '/&gt;
&lt;echo&gt;Build into c:/temp/dest/testProj, successfully.&lt;/echo&gt;
&lt;/target&gt;
&lt;/project&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在上面的例子中，所有的路径信息都是写在 build.xml 中。但是 Ant 脚本可能在不同的机器或者不同的系统上运行，也有可能一些值需要根据环境的不同而变化，在 Ant 中可以把所有这些可能变化的地方都放到一个配置文件中，然后在 Ant 脚本中引用这个配置文件就可以了，针对上面的例子，如下所示：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;project name='testBuild' default='compile' basedir='.'&gt;
	&lt;property file='build.properties'/&gt;
	&lt;target name='init'&gt;
		&lt;mkdir dir='${dest.dir}' /&gt;
	&lt;/target&gt;
	&lt;target name='compile' depends='init'&gt;
		&lt;javac srcdir='${src.dir}' destdir='${dest.dir}'/&gt;
		&lt;echo&gt;Build into ${dest.dir}, successfully.&lt;/echo&gt;
	&lt;/target&gt;
&lt;/project&gt;
build.properties的内容：
dest.dir=c:/temp/dest/testProj
src.dir=c:/temp/src/testProj
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>如果想在 Ant 脚本中引用值的话，只需用$符号开头，在一对'{}'中写入要引用的键值。如上例中，需要引用编译的目标路径用'${dest.dir}'。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N100F3">
						<span class="atitle">
								<font face="Arial" size="4">使用 Ant 任务从 CVS 中检出（check out）源代码，并编译打包</font>
						</span>
				</a>
		</p>
		<p>Ant 中提供了 cvs 任务（Task）可以从 CVS 服务器中检出资源（注意：在使用 Ant 的 cvs 任务之前，请先将 cvs.exe 下载到你的机器，并且将它添加到你本地的 PATH 环境变量中，然后重新启动 Eclipse。否则在执行下面脚本的时候就会得到 error=2 的错误）。cvs 的可选用属性很多，在这里介绍经常使用到的几个属性。从 CVS 中检出资源一般需要指定：</p>
		<ul>
				<li>CVS 所在的服务器地址：目标 CVS 服务器地址 
</li>
				<li>用户名：登录该 CVS 服务器你指定的用户名 
</li>
				<li>密码：登录该 CVS 服务器需要的密码 
</li>
				<li>库路径（Repository Path）：服务器中的库路径 
</li>
				<li>模块名：当前需要检出的模块名，一般都是以工程的名字作为模块名 
</li>
				<li>标签名：需要从 CVS 中检出哪个标签 </li>
		</ul>
		<p>在介绍使用 Ant 的 cvs 之前，先说一下本地的目录结构。在 C 盘的 temp 目录下，分别有四个目录，如下所示：</p>
		<ul>
				<li>build 目录：放编译后的类以及资源文件 
</li>
				<li>dist 目录：放生成的 jar 文件或者 war 文件 
</li>
				<li>lib 目录：放在编译过程中需要用到的 jar 文件 
</li>
				<li>src 目录：放从 cvs 中检出的源文件（包括 JSP 等）<br /><img alt="图6：src 目录" src="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/image006.jpg" onload="javascript:if(this.width&gt;500)this.width=500" /></li>
		</ul>
		<p>在 Ant 中这样写就可以从中检出资源：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  &lt;cvs cvsRoot=':pserver:username:pwd@cvs.server:/home/testPath' 
package='TestProj' dest=' c:/temp/src/testProj ' failonerror='true' /&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这段脚本片断的意思就是从叫'cvs.server'的服务器中，用用户名是 username、密码为 pwd 的用户检出在库路径是 /home/testPath 下的 TestProj 模块（项目），检出后的资源放入本地目录 c:/temp/src/testProj 中。在上面这段脚本中，可以看到有很多值可能会根据不同的环境或者用户随之改变的，比如用户名和密码等；而且从脚本的重复可利用性来说，需要把有些值抽出来放到配置文件中，如服务器的地址和库路径等。因此把这些可能需要更改的地方放到 property 文件中，效果会更好。改完后的完整 Ant 脚本如下所示：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  &lt;?xml version='1.0'?&gt;
&lt;project name='testWeb' default='checkout' basedir='.'&gt;
	&lt;target name='checkout'&gt;
		&lt;property file='TestWeb.properties' /&gt;
		&lt;cvs cvsRoot='${cvs.root}' package='${cvs.projectName}' 
tag='${cvs.tag}' dest='${src.dir}' failonerror='true' /&gt;
	&lt;/target&gt;
&lt;/project&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>对应的 TestWeb.properties 文件内容如下所示：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">base.dir=c:/temp/
src.dir=${base.dir}/src

cvs.server=cvs.server
cvs.user=username
cvs.pw=pwd
cvs.repositoryPath=/home/testPath
cvs.projectName=TestProj
cvs.root=:pserver:${cvs.user}:${cvs.pw}@${cvs.server}:${cvs.repositoryPath}
cvs.tag=
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在检出了资源后，需要对其进行编译打包。为了使 Ant 脚本更加具有可读性和灵活性，我们需要对上面的 Ant 脚本进行一些改动。首先将 Ant 脚本中进行分段，如下所示：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;?xml version='1.0'?&gt;
&lt;project name='testWeb' default='all' basedir='.'&gt;
	&lt;target name='all' depends='init,clean,checkout,build'&gt;
    &lt;!--脚本的入口点--&gt;
	&lt;/target&gt;
	&lt;target name='init'&gt;
    &lt;!--做初始化属性文件和设置classpath等设置初始条件--&gt;
	&lt;/target&gt;
	&lt;target name='clean'&gt;
     &lt;!--删除上一次留下的没用的目录和文件--&gt;
	&lt;/target&gt;
	&lt;target name='checkout'&gt;	
     &lt;!--从CVS中检出资源--&gt;
	&lt;/target&gt;
	&lt;target name='build'&gt;
     &lt;!--编译源文件并打包到指定的目录--&gt;
	&lt;/target&gt;
&lt;/project&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>上面的脚本中，总共分成了5个目标（target），脚本的入口点是'all'，all 按顺序调用 init，clean，checkout，build。其中：</p>
		<ul>
				<li>init 是用来做初始化属性文件和设置 classpath 等设置初始条件的事情 
</li>
				<li>clean 用来删除上一次留下的没用的目录和文件 
</li>
				<li>checkout 已经介绍过了，是用来从 CVS 中检出资源 
</li>
				<li>build 用来编译源文件并打 WAR 包到指定的目录 </li>
		</ul>
		<p>详细的 Ant 脚本可以参见随本文所附的 TestWeb.xml 和 TestWeb.properties。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N10159">
						<span class="atitle">
								<font face="Arial" size="4">编译过程与产生不同目标环境的脚本分开执行</font>
						</span>
				</a>
		</p>
		<p>在前面介绍的 Ant 脚本中，根据从 CVS 服务器中检出的资源打成了一个默认的 war 包，并没有考虑根据不同的目标环境来生成不同的包，从下一节开始介绍如何根据不同的环境来生成不同的部署包。</p>
		<p>还有一个问题是：为什么需要把从 CVS 中检出资源、编译的过程跟根据目标环境打包的过程分开？</p>
		<p>这是因为本身 CVS 检出资源是需要花一定的时间，如果资源比较多这个过程就会花费挺长时间；另外，在多人开发的情况下必须保证在生成不同的部署包的时候是用的是同一套代码生成的，否则会出现各个服务器上运行的版本不一致，如果检出资源、编译的过程跟生成包的脚本一起执行的话就会出现这个问题（比如小A在测试服务器测试通过的时候之后，再生成一个在产品环境下的部署包，如果分两次从 CVS 服务器中检出资源的话，在此期间可能会有开发人员往 CVS 服务器中检入代码，导致生成的版本不一致），因此，必须将这两个过程分开执行。现在我们开始建立另外一个 Ant 脚本文件，叫 deploy.xml，专门用来生成包；另外与 deploy.xml 相对应的还有一个 deploy.properties 文件。在 deploy.xml 中会引用 deploy.properties 文件。另外根据在前面的场景中碰到的环境，创建三个不同的属性文件, develop_deploy.property、test_deploy. property 和 product_deploy. Property，在打包的时候，根据不同的目标环境，将相应属性文件中的内容拷贝至 deploy.properties 文件中（或者也可以直接在 deploy.xml 中直接切换不同的属性文件），然后在 Eclipse 中直接执行 deploy.xml；如果在命令行中，可以用下面的命令来执行：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  ant –f deploy.xml
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1016B">
						<span class="atitle">
								<font face="Arial" size="4">解开 WAR 包</font>
						</span>
				</a>
		</p>
		<p>我们首先得建立一个目录（这里是 unpack）用来存放解压后的文件。Ant 中提供了 unzip 命令用来解压 ear/war/jar 包。除了这个目录外，根据不同的目标环境，在运行目录下建立一个与目标环境相对应的目录，重新打好的 war 包就放在这个目录下，比如针对场景中的情况，如果需要创建一个产品环境下的部署包，我们可以建立一个 TestWebProduct 目录，目录名写在配置文件中（${pack.base.dir}）。</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  &lt;target name='init'&gt;
		&lt;echo&gt;init in deploy&lt;/echo&gt;
		&lt;property file='deploy.properties' /&gt;
		&lt;delete dir='${unpack.base.dir}' failonerror='false' /&gt;
		&lt;delete dir='${pack.base.dir}' failonerror='false' /&gt;
		&lt;mkdir dir='${unpack.base.dir}' /&gt;
		&lt;mkdir dir='${pack.base.dir}' /&gt;
	&lt;/target&gt;

	&lt;target name='unpack'&gt;
		&lt;echo&gt;unpack the ${war.name}&lt;/echo&gt;
		&lt;copy file='${dest.dir}/${war.name}' todir='${unpack.base.dir}' /&gt;
		&lt;unzip src='${unpack.base.dir}/${war.name}' dest='${unpack.base.dir}/${projectName}' /&gt;
		&lt;delete file='${unpack.base.dir}/${war.name}' /&gt;
	&lt;/target&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在 init 段中首先删除掉上次解压的目录和目标打包目录，然后重新建立目录；在 unpack 中，首先将编译好的默认 war 包拷贝至 unpack 定义的目录，解压之后把 unpack 下的 war 包删除。下面是这时候对应的属性文件。</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">projectName=MTSWeb
war.name=MTSWeb.war

#根目录
base.dir=c:/temp
#默认的war包所在的目录
dest.dir=${base.dir}/dist
#解压后的目录
unpack.base.dir=${base.dir}/unpack
#目标环境相对应的目录
pack.base.dir=${base.dir}/TestWebProduct
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1017E">
						<span class="atitle">
								<font face="Arial" size="4">利用 Ant 提供的 filter 任务替换属性值</font>
						</span>
				</a>
		</p>
		<p>现在根据不同环境的需要，对某些配置文件的值做一些替换。在 Ant 中，提供了 filter 任务，使得替换值很方便。当然也可以使用下面介绍的正则表达式来替换属性值。filter 主要用来在同一行内容中的替换，而正则表达式一下子可以替换多行内容。filter 的使用例子：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  &lt;filter token=' log4j.logger' value='INFO'/&gt;
  &lt;copy todir='${dest.dir}' filtering='true'&gt;
    &lt;fileset dir='${src.dir}'/&gt;
  &lt;/copy&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>这段脚本的意思就是在 src.dir 目录下的所有文件中，如果有预先定义好的'@log4j.logger@'占位符的话，在拷贝到 dest.dir 目录后，所有的占位符都被替换成了'INFO'。</p>
		<p>你也可以将所有被替换的值放到某个属性文件中，filter 任务将属性文件中的每一个条目读出来并且设置成一个 Filter。如下所示：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">  &lt;filter filtersfile='deploy_env.properties'/&gt;
  &lt;copy todir='${dest.dir}' filtering='true'&gt;
    &lt;fileset dir='${src.dir}'/&gt;
  &lt;/copy&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>上面的脚本表示所有在 deploy_env 中出现的条目将被作为一个 filter，在拷贝到 dest.dir 目录后，所有 src.dir 目录中存在的占位符将被替换成 deploy_env 中的值。具体的例子可以参见随本文附带的 deploy.xml， deploy_env.properties 和 Test.properties。 </p>
		<p>其中 deploy.xml 是 ant 脚本，deploy_env.properties 中包含所有要替换的值，在 Test.properties 中是包含有占位符的资源文件。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N1019A">
						<span class="atitle">
								<font face="Arial" size="4">利用正则表达式替换属性值</font>
						</span>
				</a>
		</p>
		<p>Ant 中支持多种正则表达式，在运行 Ant 的时候用哪种正则表达式可以通过设置 ant.regexp.regexpimpl 的值来切换，Ant 支持的的正则表达式有：</p>
		<ul>
				<li>java.util.regex package of JDK 1.4 
</li>
				<li>jakarta-regexp 
</li>
				<li>installation dependencies </li>
		</ul>
		<p>正则表达式的例子：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;replaceregexp byline='true'&gt;
&lt;regexp pattern='正则表达式'/&gt;
&lt;substitution expression='将要替换的值'/&gt;
&lt;fileset dir='${unpack.war.dir}/WEB-INF' includes='web.xml'/&gt;
&lt;/replaceregexp&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>byline 属性用来确认被替换的时候是一次替换一行还是多行；pattern 属性用来指明正则表达式；substitution expression 中是替换的值，替换的值都定义在相对应的配置文件中；fileset 属性中的 dir 用来指定被替换文件所在的目录，includes 用来指定要替换哪个文件。需要注意的是，如果在正则表达式或者替换的值中出现'&lt;'的话，需要用转义符'&lt;'。</p>
		<p>在 Eclipse3.1 中已经内置了对正则表达式的支持；但是如果你在命令行中运行需要正则表达式支持的脚本的话，则需要自己将正则表达式的包下载下来加到 classpath 中。在随文章的 deploy.xml 中提供了一个简单的替换属性文件的值的例子。正则表达式的例子可以在本文所带的 deploy.xml 中找到。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101BB">
						<span class="atitle">
								<font face="Arial" size="4">Ant 使用条件表达式，根据属性值删除不需要的文件</font>
						</span>
				</a>
		</p>
		<p>在生成部署包的时候，还有可能会根据目标环境的不同，删除一些不同的文件。比如在产品环境中那些作为测试需要的代码往往需要删除，但是测试环境中并不需要。因此就需要条件表达式来做判断。如下所示：</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;target name='checkTestEnv'&gt;
	&lt;condition property='isTestEnv'&gt;
		&lt;istrue value='${deploy.isTestEnv}' /&gt;
	&lt;/condition&gt;
	&lt;antcall target='trueCondition' /&gt;
	&lt;antcall target='falseCondition' /&gt;
&lt;/target&gt;
&lt;target name='trueCondition' if='isTestEnv'&gt;
	&lt;echo message='true condition in ${projectName}' /&gt;
&lt;/target&gt;
&lt;target name='falseCondition' unless='isTestEnv'&gt;
	&lt;echo message='false condition in ${projectName}' /&gt;
&lt;/target&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>在上面的例子中，先读出 ${deploy.isTestEnv} 的值（在配置文件 deloy.properties 中），根据读出的值对属性 isTestEnv 设值，如果 ${deploy.isTestEnv} 的值是 true，isTestEnv 的值也是 true；否则是 false。然后分别调用目标段 trueCondition 和 falseCondition。在这里，表达式值的判断是用'istrue'，在 Ant 中还提供了很多别的表达式，比如 not/and/or，equals 等等，具体关于条件表达式的信息可以参考：<a href="http://ant.apache.org/manual/CoreTasks/condition.html" target="_blank"><u><font color="#5c81a7">http://ant.apache.org/manual/CoreTasks/condition.html</font></u></a> ，该页也可以在随下载下来的文档中找到。</p>
		<p>在段 trueCondition 中，判断 isTestEnv，如果是真的话就运行，否则不运行；在段 falseCondition 中，也判断 isTestEnv，如果是假就运行，否则不运行，在段中可以根据情况做相应的事情。条件判断式的例子可以在本文的 deploy.xml 中找到。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101D2">
						<span class="atitle">
								<font face="Arial" size="4">重新打包，并拷贝到不同的目录</font>
						</span>
				</a>
		</p>
		<p>在上面的替换过程完成后，调用 war 将 unpack 目录下的内容重新打包。</p>
		<table cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee" border="1">
				<tbody>
						<tr>
								<td>
										<code>
												<pre class="section">&lt;target name='repack'&gt;
	&lt;war destfile='${pack.base.dir}/${projectName}.war' 
		basedir='${unpack.base.dir}/${projectName}'
		webxml='${unpack.base.dir}/${projectName}/WEB-INF/web.xml' 
		manifest='${unpack.base.dir}/${projectName}/META-INF/MANIFEST.MF'&gt;
	&lt;/war&gt;
&lt;/target&gt;
</pre>
										</code>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<p>详细的例子可以参见随本文的附件 deploy.xml 和 deploy.properties。</p>
		<br />
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td>
										<img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="500" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
								</td>
						</tr>
				</tbody>
		</table>
		<table class="no-print" cellspacing="0" cellpadding="0" align="right">
				<tbody>
						<tr align="right">
								<td>
										<img height="4" alt="" src="http://www.ibm.com/i/c.gif" width="100%" onload="javascript:if(this.width&gt;500)this.width=500" />
										<br />
										<table cellspacing="0" cellpadding="0" border="0">
												<tbody>
														<tr>
																<td valign="center">
																		<img height="16" alt="" src="http://www.ibm.com/i/v14/icons/u_bold.gif" width="16" onload="javascript:if(this.width&gt;500)this.width=500" border="0" />
																		<br />
																</td>
																<td valign="top" align="right">
																		<a class="fbox" href="http://www-128.ibm.com/developerworks/cn/java/j-lo-ant-eclipse/index.html#main">
																				<b>
																						<font color="#996699">回页首</font>
																				</b>
																		</a>
																</td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
		<br />
		<br />
		<p>
				<a name="N101E1">
						<span class="atitle">
								<font face="Arial" size="4">结论</font>
						</span>
				</a>
		</p>
		<p>通过本文可以看出编写好有效的 Ant 脚本能很好的解决在编译部署包的时候出现的问题，将那些变化的内容放到配置文件中，在部署的时候切换不同的配置文件就可以实现生成不同的部署包。文中也介绍了如何使用 Eclipse 来提高你编写/调试 Ant 脚本的效率。</p>
<img src ="http://www.blogjava.net/ytfei/aggbug/76397.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2006-10-20 15:48 <a href="http://www.blogjava.net/ytfei/archive/2006/10/20/76397.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>axis1.x开发webservices实例</title><link>http://www.blogjava.net/ytfei/archive/2006/08/29/66500.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Tue, 29 Aug 2006 11:08:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2006/08/29/66500.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/66500.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2006/08/29/66500.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/66500.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/66500.html</trackback:ping><description><![CDATA[一、Axis安装 1、环境 J2SE SDK 1.3 or 1.4: 我使用 1.4.2 Servlet Container: 我使用的Tomcat 5.0 <br /><br />2、到 http://ws.apache.org/Axis/网站下载Axis安装包<br /><br />3、解压缩安装包，将Axis_UNZIP_PATH\Axis-version\webapps下的Axis包拷贝到TOMCAT_HOME\webapps\下，以下约定Axis_HOME为该TOMCAT_HOME\webapps\Axis目录<br /><br />4、启动tomcat,访问http://localhost:8080/Axis 检查安装是否成功<br /><br />5、以上步骤执行成功，可以开发webservice例子了<br /><br />Axis支持三种web service的部署和开发，分别为：<br /><br />1、Dynamic Invocation Interface ( DII)<br /><br />2、Stubs方式<br /><br />3、Dynamic Proxy方式<br /><br />二、编写DII(Dynamic Invocation Interface )方式web服务<br /><br />1.编写服务端程序HelloClient<br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>public class HelloClient<br />{<br />    public String getName(String name)<br />    {<br />        return "hello "+name;<br />    }<br />}</ccid_code></pre></td></tr></tbody></table></center><br /><br />2、将源码拷贝到Axis_HOME下，重命名为 HelloClient.jws <br /><br />3、访问连接http://localhost:8080/Axis/HelloClient.jws?wsdl，页面显示Axis自动生成的wsdl <br /><br />4、编写访问服务的客户端 TestHelloClient.java <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>import org.apache.Axis.client.Call;<br />import org.apache.Axis.client.Service;<br />import javax.xml.namespace.QName;<br />import javax.xml.rpc.ServiceException;<br />import java.net.MalformedURLException;<br />import java.rmi.RemoteException;<br /><br />public class SayHelloClient2<br />{<br />    public static void main(String[] args)<br />	{<br />        try<br />		{<br />  String endpoint =<br />  "http://localhost:8080/Axis/HelloClient.jws";<br /><br />    Service service = new Service();<br />            Call call = null;<br /><br />            call = (Call) service.createCall();<br /><br />            call.setOperationName(new QName(<br />               "http://localhost:8080/Axis/HelloClient.jws", <br />			   "getName"));<br />            call.setTargetEndpointAddress<br />			(new java.net.URL(endpoint));<br /><br />            String ret = (String) call.invoke(new Object[] <br />			{"zhangsan"});<br />            System.out.println("return value is " + ret);<br />        } <br />		catch (Exception ex)<br />		{<br />       ex.printStackTrace();<br />        }<br />    }<br />}</ccid_code></pre></td></tr></tbody></table></center><br /><br />三、编写Dynamic Proxy方式访问服务 <br /><br />1、编写部署服务端程序，同上边DII方式，本次仍使用上边部署的HelloClient <br /><br />2、编写代理接口 <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>public interface HelloClientInterface<br />extends java.rmi.Remote<br />{<br />    public String getName(String name)<br />	throws java.rmi.RemoteException;<br />}</ccid_code></pre></td></tr></tbody></table></center><br /><br />3、编写并执行客户端程序TestHelloClient.java <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>import javax.xml.rpc.Service;<br />import javax.xml.rpc.ServiceFactory;<br />import java.net.URL;<br />import javax.xml.namespace.QName;<br /><br />public class TestHelloClient <br />{<br />    public static void main(String[] args)<br />	{<br />        try<br />        {<br />            String wsdlUrl = <br />			"http://localhost:8080/Axis/HelloClient.jws?wsdl";<br />            String nameSpaceUri = <br />			"http://localhost:8080/Axis/HelloClient.jws";<br />            String serviceName = "HelloClientService";<br />            String portName = "HelloClient";<br /><br />            ServiceFactory serviceFactory = <br />			ServiceFactory.newInstance();<br />            Service afService =<br />			serviceFactory.createService(new URL(wsdlUrl),<br />         new QName(nameSpaceUri, serviceName));<br />            HelloClientInterface proxy = (HelloClientInterface)<br />        afService.getPort(new QName(<br />                    nameSpaceUri, portName), <br />					HelloClientInterface.class);<br />            System.out.println<br />			("return value is "+proxy.getName("john") ) ;<br />        }catch(Exception ex)<br />        {<br />            ex.printStackTrace() ;<br />        }<br />    }<br />}</ccid_code></pre></td></tr></tbody></table></center><br /><br />四、编写wsdd发布web服务，编写stub client访问web服务 <br /><br />1、编写服务端程序server,SayHello.java，编译server.SayHello.java <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>package server;<br />public class SayHello<br />{<br />    public String getName(String name)<br />    {<br />        return "hello "+name;<br />    }<br />}<br />2.编写LogHandler.java<br />import org.apache.Axis.AxisFault;<br />import org.apache.Axis.Handler;<br />import org.apache.Axis.MessageContext;<br />import org.apache.Axis.handlers.BasicHandler;<br /><br />import java.util.Date;<br /><br />public class LogHandler <br />extends BasicHandler <br />{<br /> public void invoke<br />(MessageContext msgContext) <br />throws AxisFault<br />    {<br />        /** Log an access each time <br />		we get invoked.<br />         */<br />        try {<br />            Handler serviceHandler<br />			= msgContext.getService();<br /><br />            Integer numAccesses =<br />  (Integer)serviceHandler.getOption("accesses");<br />            if (numAccesses == null)<br />                numAccesses = new Integer(0);<br />numAccesses = new Integer<br />(numAccesses.intValue() + 1);<br />Date date = new Date();<br /> String result = <br /> date + ": service " +<br />msgContext.getTargetService() +<br />" accessed " + numAccesses + " time(s).";<br />serviceHandler.setOption<br />("accesses", numAccesses);<br />System.out.println(result);<br />        } catch (Exception e)<br />		{<br />            throw AxisFault.makeFault(e);<br />        }<br />    }<br />}</ccid_code></pre></td></tr></tbody></table></center><br /><br />3、编写wsdd文件 <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>deploy.wsdd<br />&lt;deployment xmlns=<br />"http://xml.apache.org/Axis/wsdd/"<br />  xmlns:java=<br />			"http://xml.apache.org/Axis/wsdd/providers/java"&gt;           <br />   &lt;handler name="print" type="java:LogHandler"/&gt; <br /> &lt;service name="sayhello"<br /> provider="java:RPC"&gt;<br />   &lt;requestFlow&gt;<br />     &lt;handler type="print"/&gt;<br />   &lt;/requestFlow&gt;<br />  &lt;parameter name="className" <br />  value="server.SayHello"/&gt;<br />  &lt;parameter name="allowedMethods"<br />  value="*"/&gt;  <br /> &lt;/service&gt;<br />&lt;/deployment&gt;</ccid_code></pre></td></tr></tbody></table></center><br /><br />3、将编译后的文件拷贝到Axis_HOME/WEB-INF/classes下，如：D:\tomcat\webapps\Axis\WEB-INF\classes <br /><br />4、发布服务： <br /><br />java org.apache.Axis.client.AdminClient deploy.wsdd <br /><br />5、生成client stub文件 <br /><br />a:方式1 <br /><br />将SayHello.java拷贝到Axis_HOME/下，重命名为SayHello.jws， <br /><br />执行下面的命令生存client stub <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>java org.apache.Axis.wsdl.WSDL2Java <br />-p client  http://localhost:8080<br />/Axis/services/SayHello.jws?wsdl</ccid_code></pre></td></tr></tbody></table></center><br /><br />b:方式2 <br /><br />执行如下命令生成SayHello.wsdl <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>java org.apache.Axis.wsdl.Java2WSDL<br />-oSayHello.wsdl -lhttp://localhost:8080<br />/Axis/services/SayHello -nsayhello server.SayHello</ccid_code></pre></td></tr></tbody></table></center><br /><br />执行如下命令生成client stub <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>java org.apache.Axis.wsdl.WSDL2Java <br />SayHello.wsdl  -p client</ccid_code></pre></td></tr></tbody></table></center><br /><br />生成的stub client文件列表为： <br /><br />1.SayHello.java <br /><br />2.SayHelloService.java。 <br /><br />3.SayHelloServiceLocator.java <br /><br />4.SayHelloSoapBindingStub.java <br /><br />6、编写客户端程序，编译并执行 <br /><br /><center><ccid_nobr></ccid_nobr><table cellspacing="0" bordercolordark="#ffffff" cellpadding="2" width="400" align="center" bordercolorlight="black" border="1"><tbody><tr><td class="code" style="FONT-SIZE: 9pt" bgcolor="#e6e6e6"><pre><ccid_code>public class SayHelloClient<br />{<br />    public static void main(String[] args)<br />	{<br />        try<br />		{<br />    SayHelloService service = new client.<br />       SayHelloServiceLocator();<br />          client.SayHello_PortType <br />		  client = service.getSayHello();<br />            String retValue=client.getName("zhangsan");<br />            System.out.println(retValue);<br />} <br />catch (Exception e)<br />{<br /> System.err.println<br /> ("Execution failed. Exception: " + e);<br />        }<br />    }<br />}</ccid_code></pre></td></tr></tbody></table></center><br /><br />(T117)<br /><img src ="http://www.blogjava.net/ytfei/aggbug/66500.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2006-08-29 19:08 <a href="http://www.blogjava.net/ytfei/archive/2006/08/29/66500.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用J2EE开发WebService :转</title><link>http://www.blogjava.net/ytfei/archive/2006/08/17/64215.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Thu, 17 Aug 2006 14:16:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2006/08/17/64215.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/64215.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2006/08/17/64215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/64215.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/64215.html</trackback:ping><description><![CDATA[
		<center>
				<h4>用J2EE开发WebService</h4>
		</center>
		<br />(<font color="#008000"><em>by </em>huihoo.com</font> donyoung , Allen制作) <a href="http://211.99.144.3/forum/forumdisplay.php?fid=7"><font color="red">WebServie讨论&gt;&gt;&gt;</font></a><br /><br />英文原文：http://www.theserverside.com/resources/article.jsp?l=WebServices-Dev-Guide <br /><br /><img src="http://www.huihoo.com/xml/j2ee/tmc-logo.jpg" /><br /><b>I. 概要</b><br /><br />基于XML的Web服务是参照B2B通信协作模式制定的新的规范。它提供了概念上和结构上的，适用于各种不同平台和产品的基础。现在，开发者可以利用J2EE技术来开发基于XML的Web服务。他们可以利用现存的J2EE技术来开发完整的，遵从XML标准的，能完全共通的WEB服务。无需重新设计或者构造现有的J2EE系统，开发人员就可以构建复杂的强大的Web服务应用。 <br /><br /><b>II. 介绍</b> Web服务是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求，轻量级的独立的通讯技术。这种技术允许网络上的所有系统进行交互。随着技术的发展，一个Web服务可以包含额外的指定功能并且可以在多个B2B应用中协作通讯。 <br /><br />Web服务正在不断完善，并且以一种非常智能的动态的方法来进行。这些灵活的Web服务可以理解请求中上下文的关系，并且在每一个特定的情况下产生动态的结果。这些服务会根据用户的身份，地点以及产生请求的原因来改变不同的处理，用以产生一个唯一的，定制的方案。这种协作机制对那些只对最终结果有兴趣的用户来说，是完全透明的。 <br /><br />这种Web服务所遵循的XML标准可以增进事物通信的性能。开发人员将可以利用不同的平台，产品和标准来实现很多种可能。通过这种标准，开发人员可以建立一个系统使他们的Web服务提供最大的协同工作的能力。 <br /><br />这份白皮书描述了如何方便地利用Java和XML技术来实现Web服务构架。它说明了Web服务中的每一个关键部分以及如何使他们结合在一起。你将会对基于XML的Web服务的结构以及如何与J2EE结合，有一个更加深入的了解我们从如何利用J2EE建立Web服务开始。这部分将使你对如何建立一个Web服务有一个了解。 <br /><br /><b>III. 总结</b> 一般来说，在不同的事务之间进行电子通信协作会有很多阻碍。全异的系统，安全限制和不相同的数据格式，导致很多B2B系统在他们自己的领域或者客户群中形成唯一。Web服务将改变这一切，使不同的事务互相通信变为可能，值得注意的是，这会降低建立商业站点的开发和维护成本。 <br /><br />在建立Web服务的时候，有三个主要步骤： <br /><br />1. 建立客户端联接 为了允许Applets，Applications，商业合作伙伴，浏览器和PDAs 使用Web服务。 <br /><br />2. 实现Web服务 包括工作流，数据传送，商业逻辑以及数据访问。这些功能是隐藏在Web服务后，并且为客户端工作的。 <br /><br />3. 联接后台系统 这个系统可能包括一个或多个数据库，现存的企业信息系统，商业合作伙伴自己的系统或者Web服务，以及在多个系统中共享的数据。 <br /><br />你可以利用J2EE来实现这三个目标。用J2EE开发Web服务基于以下两个技术： <br /><br />XML 技术. <br />在Web服务中，XML标准是非常重要的。XML是一种数据格式，它可以以一种连贯的方式来表现数据，并且可以在网络中以点对点的形式传送。这些不同的XML标准连同指定的处理方法是设计来支持特定的行为的。 <br /><br />Java 技术. <br />Developers开发人员利用 J2EE APIs来创建事务和表现的逻辑，访问XML文档，以及对XML文档进行操作。信任被证实可行的Java技术是非常重要的，因为它允许开发者利用现有的下部构造，在其上构建新的功能。开发者可以继续利用J2EE的标准API以及各种优秀的组件来开发系统。现在，开发者可以利用J2EE中提供的Java API for XML Parsing (JAXP) 来开发Web服务，我们将在稍后介绍。这个新的APIs主要用来处理XML数据格式以及服务，将使开发变得更容易，效率更高。 <br />图 1 表现了基于J2EE的Web服务的核心构架。请注意，很多APIs在这里并没有全部表示出来，象用来解析或者传送消息的。但是，那些基于J2EE的标准，协议以及主要的子系统都表示出来了。 <br /><img src="http://www.huihoo.com/xml/j2ee/figure1.jpg" /><br />图 1让我们进一步看一下利用J2EE来创建Web服务的细节。 <br /><br /><b>IV. 客户端联接</b><br /><br />客户端联接是关于Web服务的使用者如何来使用你的系统。表格 1 显示了三种主要使用系统的客户。 <br /><br /><table border="1"><tbody><tr><td>客户类型</td><td>样例</td><td>如何联接</td></tr><tr><td>商业合作伙伴</td><td>代理商，客户群</td><td>基于XML的Web 服务技术 (SOAP, UDDI, WSDL, ebXML)</td></tr><tr><td>瘦客户端</td><td>浏览器，PDAs，无线设备</td><td>HTTP 协议</td></tr><tr><td>胖客户端</td><td>应用小程序，应用程序，已经存在的系统</td><td>IIOP协议</td></tr></tbody></table><br />表格 1商业合作伙伴的联接 <br /><br />第一种访问Web服务的客户类型是商业合作伙伴。他们可能使用很多种类型的编程语言，中间件或者硬件。当他们访问尼的系统的时候，Web服务要求返回一个XML文件。这个文件具有标准的标记来表示商业数据，并且允许不同的系统通过这个来交互。 <br /><br /><b>Java Servlets</b><br /><br />当一个商业合作伙伴向Web服务发布一个请求的时候，接收请求的是一个Java servlet. 这个Servlet是一个在管理容器中运行，负责接收请求和响应的Java对象。它可以以很多种协议返回请求结果，象HTTP, FTP或者POP。在这个例子中Servlet通常使用HTTP来响应请求，这样的话，Web服务就可以利用HTTP来通过防火墙了。 <br /><br />当一个请求到达J2EE Web服务的时候，以下操作会发生，见图2 <br /><br />1. Java servlet接收XML 文档。 <br /><br />2. Servlet 处理传入的基于XML的请求 <br /><br />3. Servlet调用一个或者多个Enterprise JavaBeans (EJB) 组件来处理数据。 <br /><br />4. EJB组件进行他们自己的处理，可能会调用其他存在的系统。 <br /><br />5. EJB 组件把结果返回给Servlet。 <br /><br />6. Servlet 把结果汇集到XML文档中。 <br /><br />7. Servlet 把XML传送到客户端。 <img src="http://www.huihoo.com/xml/j2ee/figure2.jpg" /><br /><br />图 2为了实现商业合作伙伴的联接，必须有一种方法来发布，描述，定位以及调用一个Web服务。我们现在来描述如何达到这个目的。 <br /><br /><b>UDDI</b> 在用户能够调用Web服务之前，必须确定这个服务内包含哪些商务方法，找到被调用的接口定义，还要在服务端来编制软件。所以，我们需要一种方法来发布我们的Web服务。 <br /><br />UDDI (Universal Description, Discovery, and Integration) 是一个主要针对Web服务供应商和使用者的新项目。UDDI 项目中的成员可以通过UDDI Business Registry (UBR) 来操作Web服务的调用，UBR是一个全球性的服务。Web服务供应商可以在UBR中描述并且注册他们的服务。用户可以在UBR中查找并定位那些他们需要的服务。 <br /><br />UDDI是一种根据描述文档来引导系统查找相应服务的机制。UDDI包含标准的"白皮书"类型的商业查询方式，"黄皮书"类型的局部查找，以及"绿皮书"类型的服务类型查找。"绿皮书"允许开发者精确查找符合服务类型的所有服务。（这一段翻的比较奇怪） <br /><br />UDDI利用SOAP消息机制（标准的XML/HTTP）来发布，编辑，浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据，并且发送到注册中心或者由注册中心来返回需要的数据。 <br /><br /><b>JAXR</b><br /><br />为了支持UDDI在Java平台上的功能，Java APIs for XML Registries (JAXR)允许开发者来访问注册中心。值得注意的是，JAXR并不是建立Web服务必需的，你可以利用其他常用的XML APIs来直接集成这些协议。JAXR是一个方便的API，它提供了Java API来发布，查找以及编辑那些注册信息。它的重点在于基于XML的B2B应用，复杂的地址本查找以及对XML消息订阅的支持等Web服务。它也可以用来访问其他类型的注册中心，象ebXML注册中心（稍候描述）。 <br /><br />这些对Web服务的注册信息进行的操作，可以使用当前的一些Web服务工具来完成（例如第三方的SOAP和ebXML消息工具）。另外，当JAXP提供了一致并具有针对性的API来完成这些操作，这将使开发变得更加容易。 <br /><br /><b>WSDL</b><br /><br />对于商业用户来说，要找到一个自己需要使用的服务，他必须知道如何来调用。WSDL (Web Services Description Language) 规范是一个描述接口，语义以及Web服务为了响应请求需要经常处理的工作的XML文档。这将使简单地服务方便，快速地被描述和记录。 <br /><br />以下是一个WSDL的样例： <br /><br /><p>&lt;?xml version="1.0"?&gt;<br />&lt;definitions name="StockQuote"<br />                targetNamespace="http://example.com/stockquote.wsdl"<br />                xmlns:tns="http://example.com/stockquote.wsdl"<br />                xmlns:xsd1="http://example.com/stockquote.xsd"<br />                xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"<br />                xmlns="http://schemas.xmlsoap.org/wsdl/"&gt;<br />&lt;types&gt;<br />   &lt;schema targetNamespace=http://example.com/stockquote.xsd<br />                 xmlns="http://www.w3.org/2000/10/XMLSchema"&gt;<br />      &lt;element name="TradePriceRequest"&gt;<br />        &lt;complexType&gt;<br />           &lt;all&gt;<br />                &lt;element name="tickerSymbol" type="string"/&gt;<br />              &lt;/all&gt;<br />           &lt;/complexType&gt;<br />        &lt;/element&gt;<br />        &lt;element name="TradePrice"&gt;<br />            &lt;complexType&gt;<br />                &lt;all&gt;<br />                   &lt;element name="price" type="float"/&gt;<br />                 &lt;/all&gt;<br />              &lt;/complexType&gt;<br />           &lt;/element&gt;<br />        &lt;/schema&gt;<br />     &lt;/types&gt;<br />     &lt;message name="GetLastTradePriceInput"&gt;<br />         &lt;part name="body" element="xsd1:TradePriceRequest"/&gt;<br />     &lt;/message&gt;<br />     &lt;message name="GetLastTradePriceOutput"&gt;<br />         &lt;part name="body" element="xsd1:TradePrice"/&gt;<br />    &lt;/message&gt;<br />    &lt;portType name="StockQuotePortType"&gt;<br />        &lt;operation name="GetLastTradePrice"&gt;<br />            &lt;input message="tns:GetLastTradePriceInput"/&gt;<br />            &lt;output message="tns:GetLastTradePriceOutput"/&gt;<br />         &lt;/operation&gt;<br />      &lt;/portType&gt;<br />      &lt;binding name="StockQuoteSoapBinding"<br />                    type="tns:StockQuotePortType"&gt;<br />         &lt;soap:binding style="document"<br />                                 transport="http://schemas.xmlsoap.org/soap/http"/&gt;<br />        &lt;operation name="GetLastTradePrice"&gt;<br />            &lt;soap:operation<br />                           soapAction="http://example.com/GetLastTradePrice"/&gt;<br />            &lt;input&gt;<br />               &lt;soap:body use="literal"/&gt;<br />            &lt;/input&gt;<br />            &lt;output&gt;<br />                &lt;soap:body use="literal"/&gt;<br />            &lt;/output&gt;<br />         &lt;/operation&gt;<br />      &lt;/binding&gt;<br />     &lt;service name="StockQuoteService"&gt;<br />        &lt;documentation&gt;My first service&lt;/documentation&gt;<br />        &lt;port name="StockQuotePort" binding="tns:StockQuoteBinding"&gt;<br />            &lt;soap:address location="http://example.com/stockquote"/&gt;<br />        &lt;/port&gt;<br />     &lt;/service&gt;<br />  &lt;/definitions&gt;<br /><br />它包含了以下的关键信息： <br />· 消息的描述和格式定义可以通过XML文档中的<types>和<message> 标记来传送。 <br />· <porttype>标记中表示了消息传送机制。 (e.g. request-only, request-response, response-only) 。 <br />· <binding>标记指定了编码的规范 。 <br />· <service>标记中表示服务所处的位置 (URL)。 <br /><br />WSDL在UDDI中总是作为一个接口描述文档。因为UDDI是一个通用的用来注册WSDL规范的地方，UDDI的规范并不限制任何类型或者格式描述文档。这些文档可能是一个WSDL文档，或者是一个正规的包含导向文档的Web页面，也可能只是一个包含联系信息的电子邮件地址。 <br /><br />现在Java提供了一个 Java API for WSDL (JWSDL)规范。它提供了一套能快速处理WSDL文档的方法，并且不用直接对XML文档进行操作，它会比JAXP更方便，更快速。 <br /><br />图 3 显示了如何使用WSDL 和 UDDI。 <br /><br /><img src="http://www.huihoo.com/xml/j2ee/figure3.jpg" /><br /><br />图 3 <br /><br /><b>SOAP</b><br /><br />当商业用户通过UDDI找到你的WSDL描述文档后，他通过可以Simple Object Access Protocol (SOAP) 调用你建立的Web服务中的一个或多个操作。 <br /><br />SOAP是XML文档形式的调用商业方法的规范，它可以支持不同的底层接口，象HTTP(S)或者SMTP。之所以使用XML是因为它的独立于编程语言，良好的可扩展性以及强大的工业支持。之所以使用HTTP是因为几乎所有的网络系统都可以用这种协议来通信，由于它是一种简单协议，所以可以与任何系统结合，还有一个原因就是它可以利用80端口来穿越过防火墙。 SOAP的强大是因为它简单。SOAP是一种轻量级的，非常容易理解的技术，并且很容易实现。它有工业支持，可以从各主要的电子商务平台供应商那里获得。 <br /><br />从技术角度来看，SOAP详细指明了如何响应不同的请求以及如何对参数编码。一个SOAP封装了可选的头信息和正文，并且通常使用HTTP POST方法来传送到一个HTTP 服务器，当然其他方法也是可以的，例如SMTP。SOAP同时支持消息传送和远程过程调用。以下是一个SOAP请求。 <br /><br /><p><font size="2">POST /StockQuote HTTP/1.1<br />Host: www.stockquoteserver.com<br />Content-Type: text/xml; charset="utf-8"<br />Content-Length: nnnn <br />SOAPAction: "Some-URI" <br /></font></p><p><font size="2">&lt;SOAP-ENV:Envelope<br />    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"<br />    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/&gt;<br />    &lt;SOAP-ENV:Header&gt;<br />        &lt;t:Transaction xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1"&gt;<br />           5<br />        &lt;/t:Transaction&gt;<br />    &lt;/SOAP-ENV:Header&gt;<br />    &lt;SOAP-ENV:Body&gt;<br />        &lt;m:GetLastTradePrice xmlns:m="Some-URI"&gt;<br />            &lt;symbol&gt;SUNW&lt;/symbol&gt;<br />        &lt;/m:GetLastTradePrice&gt;<br />    &lt;/SOAP-ENV:Body&gt;<br />&lt;/SOAP-ENV:Envelope&gt; </font></p><br /><b>JAX/RPC</b><br /><br />为了使开发人员专注于建立象SOAP那样的基于XML的请求，JCP正在开发基于RPC (JAX/RPC) 的Java API。JAX/RPC是用来发送和接收方法调用请求的，它基于XML协议，象SOAP，或者其他的象XMLP (XML Protocol，要了解更多可以参考http://www.w3.org/2000/xp/)。JAX/RPC使你不用再关注这些协议的规范，使应用的开发更快速。不久，开发人员就不用直接以XML表示方法调用了。 <br /><br />目前有很多第三方实现了SOAP，开发人员可以在不同的层次上调用SOAP，并选择使用哪一种。将来，JAX/RPC会取代这些APIs并提供一个统一的接口来构造以及处理SOAP RPC请求。 <br /><br />在接收一个从商业伙伴那里过来的SOAP请求的时候，一个Java servlet用JAX/RPC来接收这个基于XML的请求。一旦接收到请求后，servlet会调用商务方法，并且把结果回复给商业伙伴。 <br /><br /><b>ebXML</b> 对于具有高扩展性的商业交易来说，他们需要一种可信任的结构来实现商业事务，多请求的事务，计划以及文档流程，应用的需求经常超越了基于纯SOAP的实现。因为SOAP只是提供了一个底层的结构，而你可能需要一个更高级的框架结构。 <br /><br />ebXML就是为了这个目的的，它是一套处理B2B应用间的合作与通信的XML规范。以下是ebXML中的关键组件： <br /><br /><b>Collaboration Protocol Profile (CPP)</b><br /><br />CPP提供了一种标准并且简单的方法描述了公司提供的产品。另外，它还描述了消息交换的能力以及公司支持的商务合作。它也描述了公司的商务处理方法，包括合伙人如何与公司合作。CPP定义了B2B交易中双方的商务协作。例如，它同时定义了买卖双方的商务处理方法。 <br /><br /><b>Collaboration Protocol Agreement (CPA)</b><br /><br />CPA描述了两个公司之间进行交易时的详细需求以及机制。它包含有由手工或者自动从经过买卖双方认可的CPPs中的信息。这个CPA是双方进行指定交易的合约。 CPP和CPA的样例，以及关于规范的细节可以从以下网站获得： <br /><br />http://ebxml.org/project_teams/trade_partner/cpp-example.xml <br />http://ebxml.org/project_teams/trade_partner/cpa-example.xml <br />http://www.ebxml.org/specs/ebCCP.pdf <br /><br /><b>Business Process and Information Modeling</b><br /><br />ebXML还以XML的形式描述了商业事务处理的规范。它包括交易，文档流程，数字通信，数据封装格式以及其他更多。这些规范是用来建立CPPs，描述以及共享商业事务和信息时用的。 <br /><br /><b>Core Components</b><br /><br />ebXML中另外一个重要的部分是一系列的XML标记，我们叫它核心组件。这些标记包含了商务数据，象日期，税，账户，交易合同以及其他的。它指明了商业合约和实体，但对每个不同的行业，可能都不一样。 <br /><br /><b>Messaging</b><br /><br />ebXML消息格式包含了所有相关的消息导向信息（同步或者异步，可靠性）。一般来说，一个ebXML消息包含了CPA中的可视化内容，并强制执行交易规则。 EbXML是建立在SOAP消息封装机制上的。它扩展了SOAP的协议，增加了多层框架结构来支持附件，安全性以及传送的可靠性。 <br /><br /><b>Registry/Repository</b><br /><br />EbXML注册中心是存储CPPs, CPAs, ebXML核心组件和与ebXML相关的文档的服务。它具有强大的查询功能，允许用户查找相关的组件以及发掘潜在客户。JAXR API也可以用来访问ebXML注册中心。商业服务定义了CPPs，并且被存储在ebXML注册中心，然后发布到UDDI中。一个关键的概念是，UDDI提供了一个全球唯一的Web服务的描述信息，但那些真实的信息，还是保存在本地的ebXML库中。这样的话，一个潜在的客户首先到UDDI中查找相关内容，然后根据这些到ebXML库中找CPPs或者其他相关文档。 <br /><br /><b>JAXM</b><br /><br />当从商业合作伙伴那里接收一个Web服务的请求时，我们需要Java API实现一个Servlet来处理ebXML消息，就象我们用JAX/RPC来处理SOAP请求一样。 <br /><br /><b>Java API for XML Messaging (JAXM)</b><br /><br />是集成XML消息标准（象ebXML消息或者SOAP消息）的规范。这个API是用来推动XML消息处理的，它检测那些预定单的消息格式以及约束。它控制了所有的消息封装机制，用一种直观的方式分割了消息中的信息，象路由信息，发货单。这样，开发人员只要关注消息的有效负载，而不用去担心那些消息的重复处理。 <br /><br />目前的开发人员用JAXP来实现JAXM将要提供的功能，JAXM将会提供一套非常具有针对性的API来处理基于XML的消息传送。这将大大简化开发人员的代码，并使它们具有统一的接口。 <br /><br />JAXM和JAX/RPC的差别在于处理消息导向的中间件以及远程过程调用的不同。JAXM注重于消息导向，而JAX/RPC是用来完成远程过程调用的。以下是图解。 <br /><br /><img src="http://www.huihoo.com/xml/j2ee/figure4.jpg" /><br /><br />图 4 <br /><br />请注意，在JAXM 和 JAX/RPC技术成熟之前，开发人员还是依赖于第三方的SOAP APIs，象Apache SOAP, IdooXOAP, 以及 GLUE。当JAXM 和 JAX/RPC正式发布后，它将为当前不同的SOAP和ebXML消息提供统一的接口。就象JDBC位多种不同的数据库提供统一的接口。 <br /><br />以上是对于让商业合作伙伴访问你的Web服务的讨论。下面我们来讨论瘦客户端和胖客户端。 <br /><br /><b>Thin Client Connectivity</b><br /><br />瘦客户端（象浏览器或者无线设备）只对浏览页面感兴趣。Web服务的职责是执行需要处理的Web请求，象运行B2C交易，然后给出订单确认。为实现这个，开发者用JSP来写动态页面。JSP组件技术时一种可以根据后台数据处理的结果，来动态生成页面的技术。它们在提供JSP组件的容器中运行。 JSP可以表现后台用各种方法来实现的业务逻辑（e.g. EJBs，普通的Java对象，或者标准的JavaBean）。它可以生成标准的HTML或者XHTML来显示结果。 JSP组件与其说是可编程接口，不如说是用户界面。比方说，一个股票报价服务可能需要调用一个统计股票平均报价的应用中的Web服务，然后利用JSP技术把最终结果显示出来。以下显示了JSP组件的角色。 <br /><br /><img src="http://www.huihoo.com/xml/j2ee/figure5.jpg" /><br /><br />图 5 <br /><br /><b>Thick Client Connectivity</b><br /><br />有些Web服务的连接适合用胖客户端。比方说，公司的内部网。用户界面的响应以及功能可能更加重要。 <br /><br />一个胖客户端可以用很多种方法来联接Web服务。比方说，可以用UDDI, WSDL, SOAP以及ebXML。这是一个性能比较低的例子，因为客户端和服务端可能是由同样的开发组开发的，所以不需要处理很多的XML传送或者解析。 <br /><br />一个提高性能的方法是，胖客户端通过其他更有效的端口来联接，象Java RMI-IIOP。 <br /><br /><b>V. Implementing Web Services</b><br /><br />现在我们来看，如何在内部实现Web服务。 <br /><br /><b>数据传送和转换</b><br /><br />在进入Web服务之前，我们必须解决如何把传送进来的XML数据转换成我们自己的服务能够方便处理的格式，然后再把处理结果转换成XML格式返回给客户。因此一个开发人员需要一个强壮的机制来解析XML文件，绑定到Java对象，生成XML文件，并且传送各种不同的XML格式文件。有时由于我们的应用程序支持不同的接口（例如：B2B伙伴的SOAP，基于浏览器的HTML格式，或者是无线的WML访问同样的Web服务）我们可能需要不同的服务接口来处理这些不同客户端传送过来的请求。 <br /><br /><b>JAXP</b><br /><br />用来处理XML的Java APIs是一套Java本地接口，它提供了可插入到XSLT引擎中的接口SAX，DOM。这些构成了解析和处理XML文档的基础。这些APIs对Web服务来说，是非常底层的，它给了我们用Java来访问，修改以及创建XML文档的全部功能。 <br /><br />For more information, please see: <br /><br />http://java.sun.com/xml/tutorial_intro.html <br />http://java.sun.com/xml/xml_jaxp.html <br /><br /><b>JAXB</b><br /><br />XML绑定技术可以把XML文档和Java对象进行自由转换。用JAXB，你可以在后台的EJB层，把XML文档转换成Java对象。同样你也可以把从EJB中取出的Java对象转换成XML文档返回给用户。 <br /><br />JAXB接口提供了比SAX和DOM更高级的方法来处理XML文档。它提供的特性可以在XML数据和Java类之间互相映射，提供了一个简单的方法来转换XML数据。它比逐个解析标记更简单。 <br /><br /><b>XSLT</b><br /><br />从商业伙伴那里传送过来的XML文档可能和内部使用的格式不相同，比方说商业伙伴那里用"OrderNum"，而内部使用"OrderID"。 <br /><br />我们经常为了响应不同的客户请求，而重新格式化XML数据文档。举例来说，一个商业伙伴的请求可能传送一个SOAP表单，而一些浏览器用户可能是一个XHTML。在一个更复杂的系统中，我们可能需要支持很多种不同的表现形式，象WML表单或者VoiceXML。这要求我们有一种机制来把各种XML以基本的XML响应格式来传送给我们系统中不同的接口。 <br /><br /><b>XML Stylesheet Language Transformations (XSLT)</b><br /><br />是一种转换XML格式的机制。一个stylesheet可以指定一系列的模版对应规则，并把它们赋给一个可递归的，象DOM这样的模型。一个XSLT引擎可以用stylesheet来转换XML文档。XSLT stylesheet的语法是非常有表现力的，包含了循环，条件和数学表达式等。还有类似于函数（function）的机构和概念上的递归。 <br /><br /><b>Shared Context</b><br /><br />当两个商业发生交易的时候，通常有一个上下文的关系。这个关系是指定给合作伙办的一个协议，或者是一种商业规则，这样就可以给不同的合作伙伴进行交易。此外，一个商业协作在一段时间内可能调用不同的接口。每一个这样的调用都是处理同一个商业关系的，可能出现在整个商业生命周期中。 <br /><br />在J2EE Web服务中，为这个关系建一个离散的位置是一种建议的实现方法。作为一个开发人员，你应该在复杂的Web服务中需要这样的关系，并且为你的系统结构设计一个离散的组件来控制它。目前这种关系是通过数据库访问（JDBC）来实现的。但是，Context API可以把Web服务中需要对这种关系的访问操作作为一种流控制。这样，这些共享的数据就可以由各种组件来访问，象Servlet, JSP或者EJB组件。 <br /><br /><b>Business Layer</b><br /><br />当传送进来的XML数据被转换成Java对象后，这个数据已经准备被传送到EJB商务层做处理。EJB技术是一种用Java来创建商业组件的标准。用EJB组件，你可以从容器中得到一些服务，象安全性，状态保持，连接池，负载平衡以及失败恢复。 <br /><br />在EJB2.0标准中有3中EJB组件： <br /><br /><b>Session Beans</b><br /><br />进行客户端的工作。一般来说，Session Bean生命周期短，执行快速的操作，象提交订单，计算交易税额。 <br /><br /><b>Entity Beans</b><br /><br />表现商业数据。一般来说，Entity Bean生命周期长，并且映射到后台的存储介质内，象RDBMS或者OODBMS系统。Entity Bean分为两种类型：bean-managed persistent 和container-managed persistent <br /><br /><b>MessageDriven Beans</b><br /><br />是消息导向组件。它们通过消息导向中间件来接收消息象IBM MQSeries或者TIBCO Rendezvous。消息也可以通过Java客户端利用Java Message Service (JMS) 标准来发送。当消息到达后，一般用JMS API来访问。 <br /><br />一般来说，session beans 通过调用entity bean来完成希望的操作。比方说，一个用来计算订单价格的session bean，可能调用到表示产品和订单的entity bean。 Message-driven beans 用来接收消息，或者传送消息到那些session beans 或者 entity beans. <br /><br /><img src="http://www.huihoo.com/xml/j2ee/figure6.jpg" /><br /><br />图6显示了一个EJB组件交互的机制。 <br /><br />你可以用Java Naming和JNDI API来创建，查找以及删除EJB组件。这个API是用来访问J2EE发布系统中外部资源的标准API，可以访问包括数据库驱动，消息中间件，或者创建EJB的程序。 <br /><br />更多 EJB资料， 请查阅: <br /><br />· http://java.sun.com/products/ejb/white/white_paper.html <br />· http://java.sun.com/products/ejb/ <br />· http://www.theserverside.com <br />· "Mastering Enterprise JavaBeans" by Ed Roman, published by John Wiley &amp; Sons. <br /><br /><b>VI. Performing Back-End Integration</b><br /><br />最后来讨论用J2EE来开发Web服务的时候，如何与后台系统相连，象数据库，原先的系统和其他的商业伙伴。 <br /><br /><b>Database Connectivity</b><br /><br />为了联接关系数据库，开发人员必须选择APIs: The JDBC API 是一个用来访问支持SQL的关系数据库API.。（这个相信大家都知道了。） <br /><br /><b>SQL/J</b><br /><br />是用Java编写的标准的嵌入式SQL。类似于在HTML中嵌入JSP组件。 <br /><br /><b>Legacy System Connectivity</b><br /><br />在企业级开发中，与现存的系统相连接，一直都是一个比较困难的任务。大部分企业应用都是一个大杂烩，包含象SAP R/3, Siebel, i2以及一些客户服务系统。整合工作是一个手工任务，因为对现存的系统可用方案并不多。软件独立开发商被要求编写一个在任何平台上都可以运行的客户适配器，但这缺乏一个统一的标准平台。 <br /><br /><b>J2EE Connector Architecture (JCA)</b><br /><br />是在工业中应用的，一个针对现存系统的适配器。你可以用它来连接现在的系统，或者编写你自己的适配器。它可以运行在与任何J2EE兼容的环境中。用JCA，你只要编写一个适配器，就可以在任何J2EE环境中运行。对于软件独立开发商来说，这为他们提供了一个整合现存系统的方案。事实上，这些适配器正在开发中，对最终开发者来说，这的确是令人激动的。 <br /><br /><b>Business Partner Connectivity</b><br /><br />后台系统的最后一个类型是商业伙伴的Web服务。商业伙伴用全球认定的XML标准来暴露出一些他们自己的系统，在我们发布自己的Web服务时，可能会用到他们的这些服务。一般来说，UDDI用来注册Web服务，WSDL用来描述Web服务，SOAP和ebXML用来处理商务交易。 <br /><br />你的EJB组件可以调用JAP套件来访问商业伙伴的Web服务，这在之前已经介绍过了。 <br /><br />用 Java API for XML Registries (JAXR) 在UDDI注册中心查找商业伙伴的Web服务。 <br /><br />用 Java API for XML RPC (JAX/RPC) 处理到外部Web服务的请求。 <br /><br />用 Java API for XML Messaging (JAXM) 发送SOAP 或者 ebXML 消息到外部Web服务。 <br /><br />用 Java API for XML Parsing (JAXP) and the Java API for XML Binding (JAXB) <br /><br />把Java数据转换成适用于合作伙伴的XML格式。同样可以用来把合作伙伴那边的数据转换成易于自己处理的XML格式，或者进行XSLT数据转换。 <br /><br />结合使用Java标准APIs和J2EE Web服务构架，我们就可以建立强大的跨平台的系统。利用它们，我们可以与商业伙伴共享数据，提供完整的end-to-end的Web服务解决方案。见图7。 <br /><img src="http://www.huihoo.com/xml/j2ee/figure7.jpg" /> <br /></service></binding></porttype></message></types></p><img src ="http://www.blogjava.net/ytfei/aggbug/64215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2006-08-17 22:16 <a href="http://www.blogjava.net/ytfei/archive/2006/08/17/64215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wap</title><link>http://www.blogjava.net/ytfei/archive/2006/08/13/63318.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Sun, 13 Aug 2006 06:51:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2006/08/13/63318.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/63318.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2006/08/13/63318.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/63318.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/63318.html</trackback:ping><description><![CDATA[
		<a href="http://www.ust.hk/itsc/wap/emulators/nokia.html">http://www.ust.hk/itsc/wap/emulators/nokia.html</a>
		<br />
		<br />
		<a href="http://www2.chn.monternet.com:8080/devdownload/DevWapSimulator.jsp">http://www2.chn.monternet.com:8080/devdownload/DevWapSimulator.jsp</a>
<img src ="http://www.blogjava.net/ytfei/aggbug/63318.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2006-08-13 14:51 <a href="http://www.blogjava.net/ytfei/archive/2006/08/13/63318.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用开源协议</title><link>http://www.blogjava.net/ytfei/archive/2006/07/13/57951.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Thu, 13 Jul 2006 04:49:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2006/07/13/57951.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/57951.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2006/07/13/57951.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/57951.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/57951.html</trackback:ping><description><![CDATA[
		<h3>常用开源协议</h3>
		<h4> </h4>
		<p>开源在今天的软件业已经很普遍，但开源是否意味着使用者可以对开源后的代码为所欲为呢？答案是否定的。开源运动同样有自己的游戏规则和道德准则。不遵行这些规则不但损害开源运动的健康发展，也会对违规者造成名誉和市场上的损失，更可能陷入法律纠纷和赔偿。</p>
		<p>现今存在的开源协议很多，而经过Open Source Initiative组织通过批准的开源协议目前有58种。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码，最好也是选择这些被批准的开源协议。 </p>
		<p>这里我们来看四种最常用的开源协议及它们的适用范围，供那些准备开源或者使用开源产品的开发人员/厂家参考。</p>
		<p>现今存在的开源协议很多，而经过Open Source Initiative组织通过批准的开源协议目前有58种。我们在常见的开源协议如BSD, GPL, LGPL,MIT等都是OSI批准的协议。如果要开源自己的代码，最好也是选择这些被批准的开源协议。 </p>
		<p>
				<br />BSD开源协议 </p>
		<p>BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用，修改源代码，也可以将修改后的代码作为开源或者专有软件再发布。 </p>
		<p>
				<br />但”为所欲为”的前提当你发布使用了BSD协议的代码，或则以BSD协议代码为基础做二次开发自己的产品时，需要满足三个条件： </p>
		<p>1．  如果再发布的产品中包含源代码，则在源代码中必须带有原来代码中的BSD协议。 </p>
		<p>2．  如果再发布的只是二进制类库/软件，则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。 </p>
		<p>3．  不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。 </p>
		<p>BSD代码鼓励代码共享，但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码，也允许使用或在BSD代码上开发商业软件发布和销售，因此是对商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议，因为可以完全控制这些第三方的代码，在必要的时候可以修改或者二次开发。</p>
		<p>Apache Licence 2.0</p>
		<p>Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似，同样鼓励代码共享和尊重原作者的著作权，同样允许代码修改，再发布（作为开源或商业软件）。需要满足的条件也和BSD类似： </p>
		<p>1．需要给代码的用户一份Apache Licence </p>
		<p>2．如果你修改了代码，需要再被修改的文件中说明。 </p>
		<p>3．在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。</p>
		<p>4． 如果再发布的产品中包含一个Notice文件，则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可，但不可以表现为对Apache Licence构成更改。</p>
		<p>Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。</p>
		<p>GPL </p>
		<p>我们很熟悉的Linux就是采用了GPL。GPL协议和BSD, Apache Licence等鼓励代码重用的许可很不一样。GPL的出发点是代码的开源/免费使用和引用/修改/衍生代码的开源/免费使用，但不允许修改后和衍生的代码做为闭源的商业软件发布和销售。这也就是为什么我们能用免费的各种linux，包括商业公司的linux和linux上各种各样的由个人，组织，以及商业软件公司开发的免费软件了。</p>
		<p>GPL协议的主要内容是只要在一个软件中使用(“使用”指类库引用，修改后的代码或者衍生代码)GPL协议的产品，则该软件产品必须也采用GPL协议，既必须也是开源和免费。这就是所谓的”传染性”。GPL协议的产品作为一个单独的产品使用没有任何问题，还可以享受免费的优势。</p>
		<p>由于GPL严格要求使用了GPL类库的软件产品必须使用GPL协议，对于使用GPL协议的开源代码，商业软件或者对代码有保密要求的部门就不适合集成/采用作为类库和二次开发的基础。</p>
		<p>其它细节如再发布的时候需要伴随GPL协议等和BSD/Apache等类似。</p>
		<p>LGPL </p>
		<p>LGPL是GPL的一个为主要为类库使用设计的开源协议。和GPL要求任何使用/修改/衍生之GPL类库的的软件必须采用GPL协议不同。LGPL 允许商业软件通过类库引用 (link)方式使用LGPL类库而不需要开源商业软件的代码。这使得采用LGPL协议的开源代码可以被商业软件作为类库引用并发布和销售。</p>
		<p>但是如果修改LGPL协议的代码或者衍生，则所有修改的代码，涉及修改部分的额外代码和衍生的代码都必须采用LGPL协议。因此LGPL协议的开源代码很适合作为第三方类库被商业软件引用，但不适合希望以LGPL协议代码为基础，通过修改和衍生的方式做二次开发的商业软件采用。 </p>
		<p>GPL/LGPL都保障原作者的知识产权，避免有人利用开源代码复制并开发类似的产品。</p>
<img src ="http://www.blogjava.net/ytfei/aggbug/57951.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2006-07-13 12:49 <a href="http://www.blogjava.net/ytfei/archive/2006/07/13/57951.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>魔兽音效</title><link>http://www.blogjava.net/ytfei/archive/2006/07/13/57894.html</link><dc:creator>飞翔</dc:creator><author>飞翔</author><pubDate>Thu, 13 Jul 2006 00:54:00 GMT</pubDate><guid>http://www.blogjava.net/ytfei/archive/2006/07/13/57894.html</guid><wfw:comment>http://www.blogjava.net/ytfei/comments/57894.html</wfw:comment><comments>http://www.blogjava.net/ytfei/archive/2006/07/13/57894.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/ytfei/comments/commentRss/57894.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/ytfei/services/trackbacks/57894.html</trackback:ping><description><![CDATA[NE的： <br /><br />恶魔猎手- (英雄，城镇中心) <br />=建造音效= <br />- At last, we shall have revenge! 终于，我们可以报仇了！ <br />=选定音效= <br />- The time has come. 是时候了 <br />- We must act! 我们必须行动了！ <br />- My blade thirsts 我的刀刃渴望着…… <br />- Quickly! 快！ <br />- Command Me! 命令我吧！ <br />=行动/执行动作音效= <br />- [思想控制] You are spellbound!*** 你已经着魔了 <br />- [蜕变] Time to raise hell! 呼唤地狱的时刻到了 <br />- [吸魂] Your soul is mine!*** 你的灵魂属于我 <br />- [鬼怪视界] Hide no longer!*** 你无处可藏 <br />- Anatorettador!** 精灵语 <br />- Though I be damned! 就算我是被诅咒的！ <br />- Duranacal.** 精灵语 <br />- At last. 终于 <br />- Hmmm. 唔 <br />=骂玩家音效= <br />- I shall fight fire with fire! 我要以火焰来克制火焰。 <br />- Chaos boils in my veins! 混沌的力量在我血液中沸腾 <br />- Demon blood is thicker than... regular blood. 恶魔之血浓于……一般的血 <br />- I like my enemies dead and my blades flaming. 最爱看敌人死在我燃烧的刀刃下 <br />- I love green trees! (注解: 这个很粗暴. 在游戏中其实是倒过来的, 我不想把它拼出来所以我把它倒过来了. ) <br />- You will perish in flames (咳嗽声) Ops, sorry! 你将在火焰中毁灭（咳嗽）哦，对不起！ <br />- Darkness called, ... but I was on the phone, so I missed him. I tried to *69 Darkness, but his machine picked up. I yelled: "Pick up the phone Darkness", but he ignored me. Darkness must have been screening his calls. 黑暗之王一度召唤我，……但我在打电话，所以我错过了。我试着回拨给他，但只听到录音留言。我喊道：“拿起电话呀诎抵酢保撬焕砦摇：诎抵跻欢ㄊ瞧帘瘟怂牡缁啊?br /&gt;=攻击音效= <br />- [.vs 英雄] For Calendor! 为了Kalimdor <br />- None shall survive! 挡我者死！ <br />- Your blood is mine! 喝你的血！ <br />- Run for your life! 快逃命吧！ <br />- Revenge! 复仇！ <br /><br />丛林守护者- (英雄，城镇中心) <br />=建造音效= <br />- I must safegaurd the land! 保护大地是我的职责。 <br />=选定音效= <br />- Is there danger? 有险情吗？ <br />- Command me. 命令我吧 <br />- Who threatens the wilds? 谁在威胁着大自然？ <br />- The time is now. 就是现在 <br />- Nature is restless. 大自然永不宁静 <br />=行动/执行动作音效= <br />- [自然之触] Everything I touch dies or comes back to life! 我的触碰带来死亡和再生！ <br />- [扼死藤] This should weed out a few! 这些杂草应该清除 <br />- [荆棘] You mess with the branch, you get the thorns! 你跟树枝战斗，就得面对荆棘。 <br />- [宁静] The calm, before the storm. 暴风雨前的宁静 <br />- By the spirits! 以精灵们的力量！ <br />- For Calendor! 为了Kalimdor！ <br />- Well, there it is. 好，在那边 <br />- So shall is be. 理应如此 <br />- Naturally. 自然而然 <br />=骂玩家音效= <br />- My father was mounted over someone''s fireplace. 我父亲是画在壁炉上方的座骑 <br />- Feel natural, nature''s way. 感受大自然的自然 <br />- Don''t let the doe hit you on the way out! 那些母鹿要来扁你了 <br />- When I Attack, part 3. 当我攻击时，第3部分 <br />- Free rides for the ladies MM免费骑哦 <br />- Heard up! 收到！ <br />=攻击音效= <br />- [.vs 英雄] Smite the defilers of the land! 给污染者以致命一击！ <br />- Feel nature''s wrath! 感受自然的愤怒！ <br />- Death to all defilers! 污染者，受死！ <br />- None shall harm the wilds! 没有人可以伤害大自然！ <br /><br />月亮女祭祀- (英雄，城镇中心) <br />=建造音效= <br />- Warriors of the night, assemble! 夜之战士们，集结起来！ <br />=选定音效= <br />- We are poised to strike! 我们随时准备战斗！ <br />- We must act! 我们得行动了！ <br />- I am vigilant! 我时刻警惕着！ <br />- Trust in my command. 相信我的指挥吧！ <br />=行动/执行动作音效= <br />- [月光] Godess, grant me sight! 女神啊，赐予我慧眼吧！ <br />- [月反射] Let me bounce this off you. 从你身上反弹吧！ <br />- [灼光] Highbeams on! 强光照射！ <br />- [强击] Shoot to kill! 射杀！ <br />- [黎明] Darkness falls across the land. 黑暗降临大地（知道MJ的Thriller吗？Darkness Falls Across The Land ，The Midnight Hour Is Close At Hand，Creatures Crawl In Search Of Blood……''Cause This Is Thriller, Thriller Night……MJ开始与一群僵尸跳舞^o^ ） <br />- Leading the way! 领路！ <br />- Onward! 前进！ <br />- As I thought. 正合我意 <br />- The Godess agrees. 正如女神所愿 <br />=骂玩家音效= <br />- I command the army of Darkness! 我指挥着黑暗（暗夜）部队！ <br />- I''m caught between the moon and NightElf city. 我往返于月亮与夜精灵城之间 <br />- Come on! We''re burning moonlight. 来吧！我们是燃烧的月之光 <br />- When a Treant falls in the forest, does it make a sound? 一个树人在森林里倒下时，会发出声音吗？ <br />=攻击音效= <br />- [.vs 英雄] By the Godess! 以女神的力量！ <br />- Strike! 进攻！ <br />- For the Godess! 为了女神！ <br />- Prepare to be Moonstruck!准备接受月神之击！（Moonstruck的字典解释：源于月光能引起精神错乱的信仰，是不是有点讽刺？） <br /><br />Warden <br />守望者 <br />Ready - "My prey is near." ---我的猎物就在附近。 <br />Warcry - "Justice has come." ---审判降临。 <br />What1 - "Have you reached a verdict?"---你有判决了吗？ <br />What2 - "Let me investigate." ---让我来仔细调查 <br />What3 - (Elvish) <br />What4 - (Elvish) <br />What5 - "I am the iron hand of justice."---我是司法（正义）的铁碗。 <br />Yes1 - "Let the hunt begin."---狩猎开始吧。 <br />Yes2 - "Understood." ---明白。 <br />Yes4 - "I can taste their fear."---我能感觉到他们的恐惧。 <br />Yes5 - "Justice shall be swift." ---执法必须迅速。 <br />YesAttack1 - "They shall not escape!" ---他们决对逃脱不了！ <br />YesAttack2 - "Let justice be served!" ---为司法服务！ <br />YesAttack3 - "I am the law." ---我就是法律。 <br />Pissed1 - "I shall be your executioner." ---我会是你的死刑执行者。 <br />Pissed2 - "Only the guilty need fear me." ---只有犯罪者对我感到恐惧。 <br />Pissed3 - "Justice may be blind, but i'm not." ---司法可能有盲目，但，我没有。 <br />Pissed4 - "Truth, Justice and the Night Elf way." ---执行真理，正义和夜精灵的路线（方法？） <br />Pissed5 - "You think you're above the law?" ---你认为你能凌驾于法律之上？ <br />Pissed6 - "What we have here is a failure to communicate." ---我们在这所面对的是沟通的失败（既然已经这样，没有沟通的必要了。） <br />Pissed7 - "I hold you in contempt."---对你，我只有蔑视。（鄙视你！！！：） <br />Pissed8 - "He's no good to me if he's dead." ---他死了的话，对我毫无价值。（追杀狂。。。） <br />ORC的： <br />剑圣- (英雄，城镇中心) <br />=建造音效= <br />- I obey the six vengance! (原帖都没翻译...obey是执行的意思,vengance,复仇,报仇,连起来我也不知道.我执行这6个复仇?不通顺...) <br />=选定音效= <br />- I am yours! 我属于你！ <br />- Ohh! 噢！ <br />- Yesa, Lord!* 是，主人！ <br />- What task is there?有什么任务？ <br />=行动/执行动作音效= <br />- I hearo and obey!* 我听从命令！（剑圣说的是日式英语……把r音发成鲁等） <br />- Hai! 日语，嗨咿！ <br />- Excellent choice! 完美的选择！ <br />- Yes, huh! 是，哈！ <br />=骂玩家音效= <br />- Snatch the pebble from my hand, grasshopper! <br />- My a blade can cut through armor, and still cut a tomato!* 我的刀可以切穿盔甲，切到里面的番茄（心脏） <br />- Twin blade action, for clean, close shave everytime! 看我的双刀流……每次都可以把脸刮的很干净~（剔须刀呀？） <br />- Wasabi! 日语，芥末 （……剑圣整个一 *** 武士） <br />=Attack Sounds= <br />- [.vs 英雄] For the burning Blade! 为了燃烧之刃 <br />- Taste a* my blade! 尝尝我的利刃 <br />- Ailease! *喊声* <br />- Hooah! *吼声* <br /><br />先知- (英雄，城镇中心) <br />=建造音效= <br />- The future is ours! 未来属于我们！ <br />=选定音效= <br />- My eyes are open. 我洞悉一切 <br />- Seeing is believing! 眼见为实 <br />- Do you need my counsel? 需要我的忠告吗？ <br />- Destiny awaits. 命运在等待 <br />=行动/执行动作音效= <br />- It is certain. 确信无疑 <br />- Of course. 当然 <br />- I see. 明白 <br />- Watch out! <br />=骂玩家音效= <br />- I see dead people. 我看见死人了（开地图秘籍哦，果然是farseer） <br />- Touch you tongue to mine! 敢用你的舌头舔我！ (狼的呻吟声) <br />- Concentrate and ask again. 思想集中一点！再问我一遍 <br />- Outlook not so good. 前景不太理想（暗指微软的outlook不太好用） <br />- Reply hazy. Try again! 回答的摸棱两可，再说一遍！ <br />=攻击音效= <br />- [.vs 英雄] Spirits of Earth and Storm, strike! 大地与风暴的灵魂啊，攻击吧！ <br />- Strike! 进攻！ <br />- Look out! 注意！ <br />- Attack! 进攻！ <br /><br />牛头人酋长- (英雄，城镇中心) <br />=建造音效= <br />- I have an axe to grind! 我有把斧子要磨 <br />=选定音效= <br />- I stand ready! 我准备好了 <br />- Your command? 你的命令？ <br />- Your order? 你的指示？ <br />- What would you ask of me? 你要我做什么？ <br />=行动/执行动作音效= <br />- Done! 完成！ <br />- For my ancestors!为了我的祖先们！ <br />- An excellent plan! 好计划！ <br />- Yes Chieftan? 是，酋长？（他自己也是酋长哦） <br />=骂玩家音效= <br />- Mmmm. My back is killing me! 唔，我的后背要了我的命。 <br />- I need to take a load off! 我需要减轻负荷。 <br />- Rrrrggg! I think I have a splinter! 呃啊~~~~我想我的骨头碎了！ <br />- These poles are heavy, I should find someone else to tote em!这些柱子好沉啊，我该找别的人来背它（找个真人来作我的图腾） <br />- I used to have to go to war uphills, both ways!我以前打仗的时候还得上坡，两个方面…… <br />- Your way, right away! 一是你上，二是马上 <br />=攻击音效= <br />- [.vs 英雄] For the War Chief and the Tribes! 为了酋长和部落！ <br />- For the Tribes! 为了部落！ <br />- Honorguide me!* 荣誉引导着我！ <br />- None shall pass! 把命留下！ <br /><br />Shadow Hunter <br />暗影猎手 <br />Ready - "Want to see somethin' real scary?" ---想来点真正让人惊慌的玩意儿？ <br />Warcry - "It be the mad time man." ---这真是一个疯狂的时代。 <br />What1 - "Who do I kill first?" ---先来干掉哪个？ <br />What2 - "Where our enemies be hidin'?" ---我们的敌人藏身在哪里？ <br />What3 - "Use my power." ---以我的力量。 <br />What4 - "Direct my blade." ---指引我的利刃。 <br />What5 - "Who be my next victim?" ---接下来谁受死？ <br />Yes1 - "Move faster." ---行动更快些。 <br />Yes2 - "It be a pleasure." ---很乐意。 <br />Yes3 - "Right." ---的确。 <br />Yes5 - "We be jammin'." ---我们陷入了困境。 <br />Yes6 - *laughs* <br />Yes7 - "Ya man."---年轻人。 <br />YesAttack1 - "My blade be thirsty." ---我的刀刃渴望杀戮。 <br />YesAttack2 - "I pity the fool." ---我真为那些愚蠢的家伙感到可怜。 <br />YesAttack3 - "Killin' be easy." ---将他杀死，简单。 <br />YesAttack4 - "Die!" ---死吧。 <br />Pissed1 - "Keepin it real, up in the feal." ---保持真实，？？ <br />Pissed2 - "Your commander is a fool." ---你的指挥官是个傻瓜。 <br />Pissed3 - "Call me for your free reading." ---有免费阅读的话请叫上我。 <br />Pissed4 - "You're the baddest soul in town man." ---你是整个部落最糟糕的灵魂，小子。 <br />Pissed5 - "Humans. They think they know everything." ---人类，他们总以为自己无所不知。 <br />Pissed6 - "You lack discipline." ---你缺乏纪律。 <br />Pissed7 - "Stop whinin'." ---别再抱怨了，年轻人。 <br />Pissed8 - "Look at me. I'm happy." ---看看我。我多开心。 <br />Pissed9 - "Ooh, Baby."---喔，孩子。 <br />UD的： <br /><br />死亡骑士- (英雄，城镇中心) <br />=建造音效= <br />- The pact is sealed! 契约已订！ <br />=选定音效= <br />- You called? 你召唤我吗？ <br />- My patience has ended! 我的耐心已尽！ <br />- I am the Darkness! 我就是黑暗！ <br />- My vengence is yours! 你就是我的复仇！ <br />=行动/执行动作音效= <br />- Let battle be joined! 加入战斗！ <br />- As you order! 听从命令！ <br />- Hiyah! 嗨呀！ <br />- At last! 终于！ <br />- For the Lich King!为了巫妖王！ <br />=骂玩家音效= <br />- Has hell frozen over yet? 地狱还没有冻住吗？ <br />- I am the one horseman of the Apocalypse. 我是天命骑士之一。 <br />- I hate people, but I love gatherings! 我恨人们，但我喜欢收藏品 <br />- I''m a Death Night Rider! Muh ha ha ha 我是一个死亡骑士（死掉的夜骑士）！啊哈哈哈 <br />- Blueca!** <br />- Don''t touch me... I''m evil! 别碰我……我是邪恶的！ <br />=攻击音效= <br />- [.vs 英雄] Let terror reign! 让恐惧统治一切吧！ <br />- Feel my rath! 感受我的愤怒！ <br />- Ride or die! 逃跑还是受死！ <br />- By Nazul! 以Ner ''zhul的名义 <br /><br />恐惧之王- (英雄，城镇中心) <br />=建造音效= <br />- The night beckons! 夜在召唤！ <br />=选定音效= <br />- Greetings! 向您问候！ <br />- What, mortal? 什么事，凡人 <br />- What is it now? 现在呢？ <br />- I must hunt soon! 我立即行动！ <br />=行动/执行动作音效= <br />- That was my plan! 正是我的计划！ <br />- Agreed! 同意！ <br />- Very well. 很好！ <br />- You thought of that? 你也那么想？ <br />=骂玩家音效= <br />- If I have wings, why am I always walking? 既然我有翅膀，为什么我总是步行？ <br />- (电话铃声) Yes? Arrgghh! For the last time, I''m a Dread Lord, not a Drug Lord! 喂？啊！！我说最后一次，我是一个恐怖魔王，不是毒品王！ <br />- This is not a dress, it''s the standard Dread Lord uniform!这不是一般的服装，这是恐怖魔王标准套装！ <br />- Dress to kill! Blah! 是穿来杀人的！废话！ <br />- (电话铃声) Yes? Darkness, hey, what''s up? The Demon Hunter left you a message? No, I don''t have his number. 喂？黑暗之王吗？嗨，情况如何？恶魔猎手给你留了条短信？哦，不，我没有他的号码。 <br />- And then, after I overthrow this fool... Oh! Hello! I didn''t know you were there. 然后，我揭穿这个笨蛋……啊，喂，我不知道你在那 <br />- Imbisile! 不可思议 <br />=攻击音效= <br />- [.vs 英雄] Your soul is mine! 你的灵魂属于我！ <br />- I hunger! 我饥渴！ <br />- Deathrageous! 死之怒！ <br />- Die! 死吧！ <br /><br />巫妖- (英雄，城镇中心) <br />=建造音效= <br />- The ancient evil survives! 远古邪恶生还了！ <br />=选定音效= <br />- I am sworn to Nazul! 我效忠于Ner ''zhul ！ <br />- Thy bidding? 你的命令？ <br />- Direct me! 指示我吧！ <br />- Yours to command! 由你指挥！ <br />=行动/执行动作音效= <br />- [清醒] Cllleeaarrr! 了 解！！！ <br />- [冰霜铠甲] Nazul protect them!Ner ''zhul保护他们！ <br />- [冰河] Freeze! 结冻吧 <br />- [召唤冰龙] Rise from your grave! 从坟墓中复活吧！ <br />- So be it! 正是如此！ <br />- By your words! 听你的！ <br />- It it destined! 这是宿命！ <br />- Dead man walking! 死者在行走啊！ <br />- Chilling! 颤抖吧！ <br />=骂玩家音效= <br />- Could you chew that up for me? 能帮我咀嚼一下吗？ <br />- I''m so poor, I don''t even have calcium deposits! 我真可怜，我甚至连个钙质的驱壳都没有。 <br />- I am the Ghost of Warcraft past.我是魔兽之幽灵。 <br />- I hear that banshee''s a real screamer! 我听见女妖还真是能喊哪！ <br />- You should see the skeletons in my closet! 你该看看我橱子里的骷髅！ <br />- Im hoe chap!** <br />- All the ladies dig rigor mortis. 女人们在掘坟。 <br />- You are the Weakest Link, goodbye! 你是最烂的链接，再见 <br />=攻击音效= <br />- [.vs 英雄] For the burning Legion! 为了燃烧军团！ <br />- Embrace the end! 接受这个结局吧！ <br />- I will crush you! 我要灭了你！ <br />- Embrace the cold!接受寒冷吧！ <br /><br />Crypt Lord <br />地穴领主 <br />Ready - "From the depths I come." ---我从深渊而来！（我从深奥中来！） <br />Warcry - "For the frozen throne." ---为了寒冰王座！ <br />What1 - "Speak." ---讲。 <br />What2 - "I have heard the summons."---我已听到了召唤。 <br />What3 - "Time is fleeting." ---时间飞逝。（它是古老的蜘蛛帝国的皇帝） <br />What4 - "My might cannot be matched." ---我的威力无可匹敌！ <br />What5 - "I serve only the frozen throne." ---我只为寒冰王座服务！（我只出现在资料片中。） <br />Yes1 - "Ill see to it." ---我会注意的。 <br />Yes2 - "By Nerub." ---为了Nerub（蜘蛛帝国）。 <br />Yes3 - "Indubitably." ---毫无疑问。 <br />Yes4 - "Cheeky." ---厚颜无耻。 <br />Yes5 - "Ill consume the living and the dead." ---疾病毁灭生存者和死亡者。 <br />YesAttack1 - "Oblivion awaits." ---赦免在等待。 <br />YesAttack2 - "Feel the venom of Nerub." ---感受Nerub的怨恨！ <br />YesAttack3 - "Raid!" ---袭击！ <br />Pissed1 - "The scourge will devour all." ---天灾将吞噬一切！ <br />Pissed2 - "The strands of destiny weave only a web of death." ---命运之网，死亡之网。 <br />Pissed3 - "It was good to be the king." ---身为国王，感觉不错。 <br />Pissed4 - "Humans check in. They don't check out." ---人类登记进来，却不能登记离开。 <br />Pissed5 - "I'm the fifth beatle."---我是第五只甲壳虫。（我是第五位披头士。*beatles，披头士，甲客虫，著名的四人 乐队*） <br />Pissed6 - "And they say Blizzard games don't have bugs."---他们说blizzard的游戏没有虫子。（他们说bizzard的游戏 没有bugs。） <br />HUM的： <br />大法师- (英雄，城镇中心) <br />=建造音效= <br />- This had better be worth it! 这样做最好值得！ <br />=选定音效= <br />- You require my assistance? 需要我的协助吗？ <br />- What is it now? 现在如何？ <br />- Get on with it! 继续！ <br />- Well? 什么？ <br />=行动/执行动作音效= <br />- I can hardly wait! 我不能再等了！ <br />- Perfect! 好极了！ <br />- Whatever! 怎样都行！ <br />- Fine! 很好！ <br />=骂玩家音效= <br />- Don''t you have a strategy? 你就不能有点战略吗？ <br />- Your prattle begins to annoy me. 我开始对你的天真感到厌烦了 <br />- You''d best stay clear of me, or I''ll turn you into a mindless sheep! 你最好别碰我，不然我会把你变成一只没大脑的绵羊！ <br />- I don''t waste my magic on just anything! 我不会随便浪费我的魔法的 <br />=攻击音效= <br />- [.vs 英雄] For glory! 为了荣誉！ <br />- To battle! 战斗啊！ <br />- For glory! 为了荣誉！ <br />- Nimflorie frostades seda!** （吟唱咒语） <br /><br />山丘之王- (英雄，城镇中心) <br />=建造音效= <br />- Alright, who wants some? 好吧，谁想来试试 <br />=选定音效= <br />- Aye? 什么？ <br />- Wait ''til you see me in action!* 等待行动指示 <br />- Give me something to do! 让我做点事吧 <br />- Hmmmph! 恩！ <br />=行动/执行动作音效= <br />- Brilliant! 英明！ <br />- I''m coming through! 我来了！ <br />- Move it! 行动！ <br />- Out of my way! 让开！ <br />=骂玩家音效= <br />- Could you put some bonus points in my drinking skills? 你能给我的喝酒技能升几级吗？ <br />- Any fish and chips shops about here?* 这附近有炸鱼土豆片卖吗？ <br />- I think it''s time for a nippy sweetie!** 我认为该吃点心了。 <br />- What the bloody hell are you playin'' at?* 该死的，你在玩些什么啊？ <br />- There''s nothing more motivatin'' than fightin'' with a bad hangover!* 喝的烂醉然后打仗最爽了！ <br />- Where''s the pub? 酒馆在哪？ <br />- Let''s get PIST! 去喝个痛快吧！ <br />=攻击音效= <br />- [.vs 英雄] For Kazmodon!** 为了Kazmodon！ <br />- To arms! 拿起武器！ <br />- Death comes for ye!* 死神来找你了！ <br />- I''ll run em through!* 我来搞定他们！ <br />- Watch this! 看这招！ <br /><br />圣骑士- (英雄，城镇中心) <br />=建造音效= <br />- I live to serve all believers! 我为服务信徒而生！ <br />=选定音效= <br />- What would you ask of me? 您要我做什么？ <br />- I am not afraid! 我没有恐惧！ <br />- Let me face the peril! 让我来面对危险！ <br />- At your call! 为您效劳！ <br />=行动/执行动作音效= <br />- [驱魔] Strike down upon thee with great vengance and fury! 以复仇的愤怒力量击倒汝！ <br />- As you wish! 随你所愿！ <br />- For honor! 为了荣誉！ <br />- For my people! 为了我的人民！ <br />- It shall be done! 理应如此！ <br />=骂玩家音效= <br />- It''s hammer time! 该抡起锤子了！ <br />- I want to be your sledge hammer! 我愿成为您的巨锤！ <br />- Touch me not, I am chaste! 别碰我，我是纯洁的 <br />- No, is that your final answer? 不，那就是你最后的回答？ <br />- I have bad brethren 我已经有很多兄弟了。 <br />- Is that a sword? Luxury! Is that a horse? Sloth! Is that a helmet? Vanity! 那是剑吗？奢侈！那是马吗？懒惰！那是头盔吗？虚荣！ <br />=攻击音效= <br />- [.vs 英雄] In Lightbringer''s name, have at thee! 以光明使者的名义，进攻汝！ <br />- Justice will be served! 公正终将得以伸张 <br />- Defending your name! 捍卫您的名誉！ <br />- Death to the infidels!异端者死！ <br /><br />BloodMage <br />血法师 <br />Ready - "Burning to avenge" ---复仇在燃烧 <br />Warcry - "By the blood of the high-born!" ---为了高等精灵之血！ <br />What1 - "Do you see something?" --你看到什么了吗？ <br />What2 - (Elvish) ---（精灵语） <br />What3 - "Evil is near." ---邪恶就在附近 <br />What4 - "I am here, mortal." ---我在这，人类。 <br />What5 - "This battle bores me." ---战争让我厌倦 <br />Yes1 - (Elvish) <br />Yes2 - "For my people."---为了我的人民 <br />Yes3 - (Elvish) <br />Yes4 - "For now."---就是现在。 <br />Yes5 - "Bah, childs play."---呸，小孩子的玩意儿。 <br />YesAttack1 - "I'll incinerate them." ---我来把他们烧成灰烬。 <br />YesAttack2 - "For Quel'Thalas!" ---为了Quel'Thalas！（高等精灵国家） <br />YesAttack3 - "They shall burn" ---他们该被烧尽。 <br />Pissed1 - "The blood of the high-born is my birth right." ---高等精灵之血是我出生的权利。 <br />Pissed2 - "The ghosts of Quel'Thalas cry out for vengeance" ---Quel'Thalas的灵魂在呼喊着复仇。 <br />Pissed3 - "I find your insolence disturbing" ---你的傲慢让人恶心。 <br />Pissed4 - "If you dont master your anger, your anger will master you. I should know" ---如果你不能控制你的愤怒， 你就会被你的愤怒控制。我应该知道的。（却没有做到。。）（玩游戏也是一样，If you don't master your game,your game will master you,we should know.:） <br />Pissed5 - "Hi. My... name is Roy. I'm a magic addict." *murmuring*"Hi Roy" ---“hi，我的名字。。。是Roy，我为魔法痴迷”。*自言自语声*hi，Roy。（学魔法的家伙，多少有点神经。。） <br />Pissed6 - "My blood cries out for the vengeance of my people's blood. Which can only be repaid with at least twice as much blood. Or maybe three times as much blood. Like if you went to hell, and it was full of blood. And that blood was on fire. And it was raining blood. And maybe that would be enough blood. Ehh, but probably not." <br />---我的血液在为我族人的血液呼喊着复仇。至少必须用两倍的血液来偿还。或者是三倍的血液。而如果你去了地狱，那儿整个世界都是血，并且是燃烧着的血，并且天空也在下血。而这可能就是足够多的血了。呃，也许不是。。（果然是bloodmage，一句话到处都是blood。 <br />并且值得注意的是，这里有个很有趣的地方：在twice之前有2个blood，在three之前有3个blood，将full和fire看成four和five*谐音*，那么full之前也是4个blood。而fire所指的‘that blood’，就是full后面的那个，正是第五个blood。当然这只是我个人的看法，不知道是不是正确的：）<img src ="http://www.blogjava.net/ytfei/aggbug/57894.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/ytfei/" target="_blank">飞翔</a> 2006-07-13 08:54 <a href="http://www.blogjava.net/ytfei/archive/2006/07/13/57894.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>