﻿<?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-XZC</title><link>http://www.blogjava.net/xzc0202/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 06:04:50 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 06:04:50 GMT</pubDate><ttl>60</ttl><item><title>Java同步机制总结--synchronized</title><link>http://www.blogjava.net/xzc0202/archive/2014/04/09/412147.html</link><dc:creator>xzc0202</dc:creator><author>xzc0202</author><pubDate>Wed, 09 Apr 2014 07:27:00 GMT</pubDate><guid>http://www.blogjava.net/xzc0202/archive/2014/04/09/412147.html</guid><wfw:comment>http://www.blogjava.net/xzc0202/comments/412147.html</wfw:comment><comments>http://www.blogjava.net/xzc0202/archive/2014/04/09/412147.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzc0202/comments/commentRss/412147.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzc0202/services/trackbacks/412147.html</trackback:ping><description><![CDATA[引用：<a href="http://leo-faith.iteye.com/blog/177779">http://leo-faith.iteye.com/blog/177779</a><span class="Apple-style-span" style="font-family: Helvetica, Tahoma, Arial, sans-serif; font-size: 12px; line-height: 18px; background-color: #ffffff; "><div id="blog_content" class="blog_content" style="font-size: 14px; line-height: 1.8em; ">不久前用到了同步，现在回过头来对JAVA中的同步做个总结，以对前段时间工作的总结和自我技术的条理话。JAVA中synchronized关键字能够作为函数的修饰符，也可作为函数内的语句，也就是平时说的同步方法和同步语句块。假如再细的分类，synchronized可作用于instance变量、object reference（对象引用）、static函数和class literals(类名称字面常量)身上。&nbsp;<br />在进一步阐述之前，我们需要明确几点：&nbsp;<br />A．无论synchronized关键字加在方法上还是对象上，他取得的锁都是对象，而不是把一段代码或函数当作锁&#8213;&#8213;而且同步方法很可能还会被其他线程的对象访问。&nbsp;<br />B．每个对象只有一个锁（lock）和之相关联。&nbsp;<br />C．实现同步是要很大的系统开销作为代价的，甚至可能造成死锁，所以尽量避免无谓的同步控制。&nbsp;<br />接着来讨论synchronized用到不同地方对代码产生的影响：&nbsp;<br /><br />假设P1、P2是同一个类的不同对象，这个类中定义了以下几种情况的同步块或同步方法，P1、P2就都能够调用他们。&nbsp;<br /><br />1．&nbsp; 把synchronized当作函数修饰符时，示例代码如下：&nbsp;<br />Public synchronized void method(){&nbsp;<br />//&#8230;.&nbsp;<br />}&nbsp;<br />这也就是同步方法，那这时synchronized锁定的是哪个对象呢？他锁定的是调用这个同步方法对象。也就是说，当一个对象P1在不同的线程中执行这个同步方法时，他们之间会形成互斥，达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。&nbsp;<br />上边的示例代码等同于如下代码：&nbsp;<br />public void method()&nbsp;<br />{&nbsp;<br />synchronized (this)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; (1)&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&#8230;..&nbsp;<br />}&nbsp;<br />}&nbsp;<br />(1)处的this指的是什么呢？他指的就是调用这个方法的对象，如P1。可见同步方法实质是将synchronized作用于object reference。&#8213;&#8213;那个拿到了P1对象锁的线程，才能够调用P1的同步方法，而对P2而言，P1这个锁和他毫不相干，程式也可能在这种情形下摆脱同步机制的控制，造成数据混乱：（&nbsp;<br />2．同步块，示例代码如下：&nbsp;<br />public void method(SomeObject so) {&nbsp;<br />synchronized(so)&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&#8230;..&nbsp;<br />}&nbsp;<br />}&nbsp;<br />这时，锁就是so这个对象，谁拿到这个锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时，就能够这样写程式，但当没有明确的对象作为锁，只是想让一段代码同步时，能够创建一个特别的instance变量（他得是个对象）来充当锁：&nbsp;<br />class Foo implements Runnable&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private byte[] lock = new byte[0];&nbsp; // 特别的instance变量&nbsp;<br />&nbsp;&nbsp;&nbsp; Public void method()&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(lock) { //&#8230; }&nbsp;<br />}&nbsp;<br />//&#8230;..&nbsp;<br />}&nbsp;<br />注：零长度的byte数组对象创建起来将比任何对象都经济&#8213;&#8213;查看编译后的字节码：生成零长度的byte[]对象只需3条操作码，而Object lock = new Object()则需要7行操作码。&nbsp;<br />3．将synchronized作用于static 函数，示例代码如下：&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class Foo&nbsp;<br />{&nbsp;<br />public synchronized static void method1()&nbsp;&nbsp; // 同步的static 函数&nbsp;<br />{&nbsp;<br />//&#8230;.&nbsp;<br />}&nbsp;<br />public void method2()&nbsp;<br />{&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; synchronized(Foo.class)&nbsp;&nbsp; //&nbsp; class literal(类名称字面常量)&nbsp;<br />}&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;<br />&nbsp;&nbsp; 代码中的method2()方法是把class literal作为锁的情况，他和同步的static函数产生的效果是相同的，取得的锁很特别，是当前调用这个方法的对象所属的类（Class，而不再是由这个Class产生的某个具体对象了）。&nbsp;<br />记得在《Effective Java》一书中看到过将 Foo.class和 P1.getClass()用于作同步锁还不相同，不能用P1.getClass()来达到锁这个Class的目的。P1指的是由Foo类产生的对象。&nbsp;<br />能够推断：假如一个类中定义了一个synchronized的static函数A，也定义了一个synchronized 的instance函数B，那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时，不会构成同步，因为他们的锁都不相同。A方法的锁是Obj所属的那个Class，而B的锁是Obj所属的这个对象。&nbsp;<br /><br />小结如下：&nbsp;<br />搞清楚synchronized锁定的是哪个对象，就能帮助我们设计更安全的多线程程式。&nbsp;<br /><br /><br />更有一些技巧能够让我们对共享资源的同步访问更加安全：&nbsp;<br />1．&nbsp; 定义private 的instance变量+他的 get方法，而不要定义public/protected的instance变量。假如将变量定义为public，对象在外界能够绕过同步方法的控制而直接取得他，并改变他。这也是JavaBean的标准实现方式之一。&nbsp;<br />2．&nbsp; 假如instance变量是个对象，如数组或ArrayList什么的，那上述方法仍然不安全，因为当外界对象通过get方法拿到这个instance对象的引用后，又将其指向另一个对象，那么这个private变量也就变了，岂不是很危险。 这个时候就需要将get方法也加上synchronized同步，并且，只返回这个private对象的clone()&#8213;&#8213;这样，调用端得到的就是对象副本的引用了。</div></span><img src ="http://www.blogjava.net/xzc0202/aggbug/412147.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzc0202/" target="_blank">xzc0202</a> 2014-04-09 15:27 <a href="http://www.blogjava.net/xzc0202/archive/2014/04/09/412147.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire：轻松简单地开发Web Services</title><link>http://www.blogjava.net/xzc0202/archive/2006/10/08/73841.html</link><dc:creator>xzc0202</dc:creator><author>xzc0202</author><pubDate>Sun, 08 Oct 2006 07:40:00 GMT</pubDate><guid>http://www.blogjava.net/xzc0202/archive/2006/10/08/73841.html</guid><wfw:comment>http://www.blogjava.net/xzc0202/comments/73841.html</wfw:comment><comments>http://www.blogjava.net/xzc0202/archive/2006/10/08/73841.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/xzc0202/comments/commentRss/73841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzc0202/services/trackbacks/73841.html</trackback:ping><description><![CDATA[
		<div class="center">
				<h4>摘要:</h4>XFire是一个免费的开源SOAP框架，它不仅可以极大方便地实现这样一个环境，并且可以提供许多Web Services规范中高级特征，这些特征在多数的商业或者开源工具都没有提供。你要恰当的理解这些单词：great ease and simplicity（非常轻松和简单）。你将会看到使用XFire创建Web Services是多么的简单。 </div>
		<div class="right">
				<div class="help">
						<h4>工具箱</h4>
						<a href="http://www.matrix.org.cn/favorite.shtml?type=article&amp;title=XFire%25EF%25BC%259A%25E8%25BD%25BB%25E6%259D%25BE%25E7%25AE%2580%25E5%258D%2595%25E5%259C%25B0%25E5%25BC%2580%25E5%258F%2591Web%2520Services&amp;url=resource%2Farticle%2F2006-09-24%2FXFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html">本站收藏</a>
						<br />
						<a onclick="javascript:location.href='http://del.icio.us/post?&amp;url='+encodeURIComponent(location.href)+'&amp;title='+encodeURIComponent(document.title)" href="http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html#">美味书签</a>
						<br />
						<a href="http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html#avote">投票评分</a>
						<br />
						<a href="http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html#areview">发表评论</a>
						<br />
						<a title="点击后直接粘贴即可" onclick="copyLink();" href="http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html#">复制链接</a>
						<br />
				</div>
		</div>
		<!-- end of summary line -->
		<div class="overflow" id="text">
				<b>
						<span style="FONT-SIZE: 20px">将你的POJO方法发布为Web Services</span>
				</b>
				<br />
				<br />
				<b>
						<span style="FONT-SIZE: 16px">摘要</span>
				</b>
				<br />
				<br />问一下.Net的开发者，开发Web Services有多困难？他们会被你的问题逗乐，他们会告诉你所有步骤花费的时间不会超过一分钟。再问一下Java开发者，运气好的话你会碰到上面的回答，一般情况下，你会得到一个完全不同的答案。从Web Services引入到Java中至今已经5年了，然而它仍然被认为是一门较新的技术，一个主要的原因就是使用Java实现Web Services太困难了。现在，随着新一代Web Services引擎XFire的发布，这种情况将会发生明显的变化。使用XFire，你可以把Java类方法发布为Web Services而不需要编写额外的代码。在这篇文章中，你将会看到XFire使Web Services开发变得多么容易和简单。<br /><br />Web Services使我们能够在网络上建立分布式系统，应用程序组件可以通过任何平台、任何语言和任何方式访问。无论应用程序如何开发，使用了什么语言，以及运行在什么操作系统平台上，只要它作为Web Service，并且为协同解决问题而设计，那么你的应用程序，以任何语言开发或在任何平台上，都可以利用它的服务。这是Web Service的主要概念。<br /><br />为了实现Web Services的平台无关性和实现访问独立性，软件行业需要遵循一些作为标准的技术。其中一些包括：<br />---XML：在Web Services环境中各层之间进行传递的默认数据格式。<br />---SOAP：封装和交换信息的默认协议。第一次被提出时，它是只取Simple Object Access Protocol（简单对象访问协议）的首字母。但是现在SOAP更多被认为是一个特定的名词，以它自己而命名，同样很多人认为这是用词不当：SOAP实际上不是用来访问对象的。另外，它也不再简单。<br />---WSDL（Web Services Description Language，Web Services描述语言）：描述Web Services的语言。尽管基于XML并且可以被人理解，WSDL主要是由机器处理，由客户端程序读取和理解。<br /><br />下面的高级层次图表，基于WWW协会发布的“Web Services Architecture”（Web Services架构）文档，显示了这些技术在实际的工作环境中是如何发挥作用：<br /><br /><img style="DISPLAY: inline" onclick="javascript:imgClick(this);" alt="image" src="http://www.matrix.org.cn/resource/upload/forum/2006_09_24_200650_HCFUExJrIl.jpg" width="600" onload="javascript:imgLoad(this);" border="0" resized="1" /><br />这个流程图显示了Web Services中的核心技术是如何工作的。<br /><br />这里，Provider是提供服务的应用程序组件，Requester是使用服务的客户端程序。很多其他技术也会参与到交互中，但是这个图只显示了在Web Services环境中必需的核心技术组件。<br /><br />XFire是一个免费的开源SOAP框架，它不仅可以极大方便地实现这样一个环境，并且可以提供许多Web Services规范中高级特征，这些特征在多数的商业或者开源工具都没有提供。你要恰当的理解这些单词：great ease and simplicity（非常轻松和简单）。你将会看到使用XFire创建Web Services是多么的简单。<br /><br />假如你的Web应用有一个Java类，并且你想把它的一个方法发布为Web Services，当使用XFire时，你不需要编写一行额外的Java代码。只需要编辑发布描述符，然后你就会得到一个Web Services。是的，它相当地简单。我们来看一个例子。<br /><br /><span style="COLOR: red">版权声明：任何获得Matrix授权的网站，转载时请务必保留以下作者信息和链接</span><br />作者:Shahid Ahmed ;<a href="http://www.matrix.org.cn/user.shtml?username=mydeman" target="_new">mydeman</a><br />原文:<a href="http://www.javaworld.com/javaworld/jw-05-2006/jw-0501-xfire.html" target="_new">http://www.javaworld.com/javaworld/jw-05-2006/jw-0501-xfire.html</a><br />Matrix:<a href="http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html" target="_new">http://www.matrix.org.cn/resource/article/2006-09-24/XFire_6bd1061c-4bc6-11db-978f-43b3336b7e51.html</a><br />关键字:XFire;Web Services<br /><br /><b><span style="FONT-SIZE: 16px">一个简单的Java类</span></b><br /><br />我们的例子是一个银行业应用程序，服务器是运行在J2SE1.4.2_07下的Apache Tomcat5.5.7。假定你已经了解如何使用Java编写Web应用程序，并知道应该如何把它部署到Apache Tomcat服务器上。我们的Web应用程序非常简单；它只做一件事——将资金从一个账户转到另外一个账户上。一个普通的Java类BankingService包含了一个叫做transferFunds()的方法来为我们完成这项工作。它需要四个输入参数：<br />1、        String fromAccount<br />2、        String toAccount<br />3、        double amount<br />4、        String currency<br /><br />代码如下：<br /><pre class="overflow">package com.mybank.xfire.example;<br /><br />import java.text.NumberFormat;<br />import java.text.DecimalFormat;<br /><br />/** XFire WebServices sample implementation class. <br />*/<br />public class BankingService implements IBankingService {<br />    <br />    //Default constructor.<br />    public BankingService(){    <br />    }<br />    <br />    /** Transfers fund from one account to another.<br />    */<br />    public String transferFunds(<br />        String fromAccount, String toAccount, double amount, String currency){<br />        <br />        String statusMessage = "";<br />                      <br />        //Call business objects and other components to get the job done.<br />        //Then create a status message and return.<br />        try {<br />            NumberFormat formatter = new DecimalFormat("###,###,###,###.00");       <br />            statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+ <br />            " was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount;<br />        } catch (Exception e){<br />            statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString();<br />        }<br />        return statusMessage;<br />    }<br />    <br />}</pre><br /><br />在这里你看到了什么异常的东西了吗？或许没有，除了默认的构造函数，类型是public。这是必须的。否则，XFire不能够初始化这个类。<br /><br />因为使用接口的设计是一个好的实践，所以我们的Java类也实现了一个称为IBankingService的接口。代码十分简单：<br /><pre class="overflow">package com.mybank.xfire.example;<br /><br />public interface IBankingService {  <br /><br />    public String transferFunds(<br />        String fromAccount, String toAccount, double amount, String currency);<br />        <br />}</pre><br /><br />在实际实现中，这样一个方法可能包括各种类型的复杂调用、查询和处理操作。但是我们的示例代码已经最小化了，以至于我们可以集中精力在主要目标上：把这个方法发布为Web Services。<br /><br />你可以看到BankingService是一个普通的Java类，没有任何代码告诉我们它将会在Web Services中使用。好的，这里我们不需要增加任何东西。我们所有的工作都在部署描述符里完成。<br /><br /><b><span style="FONT-SIZE: 16px">Web应用的部署描述符</span></b><br /><br />在Java中，Web应用程序通常需要至少一个部署描述符（叫做web.xml）对其进行配置。XFire本身是一个基于servlet的应用程序。因此，我们需要增加必要的引用到描述符文件中。然后我们还必须配置将要创建的Web Services。我们使用一个称为services.xml的新文件来完成这件事。<br /><br /><b>web.xml</b><br />首先，修改web.xml。我们需要增加下面的XFire servlet相关的条目：<br /><pre class="overflow">&lt;servlet&gt;<br />        &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />        &lt;display-name&gt;XFire Servlet&lt;/display-name&gt;<br />        &lt;servlet-class&gt;org.codehaus.xfire.transport.http.XfireConfigurableServlet<br />         &lt;/servlet-class&gt;<br />    &lt;/servlet&gt;<br /><br />    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/servlet/XFireServlet/*&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt;<br />    <br />    &lt;servlet-mapping&gt;<br />        &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />        &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;<br />    &lt;/servlet-mapping&gt;</pre><br /><br /><b>services.xml</b><br />现在我们不得不说一下我们的Web Services的由什么组成的了。这由一个叫做services.xml的文件完成，它存放在META-INF/xfire目录下，而这整个目录放在WEB-INF/classes文件夹中，它在Web应用程序的标准类路径中。这里是services.xml中的基本配置条目：<br /><pre class="overflow">&lt;beans xmlns="http://xfire.codehaus.org/config/1.0"&gt;<br />  <br />  &lt;service&gt;<br />    &lt;name&gt;Banking&lt;/name&gt;<br />    &lt;namespace&gt;mybank&lt;/namespace&gt;<br />    &lt;serviceClass&gt;com.mybank.xfire.example.IBankingService&lt;/serviceClass&gt;<br />    &lt;implementationClass&gt;com.mybank.xfire.example.BankingService&lt;/implementationClass&gt;<br />  &lt;/service&gt;  <br />  <br />&lt;/beans&gt;</pre><br /><br />让我们看看这里都包含了什么内容。Web Services的定义包含在&lt;service&gt;元素中，它还含有一些子元素。第一个子元素是&lt;name&gt;，它可以是你提供任何的合法名字。这将会被客户端程序和其它需要定位你的服务的组件用到。例如，在服务准备好以后，你将在浏览器上使用这个名字来查看WSDL。<br /><br />下一个子元素是&lt;namespace&gt;。任何合法的XML名字都是可以的。&lt;namespace&gt;用来唯一标识你的服务的各个参数。<br />&lt;serviceClass&gt;元素包含了Java类的名字，它指定了方法签名。在我们的例子中，它是接口IBankingService。如果Java类没有实现任何接口，你就需要把类的名字放在这里。在你的Java类或者接口中可能有几个方法。只需要一个入口把它们全部发布为Web Services。<br /><br />&lt;implementationClass&gt;保存了实现方法的Java类名。这是一个可选元素。如果上一个元素&lt;serviceClass&gt;包含了一个接口，那么相应的实现类必须在这里指定。<br /><br />就是这样。我们的Web Services配置完成了。<br /><br /><b><span style="FONT-SIZE: 16px">XFire和其它类库</span></b><br /><br />现在是最后一步了，需要得到所有必需的类库。我们怎样得到它们呢？去XFire网站，下载xfire-distribution-1.0.zip，然后解压到一个本地文件夹。复制下面的jar文件和它的库文件夹到WEB-INF/lib中：<br />•        activation-1.0.2.jar <br />•        commons-codec-1.3.jar <br />•        commons-httpclient-3.0.jar <br />•        commons-logging-1.0.4.jar <br />•        jaxen-1.1-beta-8.jar <br />•        jdom-1.0.jar <br />•        log4j-1.2.x.jar <br />•        mail-1.3.3_01.jar <br />•        spring-1.2.x.jar <br />•        stax-api-1.0.jar <br />•        wsdl4j-1.5.2.jar <br />•        wstx-asl-2.9.jar <br />•        xbean-2.1.0.jar <br />•        xbean-spring-2.2.jar <br />•        xfire-all-1.0.jar <br />•        XmlSchema-1.0.jar<br /><br />一切妥当。我们来部署和启动应用程序。为了部署示例应用，只需要复制websvc.war到Apache Tomcat的webapps文件夹中，再等待几秒钟。它将会自动启动。这个应用的全部源代码也包含在这个war文件中。我们的程序已经准备作为一个Web Service了。<br /><br /><b><span style="FONT-SIZE: 16px">我们如何知道Web Service正在工作呢？</span></b><br /><br />为了了解Web Service是否正在工作，我们需要测试。首先，我们测试来看WSDL是否可用。我们在浏览器中输入URL。哪个URL？因为我们的应用程序的war文件是websvc.war，并且在services.xml中给出的服务名是Banking，WSDL的URL应该是：http://localhost:8080/websvc/services/Banking?wsdl。<br /><br />请注意：URL的第一部分，例如，http://localhost:8080，可能会根据你的应用服务器不同而不同。无论怎样，当你输入URL后，将会看到一个XML文档，它的根元素是&lt;wsdl:definitions&gt;。这个文档叫做服务的WSDL。如果你看到了，这就是你的应用作为Web Service已经可用的第一个证明。<br /><br />但是这个测试是不够的。可能会发生这种情况，可以看到WSDL，但是从客户端程序可能会访问不到服务。因此为了核实服务是否可以访问了，我们必须使用一个客户端进行服务的实际调用来进行一个真正的测试。<br /><br /><b><span style="FONT-SIZE: 16px">开发一个客户端</span></b><br /><br />你可以使用任何的SOAP工具创建客户端，例如，.Net或者Apache Axis，有很多种方法：使用从WSDL产生的stubs，使用动态代理，等等。在例子中，我们使用一个动态代理，以一个简单的Servlet形式，叫做WsClient.java。为了保持代码两最小，所有在屏幕显示的元素都放在了doGet()方法中。对Web Service的实际调用由callWebService()方法完成，它相当地简单。和下面的类似：<br /><pre class="overflow">/* Call the Web service<br />    *<br />    */<br />    public String callWebService(<br />        String fromAccount, String toAccount, double amount, String currency) <br />        throws MalformedURLException, Exception {<br />        <br />        //Create a metadata of the service      <br />        Service serviceModel = new ObjectServiceFactory().create(IBankingService.class);        <br />        log.debug("callSoapServiceLocal(): got service model." );<br />   <br />        //Create a proxy for the deployed service<br />        XFire xfire = XFireFactory.newInstance().getXFire();<br />        XFireProxyFactory factory = new XFireProxyFactory(xfire);      <br />    <br />        String serviceUrl = "http://localhost:8080/websvc/services/Banking";<br />        <br />        IBankingService client = null;<br />        try {<br />            client = (IBankingService) factory.create(serviceModel, serviceUrl);<br />        } catch (MalformedURLException e) {<br />            log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());<br />        }    <br />               <br />        //Invoke the service<br />        String serviceResponse = "";<br />        try { <br />            serviceResponse = client.transferFunds(fromAccount, toAccount, amount, currency);<br />       } catch (Exception e){<br />            log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());                 <br />            serviceResponse = e.toString();<br />        }        <br />        log.debug("WsClient.callWebService(): status=" + serviceResponse);              <br /><br />        //Return the response<br />        return serviceResponse;<br />    }  </pre><br /><br />这个代码是如何工作的呢？我来解释一下：首先，我们创建一个服务模型，它包含服务的说明——换句话说，就是服务的元数据。我们使用XFire的ObjectServiceFactory从IBankingService.class接口创建这个模型。<br /><br />接着，为XFire获得一个代理工厂对象，它包含了常规的代码，也相当地简单和易懂。这一步中没有任何特定应用的东西。从这个proxyFactory，使用服务模型和服务端点URL（用来获得WSDL），我们可以得到一个服务的本地代理。<br /><br />就是它了。这个代理就是实际的客户端。现在，我们可以调用它的transferFunds()方法来得到我们需要的Web Service。<br />一旦示例应用发布并启动，就可以尝试servlet URL：<br />http://localhost:8080/websvc/ws。<br /><br />这个Servlet使用默认参数来调用Web Service和显示接收到的响应。页面的最后两行应该读取：<br />Response Received<br />COMPLETED: CDN$ 500.00 was successfully transferred from A/C# 11111-01234 to A/C# 99999-05678<br /><br />现在你可以确定Web Service已经发布并且在运行中了。<br /><br />为了尝试不同的输入值，你可以使用完整的URL，例如：<br />http://localhost:8080/websvc/ws?from=11-2345&amp;to=77-9876&amp;amt=250.00&amp;cur=EUR。<br /><br /><b><span style="FONT-SIZE: 16px">基本的Web Services开发步骤清单</span></b><br /><br />这个清单总结了将一个Java方法发布为Web Service所必须的步骤：<br />1、        检查Java类的方法和默认构造函数确保为public<br />2、        增加XFire servlet相关条目到web.xml中<br />3、        创建services.xml，把它放到WEB-INF/classes/META-INF/xfire目录下<br />4、        增加XFire和第三方包到你的Web应用的WEB-INF/lib文件夹中<br /><br />这就是所有需要的步骤，是的，相当简单。<br /><br /><b><span style="FONT-SIZE: 16px">XFire的其他高级特性</span></b><br /><br />XFire的使用可能比较简单，但是在特性和功能性上，它却占据着领导者的位置。下面是它的高级特性：<br />---本地数据绑定支持POJOs（plain-old Java objects）、XMLBeans、JAXB（Java Architecture for XML Binding）、Castor等等。数据绑定说明了Web Services的XML请求和映射到Java对象的XML响应。<br />---使用StAX（Streaming API for XML）处理XML文档。同DOM的基于树和SAX的事件驱动的处理方式相比，StAX使用了拉（pull）机制，它使处理更快速，内存效率更高。<br />---支持多种传输协议，如HTTP、JMS（Java Message Service）和JVM内部传输。<br />---嵌入式，这是XFire的核心功能之一。你可以把这个SOAP引擎嵌入到你的应用中，完全隐藏所有XFire特定引用，同样所有配置都是程序驱动。<br />---丰富的API，它使XFire可高度自定义，允许开发者在不同的阶段截获请求，并且对他们进行处理。<br />---兼容最新的标准例如SOAP1.1（没有加密远程工程调用，或者RPC）和1.2、WSDL1.1、the Web Services Interoperability Organization’s Basic Profile 1.0、Web Services Addressing和WS-Security。<br /><br />最重要的是，XFire属于新一代Web Services引擎。不仅仅是营销用语，“新一代”有一些重要的意义。Apache Axis是第一代Java语言的Web Services引擎，已经成为了所有后来工具的参考标准。在过去的几年里，Axis以及这些其它的工具已经在很多生产环境中进行了实地测试。从中得出的一个关键的问题就是Web Services并不最适合RPC类型的通信。对于性能和效率，面向文档的消息形式是最好的方式。但是Apache Axis和很多其他的Web Services引擎都被设计成了面向RPC的（尽管它们支持文档形式）。现在，整个行业正在开发新一代的SOAP引擎，设计为面向文档的。Apache已经宣布结束旧版本的Axis引擎开发，现在专注于Axis2，现在它的预发布版本是0.95。XFire在今年的2月份发布了它的第一个产品版本（1.0）。它的下一个版本（1.1）仅仅在几个星期之后就进行了发布。<br /><br /><b><span style="FONT-SIZE: 16px">性能</span></b><br /><br />Web Services需要消耗很多资源，但是性能方面它们不是那么引人注目。XFire打破了这种趋势。它消耗更少的内存（部分因为 StAX的使用），但是表现却比多数可比较的SOAP引擎出色。你可以在资源中提供的链接中看到比较的结果。<br />此外，XFire还提供了各种方法来进一步优化性能。一个方法是使用JVM内置传输（in-JVM transport）。如果你知道Web Services和客户端运行在同一个JVM上，你可以选择使用本地传输，它可以大幅提升性能。在示例中的客户端代码，看以下指定服务端点URL的这行：<br />String serviceUrl = "http://localhost:8080/websvc/services/Banking";<br />替换为<br />String serviceUrl = "xfire.local://Banking";<br /><br />你会看到性能上的明显提高，因为它绕过了整个网络层。<br /><br /><b><span style="FONT-SIZE: 16px">局限性</span></b><br /><br />XFire有些重要的局限性你应该清楚：<br />---开发Web Services的好的实践是从WSDL开始。大部分的SOAP引擎提供了从WSDL生成服务stub的工具。XFire也提供了这样一个工具。但是它是基于注释（annotations-based）的，因此需要J2SE5.0。对于仍坚持使用J2SE1.4.x的人来说，它不是一个令人拍手叫好的工具，因为我们有很多其他方式来编写客户端，一个就是文章中演示的方式。<br />---附件支持，它将会包含在未来发行的版本中。<br />---易于学习的用户向导。XFire团队在这个方面还有很多工作需要做。<br /><br /><b><span style="FONT-SIZE: 16px">结论</span></b><br /><br />Java当前的趋势是简化技术的使用。因此，我们正看到一波基于POJO的开发成就。同时，面向服务架构（SOA，Services-oriented architecture）和Web Services已经变成了当前行业的热点话题。XFire正是在这种情况下产生的。它能够使POJO发布为最少的Web Services，而只需要付出最小化的努力。从而，它使希望使用这项技术的初级开发者的学习曲线变得平缓。同时，由于它兼容最新标准和提供了丰富的API，XFire为高级用户提供了更多的大好机会。<br /><br /><b>关于作者</b><br />Shahid Ahmed是一个软件架构师，如今在美国一家主要的无线运行商作咨询工作。他在22年前开始开发软件，当时Kaypro、Osborne、Apple II和TRS-80s统治着整个地球。在过去的7年里，他更多的精力集中于Java。他现在的工作包括SOA、Web Services、消息、POJO、Spring、Ajax等等。Shahid是一个软件热衷者，每天都在奋斗以求在技术的迷恋和社会生活的热爱之间寻找平衡点。<br /><br /><b>资源：</b><br />Matrix Java社区:<a href="http://www.matrix.org.cn/" target="_new">http://www.matrix.org.cn</a><br />下载本文中的示例应用：<a href="http://www.javaworld.com/javaworld/jw-05-2006/xfire/jw-0501-xfire.zip" target="_new">http://www.javaworld.com/javaworld/jw-05-2006/xfire/jw-0501-xfire.zip</a><br />Web Services架构:http://www.w3.org/TR/ws-arch/ <br />WSDL2.0（原来提议为WSDL1.2，现在重新命名了）：第一部分：核心语言（W3C Candidate Recommendation 27 March 2006）<br /></div>
<img src ="http://www.blogjava.net/xzc0202/aggbug/73841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzc0202/" target="_blank">xzc0202</a> 2006-10-08 15:40 <a href="http://www.blogjava.net/xzc0202/archive/2006/10/08/73841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp + mysql 的分页程序</title><link>http://www.blogjava.net/xzc0202/archive/2006/10/08/73836.html</link><dc:creator>xzc0202</dc:creator><author>xzc0202</author><pubDate>Sun, 08 Oct 2006 07:22:00 GMT</pubDate><guid>http://www.blogjava.net/xzc0202/archive/2006/10/08/73836.html</guid><wfw:comment>http://www.blogjava.net/xzc0202/comments/73836.html</wfw:comment><comments>http://www.blogjava.net/xzc0202/archive/2006/10/08/73836.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/xzc0202/comments/commentRss/73836.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/xzc0202/services/trackbacks/73836.html</trackback:ping><description><![CDATA[&lt;%@ page contentType="text/html; charset=gb2312" %&gt;<br />&lt;%@ page language="java" %&gt;<br />&lt;%@ page import="com.mysql.jdbc.Driver" %&gt;<br />&lt;%@ page import="java.sql.*" %&gt;
<p>&lt;% <br /> Connection sqlCon; //数据库连接对象 </p><p> Statement sqlStmt; //SQL语句对象 </p><p> ResultSet sqlRst; //结果集对象 </p><p> String strCon; //数据库连接字符串 </p><p> String strSQL; //SQL语句 </p><p> int intPageSize; //一页显示的记录数 </p><p> int intRowCount; //记录总数 </p><p> int intPageCount; //总页数 </p><p> int intPage; //待显示页码 </p><p> String strPage; </p><p> int i; </p><p> intPageSize = 2; //设置一页显示的记录数 </p><p> strPage = request.getParameter("page"); //取得待显示页码 </p><p> if(strPage==null)<br /> { </p><p>  //表明在QueryString中没有page这一个参数，此时显示第一页数据 </p><p>  intPage = 1; </p><p> }<br /> else<br /> { </p><p>  //将字符串转换成整型 </p><p>  intPage = java.lang.Integer.parseInt(strPage); </p><p>  if(intPage&lt;1) intPage = 1; </p><p> } </p><p> //装载JDBC驱动程序 </p><p>   //驱动程序名</p><p>   String driverName="com.mysql.jdbc.Driver";</p><p>   //数据库用户名</p><p>   String userName="test";</p><p>   //密码</p><p>   String userPasswd="123456";</p><p>   //数据库名<br /> <br />   String dbName="shujuku";</p><p>   //表名</p><p>   String tableName="biao";</p><p>   //联结字符串</p><p>   String url="jdbc:mysql://localhost/"+dbName+"?user="+userName+"&amp;password="+userPasswd;</p><p>   Class.forName("com.mysql.jdbc.Driver").newInstance();</p><p>   sqlCon=DriverManager.getConnection(url);</p><p>   //创建语句对象 <br /> <br /> sqlStmt = sqlCon.createStatement(); //执行SQL语句 </p><p>    strSQL = "select name from " + tableName; </p><p>    //执行SQL语句并获取结果集 </p><p>    sqlRst = sqlStmt.executeQuery(strSQL); </p><p>    //获取记录总数 </p><p> sqlRst.last(); </p><p> intRowCount = sqlRst.getRow(); </p><p> //记算总页数 </p><p> intPageCount = (intRowCount+intPageSize-1) / intPageSize; </p><p> //调整待显示的页码 </p><p> if(intPage&gt;intPageCount) intPage = intPageCount; </p><p>%&gt; </p><p>&lt;html&gt; </p><p>&lt;head&gt; </p><p>&lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312"&gt; </p><p>&lt;title&gt;JSP数据库操作例程 - 数据分页显示 - JDBC 2.0 - mysql&lt;/title&gt; </p><p>&lt;/head&gt; </p><p>&lt;body&gt; </p><p>&lt;table border="1" cellspacing="0" cellpadding="0"&gt; </p><p>&lt;tr&gt; </p><p>&lt;th&gt;姓名&lt;/th&gt; </p><p>&lt;/tr&gt; </p><p>&lt;% if(intPageCount&gt;0) </p><p>{ </p><p> //将记录指针定位到待显示页的第一条记录上 </p><p> sqlRst.absolute((intPage-1) * intPageSize + 1); </p><p> //显示数据 </p><p> i = 0; </p><p> while(i&lt;intPageSize &amp;&amp; !sqlRst.isAfterLast()){ %&gt; </p><p>&lt;tr&gt; </p><p>&lt;td&gt; </p><p>&lt;%=sqlRst.getString(1)%&gt; </p><p>&lt;/td&gt; </p><p>&lt;/tr&gt; </p><p>&lt;% sqlRst.next(); </p><p>i++; </p><p>} </p><p>} </p><p>%&gt; </p><p>&lt;/table&gt; </p><p>第&lt;%=intPage%&gt;页 共&lt;%=intPageCount%&gt;页 </p><p>&lt;%if(intPage&lt;intPageCount){%&gt;&lt;a href="test1.jsp?page=&lt;%=intPage+1%&gt;"&gt;下一页&lt;/a&gt;&lt;%}%&gt; </p><p>&lt;%if(intPage&gt;1){%&gt;&lt;a href="test1.jsp?page=&lt;%=intPage-1%&gt;"&gt;上一页&lt;/a&gt;&lt;%}%&gt; </p><p>&lt;/body&gt; </p><p>&lt;/html&gt; </p><p>&lt;% </p><p>//关闭结果集 </p><p>sqlRst.close(); </p><p>//关闭SQL语句对象 </p><p>sqlStmt.close(); </p><p>//关闭数据库 </p><p>sqlCon.close(); </p><p>%&gt; <br /> <br /> <br /> </p><img src ="http://www.blogjava.net/xzc0202/aggbug/73836.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/xzc0202/" target="_blank">xzc0202</a> 2006-10-08 15:22 <a href="http://www.blogjava.net/xzc0202/archive/2006/10/08/73836.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>