﻿<?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-我的漫漫程序之旅-文章分类-WebService</title><link>http://www.blogjava.net/supercrsky/category/28819.html</link><description>专注于JavaWeb开发</description><language>zh-cn</language><lastBuildDate>Thu, 15 May 2008 10:30:12 GMT</lastBuildDate><pubDate>Thu, 15 May 2008 10:30:12 GMT</pubDate><ttl>60</ttl><item><title>基于SOAP报文的纯服务端测试</title><link>http://www.blogjava.net/supercrsky/articles/200663.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Thu, 15 May 2008 07:57:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/200663.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/200663.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/200663.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/200663.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/200663.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt">AbstractXFireTest扩展于JUnit标准的TestCase类，提供了向某个Web Service发送SOAP请求报文并对返回的SOAP响应报文进行检验的能力。该测试类提供了若干个方便的断言方法，分别介绍如下：</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">—&nbsp; void assertNoFault(Document node)：确认SOAP响应报文无错误；</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">—&nbsp; java.util.List assertValid(java.lang.String xpath, java.lang.Object node)：确认在DOM节点特定路径下有对应的元素，路径通过XPath表达式进行定义，该方法还将匹配的元素以List对象返回，用户可以对匹配的元素进行进一步检验；</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">—&nbsp; void assertXPathEquals(java.lang.String xpath, java.lang.String value, Document node)：确认特定路径DOM节点为某一特定值；</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">—&nbsp; assertInvalid(java.lang.String xpath, java.lang.Object node)：确认DOM节点特定路径下未包含元素。</p>
<p style="text-indent: 21pt">AbstractXFireSpringTest是AbstractXFireTest的子类，在Spring中用户只需要扩展该类并实现该类的抽象方法ApplicationContext createContext()，就可以对Spring容器中用XFire定义的Web Service进行测试了。</p>
<p style="text-indent: 21pt">为了测试Web Service，我们必须准备一个SOAP请求报文，用户可以简单地手工编写一个，或通过SOAP报文截取工具（如前面我们介绍的TcpTrace、SOAPScope、Apache Axis的TCPMon等）获得一些可用的SOAP请求报文。代码清单16-6是一个访问BbtForumService 服务的请求SOAP报文：</p>
<p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-6 &nbsp;request_soap.xml：SOAP报文层面测试</p>
<p style="text-indent: 0cm">&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;</span><span style="color: #800000">soap:Envelope&nbsp;</span><span style="color: #ff0000">xmlns:soap</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/soap/envelope/"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsd</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="color: #ff0000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">getRefinedTopicCount<br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://server.xfire.baobaotao.com"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">in0&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://server.xfire.baobaotao.com"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">20</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">in0</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">getRefinedTopicCount</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">soap:Envelope</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p style="text-indent: 0cm">&nbsp;</p>
<p style="text-indent: 21pt">我们将其保存在request_soap.xml文件中，放置在类路径com/baobaotao/xfire/server下。当该SOAP请求报文发送给BbtForumService的Web Service后，我们预计它应该返回如代码清单16-7所示的正确的SOAP响应报文：</p>
<p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-7&nbsp; SOAP响应报文</p>
<p style="text-indent: 0cm">&nbsp;</p>
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><span style="color: #0000ff">&lt;?</span><span style="color: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="color: #0000ff">?&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;</span><span style="color: #800000">soap:Envelope&nbsp;</span><span style="color: #ff0000">xmlns:soap</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/soap/envelope/"</span><span style="color: #ff0000">&nbsp;xmlns:xsd</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="color: #ff0000">&nbsp;xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">getRefinedTopicCountResponse&nbsp;</span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.baobaotao.com"</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;</span><span style="color: #800000">out</span><span style="color: #0000ff">&gt;</span><span style="color: #000000">32</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">out</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">getRefinedTopicCountResponse</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" />&nbsp;&nbsp;</span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span><span style="color: #0000ff">&lt;/</span><span style="color: #800000">soap:Envelope</span><span style="color: #0000ff">&gt;</span><span style="color: #000000"><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /><br />
<img src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top"  alt="" /></span></div>
<p style="text-indent: 0cm">&nbsp;</p>
<p style="text-indent: 21pt">下面，我们着手编写测试BbtForumService Web Service的测试类，以验证实际SOAP响应报文是否和代码清单16-7中的一样：</p>
<p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-8&nbsp; TestBbtForumService</p>
<div style="padding-right: 0cm; padding-left: 0cm; padding-bottom: 1pt; border-top-style: none; padding-top: 0cm; border-bottom: #999999 1pt solid; border-right-style: none; border-left-style: none">
<p style="padding-right: 0cm; padding-left: 0cm; margin-bottom: 6pt; padding-bottom: 0cm; border-top-style: none; text-indent: 0cm; padding-top: 0cm; border-right-style: none; border-left-style: none; border-bottom-style: none"><img height="512" src="http://book.csdn.net/BookFiles/466/img/image078.jpg" width="544"  alt="" /></p>
</div>
<p>使用AbstractXFireSpringTest测试Web Service首先要做的第一件事是通过实现createContext()方法构造Spring容器，如①所示。当Spring容器启动时，XFire将自动让容器中的Web Service生效（仅进行测试，不能对外提供服务）。</p>
<p style="text-indent: 21pt">第二步需要向Web Service发送一个SOAP请求报文以得到一个SOAP响应报文，如②所示。接下来，通过AbstractXFireTest提供的检测DOM内容的方法对报文进行正确性验证。由于代码清单16‑7的SOAP报文体中对应的&lt;getRefinedTopicCountResponse&gt;元素及内部元素都位于http://www.baobaotao.com命名空间中，报文体中没有为这个命名空间定义相应的别名，为了在后续断言方法中能够使用简单的方式定义XPath表达式，我们在④处为http://www.baobaotao.com命名空间定义了一个别名。</p>
<p style="text-indent: 21pt">理解以上测试代码中几个断言方法的关键在于理解XPath表达式语言，XPath语法内容很丰富，不可能在这里逐一讲解，我们只介绍一些典型的XPath语法以满足常见的测试需求：</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">— 以&#8220;/&#8221;为前缀的路径表示从DOM根路径开始，如&#8220;/soap:Envelope/soap:Body&#8221;；</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">— 以&#8220;//&#8221;为前缀的路径表示从DOM任意元素开始查询，如&#8220;//out&#8221;表示任意元素为out的元素；</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">— 元素的属性通过@attrName表示，如&#8220;//xsd:complexType[@name=""Book""]&#8221;表示DOM中任意元素名为complexType并且拥有一个值为Book的name属性的元素；</p>
<p style="margin-left: 33.05pt; text-indent: -12.05pt">— 元素的值通过text()表示，如&#8220;//test:Response[text()='32']&#8221;表示DOM中任意值为32、元素名为Response，且位于test命名空间中的元素。</p>
<p style="text-indent: 21pt">现在回过头来看⑤、⑥两处的断言方法，相信大家就可以很容易地理解断言规则了，⑤处的断言检测SOAP响应报文是否包含某一特定元素，而⑥处的断言则对元素内的值进行检测。我们也可以通过printNode()方法将一个节点输出到控制台上，以便于查看。</p>
<h3>16.5.2&nbsp; 在JVM模式通过客户端进行测试</h3>
<p style="text-indent: 21pt">能够不启动Web服务器的情况下通过客户端程序测试Web Service的功能，这一崭新的测试方法对于开发人员来说一定颇具吸引力。因为，这意味着用户可以完全在IDE环境中运行测试，不需要外部环境的支持。不过享受这一测试好处的应用必须保证客户端和服务端的Web Service都位于同一JVM中，这时请求报文和响应报文直接在JVM内部通道中传输。当使用JVM内部通道传输请求和响应的SOAP报文时，我们只需要调整服务的地址就可以了：</p>
<p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-9&nbsp; TextBbtForumService&nbsp; JVM模式测试</p>
<p style="text-indent: 0cm"><img height="392" src="http://book.csdn.net/BookFiles/466/img/image079.jpg" width="544"  alt="" />&nbsp; </p>
<p style="text-indent: 21pt">以上代码中，①处的服务地址采用了JVM模式的地址，和其对应的HTTP地址则是http://localhost:8080/baobaotao/service/BbtForumService，所以只需要将服务名前的部分替换为&#8220;xfire.local://&#8221;就可以了。</p>
<img src ="http://www.blogjava.net/supercrsky/aggbug/200663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-15 15:57 <a href="http://www.blogjava.net/supercrsky/articles/200663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire客户端流程分析</title><link>http://www.blogjava.net/supercrsky/articles/198899.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Wed, 07 May 2008 03:09:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/198899.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/198899.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/198899.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/198899.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/198899.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt">XFire<span style="font-family: 宋体">是当前</span>J2EE<span style="font-family: 宋体">领域非常流行的</span>Web Service<span style="font-family: 宋体">框架，以其卓越的性能和简单易用的特性博得了广大开发者的青睐。目前</span>XFire<span style="font-family: 宋体">已经演变为</span>Apache<span style="font-family: 宋体">的</span>CXF<span style="font-family: 宋体">项目，但仍有大量用户在使用</span>XFire<span style="font-family: 宋体">。</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">下面是</span>XFire<span style="font-family: 宋体">客户端调用的流程分析图，本文后续本分将围绕该图展开。</span></p>
<p style="text-indent: 21pt"><a href="http://www.blogjava.net/images/blogjava_net/hywavesoft/5589/o_xfireClient.jpg"><img height="320" alt="" src="http://www.blogjava.net/images/blogjava_net/hywavesoft/5589/r_xfireClient.jpg" width="640" border="0" /></a></p>
<p style="text-indent: 21pt">XFire<span style="font-family: 宋体">客户端的调用非常灵活，可以有很多种方式，如通过配置调用、通过</span>API<span style="font-family: 宋体">编程调用或者与</span>Spring<span style="font-family: 宋体">等</span>IoC<span style="font-family: 宋体">框架集成使用。虽然调用方式灵活多样，但万变不离其中，其内部流程是一致的。</span></p>
<h3><span style="font-family: 宋体">创建服务模型</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">服务模型是</span>XFire<span style="font-family: 宋体">中非常重要的概念之一，包含了服务的接口信息、操作信息、</span>Binding<span style="font-family: 宋体">信息等诸多服务调用过程中需要的信息。因此在进行服务调用之前首先要创建服务模型。创建服务模型的工作是由服务工厂</span>ServiceFactory<span style="font-family: 宋体">完成的，用户需要为服务工程提供服务接口、名称、命名空间等一些信息，其中服务接口是必须的，其他为可选信息。</span></p>
<h3><span style="font-family: 宋体">创建</span>Client<span style="font-family: 宋体">实例</span></h3>
<p style="text-indent: 21pt">Client<span style="font-family: 宋体">是</span>XFire<span style="font-family: 宋体">客户端的核心组成部分，间接的代表了一个服务。当为具体某个服务配置拦截器（</span>Handler<span style="font-family: 宋体">，有很多种译法如拦截器、处理器、过滤器等，本文统一用拦截器）时，其实是将拦截器信息应用到</span>Client<span style="font-family: 宋体">实例上。</span>Client<span style="font-family: 宋体">可以手工创建也可以由</span>XFireProxyFactory<span style="font-family: 宋体">创建，无论通过哪种方式，</span>Client<span style="font-family: 宋体">在初始化过程中最重要的一步都是在</span>out<span style="font-family: 宋体">拦截器堆栈中增加一个</span>OutMessageSender<span style="font-family: 宋体">拦截器。该拦截器负责最终将服务调用通过</span>HTTP<span style="font-family: 宋体">发送到服务提供者并返回处理结果。本文后续部分还会对</span>OutMessageSender<span style="font-family: 宋体">做更加详细的讲解。</span></p>
<h3><span style="font-family: 宋体">创建服务代理对象</span></h3>
<p style="text-indent: 21pt">XFireProxy<span style="font-family: 宋体">，</span>XFire SOAP<span style="font-family: 宋体">客户端代理实现，用户调用服务时（如</span>Hello.echo(&#8220;tony&#8221;)<span style="font-family: 宋体">）就是通过该对象的</span>invoke<span style="font-family: 宋体">方法来执行。实际上，</span>XFireProxy<span style="font-family: 宋体">只是将调用代理到</span>Client<span style="font-family: 宋体">实例，最终执行服务的还是</span>Client<span style="font-family: 宋体">实例。</span></p>
<h3><span style="font-family: 宋体">构造调用链信息</span></h3>
<p style="text-indent: 21pt">Client<span style="font-family: 宋体">实例的</span>invoke<span style="font-family: 宋体">方法在执行时，生成了一个</span>Invocation<span style="font-family: 宋体">对象，该对象构造了一次完整的调用信息，包括</span>OutMessage<span style="font-family: 宋体">、</span>MessageContext<span style="font-family: 宋体">等。同时</span>Invocation<span style="font-family: 宋体">还负责构造一个拦截器管道（</span>HandlerPipeline<span style="font-family: 宋体">），该管道包含了本次调用需要执行的所有拦截器，当然也包括</span>OutMessageSender<span style="font-family: 宋体">。这些拦截器会分不同的阶段来执行，这也是</span>XFire<span style="font-family: 宋体">一个特性。</span>XFire<span style="font-family: 宋体">默认定义了很多阶段（</span>Phase<span style="font-family: 宋体">），每个阶段都会有若干拦截器被调用。</span></p>
<h3><span style="font-family: 宋体">循环调用拦截器</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">拦截器（</span>Handler<span style="font-family: 宋体">）是</span>XFire<span style="font-family: 宋体">中最为重要的概念，一次服务调用就是由若干拦截器组合完成的。</span>XFire<span style="font-family: 宋体">默认提供了很多预定义的拦截器，用户也可以定义自己的拦截器。基本上，通过拦截器可以影响</span>XFire<span style="font-family: 宋体">执行过程中的任何步骤，你可以为所欲为：）</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">拦截器有两个重要的概念，一个是阶段（</span>Phase<span style="font-family: 宋体">），一个是顺序（</span>Order<span style="font-family: 宋体">）。这两个因素共同决定了拦截器的执行顺序。可以在三个不同的地方配置拦截器：</span></p>
<p style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><span style="font-family: Wingdings">n<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>XFire<span style="font-family: 宋体">实例：全局拦截器，对所有通道上的所有服务起作用</span></p>
<p style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><span style="font-family: Wingdings">n<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>Transport<span style="font-family: 宋体">：通道特定的拦截器，只对该通道（如</span>HTTP<span style="font-family: 宋体">、</span>JMS<span style="font-family: 宋体">）起作用</span></p>
<p style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><span style="font-family: Wingdings">n<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体">具体服务：服务特定的拦截器，只对该服务起作用</span></p>
<p style="text-indent: 21pt"><span style="font-family: 宋体">其实，具体服务上的拦截器最终是配置到</span>Client<span style="font-family: 宋体">上。对于同一个阶段上的拦截器，执行顺序为&#8220;具体服务—</span>&gt;Transport<span style="font-family: 宋体">—</span>&gt;XFire<span style="font-family: 宋体">实例&#8221;。千万不要忽视这些顺序，这对你正确的使用拦截器非常有帮助。</span></p>
<h3><span style="font-family: 宋体">发送远程服务请求</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">这是整个调用链中最后的一环，也是最关键的一步。</span>OutMessageHandler<span style="font-family: 宋体">，前文已经有所提及，是一个特殊的拦截器，在</span>Client<span style="font-family: 宋体">初始化时创建并加入调用链中。该拦截器处于拦截器调用链的</span>Phase.SEND<span style="font-family: 宋体">阶段，基本上也是最后的阶段。</span>OutMessageHandler<span style="font-family: 宋体">从当前调用的消息上下文（</span>MessageContext<span style="font-family: 宋体">）中获取请求的服务地址</span>URI<span style="font-family: 宋体">以及</span>SOAP<span style="font-family: 宋体">消息，然后通过</span>HTTP<span style="font-family: 宋体">将</span>SOAP<span style="font-family: 宋体">请求发送到远程服务器（针对</span>HTTP<span style="font-family: 宋体">通道，如果是</span>JMS<span style="font-family: 宋体">通道则发送到指定的目的地）。最终将远程服务器的响应逐级返回给调用者。</span></p>
<h3><span style="font-family: 宋体">案例分析</span></h3>
<p style="text-indent: 21pt"><span style="font-family: 宋体">前文很多地方都提到</span>Handler<span style="font-family: 宋体">非常重要，那么具体有那些应用场景呢？本部分通过两个案例逐步演示</span>Handler<span style="font-family: 宋体">的应用。</span></p>
<p style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><strong>一、<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="font-family: 宋体">简单安全验证</span></strong></p>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">这是一个非常典型的应用场景，假设</span>A<span style="font-family: 宋体">公司对外提供了一个旅程信息查询服务，该服务通过</span>XFire<span style="font-family: 宋体">对外发布。但是</span>A<span style="font-family: 宋体">公司只希望其合作伙伴才能使用该服务，那么</span>A<span style="font-family: 宋体">公司可以为该服务配置一个</span>Handler<span style="font-family: 宋体">，该</span>Handler<span style="font-family: 宋体">从</span>SOAP<span style="font-family: 宋体">的消息头中获取认证字符串，只有通过验证的请求才被执行。下面是简单的示例代码，真实情况要比这复杂得多。</span></p>
<table style="border-right: medium none; border-top: medium none; background: #e5e5e5; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p style="text-indent: 14.75pt; line-height: normal; text-align: left" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">public</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> invoke(MessageContext context) </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">throws</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> Exception { </span></p>
            <p style="text-indent: 30pt; line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">Element header = context.getInMessage().getHeader();&nbsp;&nbsp; </span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String <span style="background: silver">authCode</span> = header.getChild(</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">"authCode"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">,</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">null</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'">).getValue();</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">if</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'">(!</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">"tony"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">.equals(<span style="background: silver">authCode</span>)){</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">throw</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> XFireFault(</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">"Authentication Fail!"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">, XFireFault.</span><em><span style="font-size: 10pt; color: #0000c0; font-family: 'Courier New'">SENDER</span></em><span style="font-size: 10pt; color: black; font-family: 'Courier New'">);</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;}</span></p>
            <p><span style="font-size: 10pt; color: black; line-height: 150%; font-family: 'Courier New'">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">对于</span>A<span style="font-family: 宋体">公司的合作伙伴，要想调用该服务，必须在其</span>SOAP<span style="font-family: 宋体">的消息头中包含上面代码中的验证字符串，否则服务将被拒绝。下面是简单的示例代码：</span></p>
<table style="border-right: medium none; border-top: medium none; background: #e5e5e5; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">public</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> invoke(MessageContext context) </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">throws</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> Exception {</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element header = context.getInMessage().getHeader();</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Element authCode = </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">new</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> Element(</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">"authCode"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">);</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; authCode.addContent(</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New'">"tony"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">);</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; header.addContent(authCode);</span></p>
            <p><span style="font-size: 10pt; color: black; line-height: 150%; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><strong>二、<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></strong><strong><span style="font-family: 宋体">查找真实服务</span></strong></p>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">这是一个比较特殊的应用场景：假设</span>A<span style="font-family: 宋体">公司已经初步实现</span>SOA<span style="font-family: 宋体">，拥有一个服务注册中心，所有的</span>XFire<span style="font-family: 宋体">服务都在该中心注册。客户端在调用服务时需要动态的从该服务注册中心获取当前的服务地址及版本。通过其他方式肯定也可以实现该需求，但是通过</span>Handler<span style="font-family: 宋体">来实现会非常的幽雅，而且对应用不需要做任何变动。我们先来看一下</span>Handler<span style="font-family: 宋体">的代码：</span></p>
<table style="border-right: medium none; border-top: medium none; background: #e5e5e5; border-left: medium none; border-bottom: medium none; border-collapse: collapse" cellspacing="0" cellpadding="0" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 426.1pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" valign="top" width="568">
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">public</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> invoke(MessageContext context) </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">throws</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> Exception {</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: #3f7f5f; font-family: 'Courier New'">// 1.</span><span style="font-size: 10pt; color: #3f7f5f; font-family: 宋体">寻址</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lookupRealServiceUri(context);</span></p>
            <p style="text-indent: 21pt"><span style="font-size: 10pt; color: black; line-height: 150%; font-family: 'Courier New'">}</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">private</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">void</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> lookupRealServiceUri(MessageContext context) {</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String uri = context.getOutMessage().getUri();</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">try</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> {</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uri = </span><span style="font-size: 10pt; color: #0000c0; font-family: 'Courier New'">serviceLocator</span><span style="font-size: 10pt; color: black; font-family: 'Courier New'">.lookup(requestEnvironment, uri);</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New'">catch</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> (</span><u><span style="font-size: 10pt; color: blue; font-family: 'Courier New'">Exception</span></u><span style="font-size: 10pt; color: black; font-family: 'Courier New'"> e) {</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: #3f7f5f; font-family: 'Courier New'">// Ignoral this exception</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span></p>
            <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; context.getOutMessage().setUri(uri);</span></p>
            <p><span style="font-size: 10pt; color: black; line-height: 150%; font-family: 'Courier New'">&nbsp;&nbsp;&nbsp; }</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">正如代码所示，只需要从</span>context<span style="font-family: 宋体">中获取当前请求的服务</span>URI<span style="font-family: 宋体">地址，然后用当前请求环境信息及服务</span>URI<span style="font-family: 宋体">地址到服务注册中心查找真实的服务，并重新设置服务的地址。</span></p>
<h3><span style="font-family: 宋体">结束语</span></h3>
<p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">本文粗略的介绍了</span>XFire<span style="font-family: 宋体">客户端的调用流程，并着重讲解了</span>Handler<span style="font-family: 宋体">的扩展机制及其应用场景，力求读者能够通过本文对</span>XFire<span style="font-family: 宋体">能有更加深入的了解和掌握。文中难免存在不足之处，欢迎任何形式的交流。</span></p>
<img src ="http://www.blogjava.net/supercrsky/aggbug/198899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-07 11:09 <a href="http://www.blogjava.net/supercrsky/articles/198899.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>实施WebService Security[WS-Security1.0]的Encrypt和Sign模式(XFire+WSS4J) </title><link>http://www.blogjava.net/supercrsky/articles/198898.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Wed, 07 May 2008 03:08:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/198898.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/198898.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/198898.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/198898.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/198898.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 鉴于很多系统需要实施WS-Security的标准，我们在SpringSide中提供了XFire+WSS4J的Demo，本文介绍SpringSide中Spring+XFire+WSS4J的基本配置[WebService Server端配置]第一，创建一个基本的BookServicepublic&nbsp;interface&nbsp;BookService&nbsp;{&nbsp...&nbsp;&nbsp;<a href='http://www.blogjava.net/supercrsky/articles/198898.html'>阅读全文</a><img src ="http://www.blogjava.net/supercrsky/aggbug/198898.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-05-07 11:08 <a href="http://www.blogjava.net/supercrsky/articles/198898.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>图文并茂——使用xfire编写webservice,并通过C#调用</title><link>http://www.blogjava.net/supercrsky/articles/197283.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Tue, 29 Apr 2008 07:41:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/197283.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/197283.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/197283.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/197283.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/197283.html</trackback:ping><description><![CDATA[&nbsp;我没学习过axis系列，一开始学的就是xfire，myeclipse5.1支持xfire支持的非常棒。这里讲解一个简单的例子，<br />
1.首先建立一个web service工程：<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img height="428" alt="new_wizard1.gif" src="http://www.blogjava.net/images/blogjava_net/killme2008/new_wizard1.gif" width="354" border="0" /><br />
<img height="411" alt="new_wizard2.gif" src="http://www.blogjava.net/images/blogjava_net/killme2008/new_wizard2.gif" width="460" border="0" /><br />
<hr width="100%" size="2" />
<img height="411" alt="new_wizard3.gif" src="http://www.blogjava.net/images/blogjava_net/killme2008/new_wizard3.gif" width="460" border="0" /><br />
<img height="496" alt="4.BMP" src="http://www.blogjava.net/images/blogjava_net/killme2008/4.BMP" width="615" border="0" /><br />
<br />
<br />
点击finish之后，myeclipse自动帮你生成services.xml以及web应用目录结构，其中的services.xml是你导出服务的配置文件，注意在WEB-INF/web.xml文件中配置了xfire自己的servlet.<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">servlet</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">servlet-name</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">XFireServlet</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">servlet-name</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">servlet-class</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">org.codehaus.xfire.transport.http.XFireConfigurableServlet</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">servlet-class</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">load-on-startup</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">0</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">load-on-startup</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">servlet</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">servlet-mapping</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">servlet-name</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">XFireServlet</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">servlet-name</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">url-pattern</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">/services/*</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">url-pattern</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">servlet-mapping</span><span style="color: rgb(0,0,255)">&gt;</span></div>
<br />
<br />
2.接下来，现在编写要导出的pojo类，首先是接口：<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">package</span><span style="color: rgb(0,0,0)">&nbsp;net.rubyeye.webservicedemo;<br />
<br />
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">Generated&nbsp;by&nbsp;MyEclipse</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">interface</span><span style="color: rgb(0,0,0)">&nbsp;IHelloWorldService&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;String&nbsp;sayHello(String&nbsp;name);<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}</span></div>
<br />
这个接口我们只提供一个方法:sayHello()，我们没有采用JSR181标注式的声明方式，还是采用xml配置文件。然后是实现类：<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">package</span><span style="color: rgb(0,0,0)">&nbsp;net.rubyeye.webservicedemo;<br />
<br />
</span><span style="color: rgb(0,128,0)">//</span><span style="color: rgb(0,128,0)">Generated&nbsp;by&nbsp;MyEclipse</span><span style="color: rgb(0,128,0)"><br />
</span><span style="color: rgb(0,0,0)"><br />
</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;HelloWorldServiceImpl&nbsp;</span><span style="color: rgb(0,0,255)">implements</span><span style="color: rgb(0,0,0)">&nbsp;IHelloWorldService&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;String&nbsp;sayHello(String&nbsp;name){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">return</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">hello,</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">+</span><span style="color: rgb(0,0,0)">name;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
}</span></div>
<br />
最后，配置下services.xml文件:<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">service</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">name</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">HelloWorldService</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">name</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">serviceClass</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.rubyeye.webservicedemo.IHelloWorldService<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">serviceClass</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">implementationClass</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;net.rubyeye.webservicedemo.HelloWorldServiceImpl<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">implementationClass</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">style</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">wrapped</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">style</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">use</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">literal</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">use</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;</span><span style="color: rgb(128,0,0)">scope</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)">application</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">scope</span><span style="color: rgb(0,0,255)">&gt;</span><span style="color: rgb(0,0,0)"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">&lt;/</span><span style="color: rgb(128,0,0)">service</span><span style="color: rgb(0,0,255)">&gt;</span></div>
<br />
我们的web服务名称叫做<span style="color: rgb(0,0,0)">HelloWorldService，接口是</span><span style="color: rgb(0,0,0)">IHelloWorldService，实现类是</span><span style="color: rgb(0,0,0)">HelloWorldServiceImpl。<strong>注意，其实我们这三个步骤可以一步完成，只要直接使用myeclipse的new web service向导即可</strong><br />
<br />
<img height="598" alt="new_webservice_wiz1.gif" src="http://www.blogjava.net/images/blogjava_net/killme2008/new_webservice_wiz1.gif" width="394" border="0" /><br />
</span><img height="458" alt="new_webservice_wiz1_codefirst2.gif" src="http://www.blogjava.net/images/blogjava_net/killme2008/new_webservice_wiz1_codefirst2.gif" width="492" border="0" /><br />
<br />
<br />
3.然后将此工程部署到tomcat上，通过http://localhost:8081/HelloWorld/services/HelloWorldService?wsdl可以看到生成的wsdl文件。注意，在部署之后，services会被拷贝到WEB-INF\classes\META-INF\xfire目录下，xfire会自动搜索此目录并加载配置文件。我们可以编写一个client来测试web服务，你也可以点击myeclipse上的Launch the Web Services来测试web服务<br />
<br />
<img height="120" alt="webexplorer_launch.gif" src="http://www.blogjava.net/images/blogjava_net/killme2008/webexplorer_launch.gif" width="261" border="0" /><br />
<br />
<br />
4.编写client代码：<br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">package</span><span style="color: rgb(0,0,0)">&nbsp;net.rubyeye.webservicedemo;<br />
<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.net.MalformedURLException;<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.util.ArrayList;<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;java.util.List;<br />
<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.codehaus.xfire.XFireFactory;<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.codehaus.xfire.client.XFireProxyFactory;<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.codehaus.xfire.service.Service;<br />
</span><span style="color: rgb(0,0,255)">import</span><span style="color: rgb(0,0,0)">&nbsp;org.codehaus.xfire.service.binding.ObjectServiceFactory;<br />
<br />
</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;HelloWorldClient&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">static</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;main(String&nbsp;args[])&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Service&nbsp;srvcModel&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;ObjectServiceFactory()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.create(IHelloWorldService.</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XFireProxyFactory&nbsp;factory&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;XFireProxyFactory(XFireFactory<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newInstance().getXFire());<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;helloWorldURL&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">http://localhost:8081/HelloWorld/services/HelloWorldService</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">try</span><span style="color: rgb(0,0,0)">&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHelloWorldService&nbsp;srvc&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;(IHelloWorldService)&nbsp;factory.create(<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;srvcModel,&nbsp;helloWorldURL);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.print(srvc.sayHello(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">dennis</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="color: rgb(0,0,255)">catch</span><span style="color: rgb(0,0,0)">&nbsp;(MalformedURLException&nbsp;e)&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}<br />
</span></div>
<br />
<span style="color: rgb(0,0,0)">执行，打印：hello,dennis<br />
<br />
<strong>注意，你也可以使用MyEclipse的new webservice client向导自动生成client，同时生成供客户端调用的stub类等。<br />
<br />
</strong>最后，我们再编写一个C#调用此web service的例子。<br />
1.在vs.net中新建一个windows 应用程序项目，并添加一个button，和一个label<br />
<img height="255" alt="c1.BMP" src="http://www.blogjava.net/images/blogjava_net/killme2008/c1.BMP" width="362" border="0" /><br />
<img height="364" alt="c2.BMP" src="http://www.blogjava.net/images/blogjava_net/killme2008/c2.BMP" width="320" border="0" /><br />
<br />
2.项目菜单——》添加web应用，输入我们要调用的web服务的wsdl文件的url，并点击前往。<br />
<img height="469" alt="c3.BMP" src="http://www.blogjava.net/images/blogjava_net/killme2008/c3.BMP" width="713" border="0" /><br />
<br />
<br />
3.添加引用之后，vs.net会自动帮你生成提供给客户端调用的stub等，这些文件在名为localhost的命名空间下。此空间下将有一个类，名为HelloWorldService。最后，在button1的onclick事件中添加代码：<br />
<br />
<div style="border-right: rgb(204,204,204) 1px solid; padding-right: 5px; border-top: rgb(204,204,204) 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: rgb(204,204,204) 1px solid; width: 98%; padding-top: 4px; border-bottom: rgb(204,204,204) 1px solid; background-color: rgb(238,238,238)"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System;<br />
</span><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System.Collections.Generic;<br />
</span><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System.ComponentModel;<br />
</span><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System.Data;<br />
</span><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System.Drawing;<br />
</span><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System.Text;<br />
</span><span style="color: rgb(0,0,255)">using</span><span style="color: rgb(0,0,0)">&nbsp;System.Windows.Forms;<br />
<br />
</span><span style="color: rgb(0,0,255)">namespace</span><span style="color: rgb(0,0,0)">&nbsp;MyProject<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;partial&nbsp;</span><span style="color: rgb(0,0,255)">class</span><span style="color: rgb(0,0,0)">&nbsp;Form1&nbsp;:&nbsp;Form<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;localhost.HelloWorldService&nbsp;helloService&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">new</span><span style="color: rgb(0,0,0)">&nbsp;localhost.HelloWorldService();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">public</span><span style="color: rgb(0,0,0)">&nbsp;Form1()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitializeComponent();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: rgb(0,0,255)">private</span><span style="color: rgb(0,0,0)">&nbsp;</span><span style="color: rgb(0,0,255)">void</span><span style="color: rgb(0,0,0)">&nbsp;button1_Click(</span><span style="color: rgb(0,0,255)">object</span><span style="color: rgb(0,0,0)">&nbsp;sender,&nbsp;EventArgs&nbsp;e)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;label1.Text&nbsp;</span><span style="color: rgb(0,0,0)">=</span><span style="color: rgb(0,0,0)">&nbsp;helloService.sayHello(</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">dennis</span><span style="color: rgb(0,0,0)">"</span><span style="color: rgb(0,0,0)">);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
<br />
我们new一个</span><span style="color: rgb(0,0,0)"><span style="color: rgb(0,0,0)">HelloWorldService ，并调用sayHello方法，将结果显示在label上</span></span><br />
<span style="color: rgb(0,0,0)">4.执行ctr+F5<br />
<br />
<img height="298" alt="c4.BMP" src="http://www.blogjava.net/images/blogjava_net/killme2008/c4.BMP" width="318" border="0" /><br />
<br />
<br />
<img height="294" alt="c5.BMP" src="http://www.blogjava.net/images/blogjava_net/killme2008/c5.BMP" width="311" border="0" /></span>
<img src ="http://www.blogjava.net/supercrsky/aggbug/197283.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-29 15:41 <a href="http://www.blogjava.net/supercrsky/articles/197283.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>.Net/C# 与 J2EE/Java Web Service 互操作完整实例 </title><link>http://www.blogjava.net/supercrsky/articles/197050.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Tue, 29 Apr 2008 03:00:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/197050.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/197050.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/197050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/197050.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/197050.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: .Net 与 J2EE/Java Web Service 互操作完整实例实现支持文件分块多点异步上传的 J2EE/Java Web Services 及其 .Net 非 Web 客户端应用程序异步上传本文参考:实现支持文件分块多点异步上传的 Web Services 及其客户端(非Web)应用程序调用相关异步执行的 Web Methodhttp://blog.csdn.net/pl...&nbsp;&nbsp;<a href='http://www.blogjava.net/supercrsky/articles/197050.html'>阅读全文</a><img src ="http://www.blogjava.net/supercrsky/aggbug/197050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-29 11:00 <a href="http://www.blogjava.net/supercrsky/articles/197050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XPath详解</title><link>http://www.blogjava.net/supercrsky/articles/196011.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Fri, 25 Apr 2008 09:02:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/196011.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/196011.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/196011.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/196011.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/196011.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 以下是本人找到的最完整最易懂的XPath教程，不敢私藏，拿出来与大家分享。实例 1基本的XPath语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径                                    /AAA                                       ...&nbsp;&nbsp;<a href='http://www.blogjava.net/supercrsky/articles/196011.html'>阅读全文</a><img src ="http://www.blogjava.net/supercrsky/aggbug/196011.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-25 17:02 <a href="http://www.blogjava.net/supercrsky/articles/196011.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java开发WebService实例--计数器</title><link>http://www.blogjava.net/supercrsky/articles/196012.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Fri, 25 Apr 2008 09:02:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/196012.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/196012.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/196012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/196012.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/196012.html</trackback:ping><description><![CDATA[&nbsp; 如果使用GOOGLE、BAIDU等搜索工具，搜索WebService的相关知识，可以查到N多的网页，我就是通过这些网页的学习，逐渐掌握了些WebService的相关知识。这里对那些无私奉献知识的人一并表示感谢。
<p>
网上关于WebService的例子，多是一些简单得不能再简单的hello
world的例子，简单得以至于你对WebService没有什么感觉。有了WebService的基本知识后，我一直再想，可以把什么样的即简单又实用
的东东做成WebService，开展示一下其功能特点。今天终于想到一个：计数器，计数器用得比较多，功能比较独立，做成WebService可以一劳
永逸为不同系统（不管是JSP还ASP，这是WebService的突出优点）、不同应用节省此类编码工作，可以说以后再也不用写计数器了。只要用就行
了。 <br />
<br />
&nbsp; 说了这么多废话，下面我们开始。本教程介绍一下WebService环境搭建、服务部署的相关知识，然后介绍一个计数器的开发。   <br />
<br />
运行图：</p>
<p><span><strong><img src="http://www.java3z.com/cwbwebhome/article/article5/img/9725623.gif" height="347" width="483"  alt="" /><br />
<br />
二、基础工作</strong></span><br />
<br />
1.开发环境<br />
我使用axis做为Web
Service引擎，它是Apache的一个开源web service引擎。它目前最为成熟的开源web
service引擎之一。下面我主要介绍一下如何使用Axis搭建web service 服务的环境。 <br />
①安装tomcat5.0应用服务器（也可以装5.5，不过我一直在用5.0）;   <br />
②解压下载（
http://ws.apache.org/Axis）后的axis包，将包中axis目录复制到tomcat目录下的webapps目录下；　　   <br />
③将axis/WEB-INF/lib目录下类文件复制到tomcat目录下的common/lib目录下；   <br />
④重新启动tomcat,访问http://localhost:8080/axis/happyaxis.jsp,如果能访问，表示安装成功；   <br />
注意，axis有几个可选的包，如email.jar....，你可以找来放到tomcat目录下的common/lib目录下，如果不使用相关的功能也可以不用。   <br />
这样，开发环境就搭建好了。   <br />
<br />
<br />
2.如何部署Web Service<br />
部署有三种方式：Dynamic Invocation
Interface(DII)、Stubs方式、Dynamic Proxy方式；这里就介绍一下简单，也是我使用的方式：DII。   <br />
DII方式中，先写好服务的JAVA文件（假设名字为helloworld.java），然后把它（注意是源文件）拷贝到webapps/axis目录
中，后缀改成jws(此时文件名为：helloworld.jws)，然后访问连接http://localhost:
8080/Axis/helloworld.jws?wsdl，页面显示Axis自动生成的wsdl，这样一个Web
Service就部署好了。怎么样，是不是很简。 <br />
我的计数器服务就是以这种方式部署的，下文中我会只说将计数器服务部署好，你可不要说：怎么部署，我不会呀。那在古代就要被打手板了。所以我想，古代只学四书五经也是件好事呀。现在要学这么多东西，半天学不会，手要被打烂了。   </p>
<p><strong>三、计数器服务的编写</strong> <br />
计数器大家都知道了，比较简单。我的计数器也同样简单，有以下功能及特点：提供四种计数器（总数器、月计数器、周计数器及日计数器）；考虑到Web
Service要服务于多种应用，这个计数器还支持多个用户；使用XML文件来记录数据。<br />
记录文件名为：d:"counter.xml。注意，此文件在服务里是硬编码，如果修改名字，请在服务程序中也进行相应的修改。文件内容格式如下：   <br />
&lt;?xml version="1.0"
encoding="UTF-8"?&gt;<br />
&lt;counter&gt;<br />
&lt;item&gt;<br />
&lt;name&gt;wallimn&lt;/name&gt;<br />
&lt;password&gt;123&lt;/password&gt;<br />
&lt;dc&gt;59&lt;/dc&gt;<br />
&lt;wc&gt;59&lt;/wc&gt;<br />
&lt;mc&gt;59&lt;/mc&gt;<br />
&lt;tc&gt;59&lt;/tc&gt;<br />
&lt;rt&gt;2007-4-16
16:01:29&lt;/rt&gt;<br />
&lt;/item&gt;<br />
&lt;counter&gt;<br />
说是计数器服务，其实跟编写普通的JAVA应用没有什么两样。我的计数器代码比较简单，我就不做过多的介绍了，把它贴在下面，源码中有少量注释，相信大家不看注释也看得懂。服务有只有一个接口：Counter(String
name, String
password),以后在客户端拿来用就可以了。还多说一句，我和程序使用到了dom4j解析xml包，要调试的请自行准备好jar包。部署方法请参照上文。   <br />
import java.io.File;<br />
import java.io.FileWriter;<br />
import
java.io.IOException;<br />
import java.text.DateFormat;<br />
import
java.text.ParseException;<br />
import java.util.Calendar;<br />
import
java.util.Date;<br />
import java.util.Iterator;<br />
import
org.dom4j.Document;<br />
import org.dom4j.DocumentException;<br />
import
org.dom4j.Element;<br />
import org.dom4j.io.SAXReader;<br />
import
org.dom4j.io.XMLWriter;<br />
/**<br />
*功能：提供计数器服务的WebService，可以为多用户提供服务。&lt;br/&gt;<br />
*
@version : V1.0<br />
* @author : 王力猛(Email: wallimn@sohu.com QQ: 54871876)<br />
*
@date : 2007-4-16 下午04:32:45<br />
*/<br />
public class WsCounterByWallimn
{<br />
//计数器文档，注意名字名路径。<br />
private final String FileN =
"d:/counter.xml";<br />
private final static DateFormat DATEFORMATER =
DateFormat.getDateTimeInstance();<br />
//出错的情况下返回的值<br />
private final static String
ERRORINFO="-1;-1;-1;-1";<br />
public WsCounterByWallimn(){
}<br />
<br />
<br />
/**<br />
*功能：打开计数器文档&lt;br/&gt;<br />
*编码：王力猛 时间：2007-4-16
下午04:44:29&lt;br/&gt;<br />
*/<br />
private Document openDocument(){<br />
Document
doc=null;<br />
SAXReader reader = new SAXReader();<br />
try {<br />
File xmlfile = new
File(FileN);<br />
doc = reader.read(xmlfile);<br />
xmlfile=null;<br />
} <br />
catch
(DocumentException e) {<br />
e.printStackTrace();<br />
}<br />
return
doc;<br />
}<br />
<br />
<br />
/**<br />
*功能：取指定名称计数器的详细信息，并设置计数器加1。&lt;br/&gt;<br />
*编码：王力猛
时间：2007-4-16 下午04:49:57&lt;br/&gt;<br />
*/<br />
private synchronized String
countertick( String name, String password){<br />
Document doc =
openDocument();<br />
Date currdt = new java.util.Date();<br />
//mc:month
counter(月计数器); dc: day counter(日计数器); <br />
//tc: total counter(总计数器); wc: week
counter(周计数器);<br />
//rt: registe time登记时间<br />
String
mc="-1",dc="-1",tc="-1",wc="-1",rt="-1";<br />
Element root =
doc.getRootElement();<br />
Element selitem=null,item=null;<br />
for(Iterator it =
root.elementIterator("item"); it.hasNext();){<br />
item =
(Element)it.next();<br />
if(name.equals(item.element("name").getText())){ <br />
selitem=item;<br />
String pwd =
item.elementText("password");<br />
if(!password.equals(pwd)){<br />
return
ERRORINFO;//密码不对，直接返回<br />
}<br />
mc=item.element("mc").getText();<br />
dc=item.element("dc").getText();<br />
tc=item.element("tc").getText();<br />
wc=item.element("wc").getText();<br />
rt=item.element("rt").getText();<br />
break;<br />
}<br />
}<br />
<br />
//如果selitem为空，说明没有个名字的计数器。则添加一个。<br />
if(selitem==null){<br />
//System.out.println("没有找到这个名字的计数器："+name);<br />
rt=DATEFORMATER.format(currdt);<br />
selitem
=
doc.getRootElement().addElement("item");<br />
selitem.addElement("name").setText(name);<br />
selitem.addElement("tc").setText("0");<br />
selitem.addElement("mc").setText("0");<br />
selitem.addElement("wc").setText("0");<br />
selitem.addElement("dc").setText("0");<br />
selitem.addElement("rt").setText(rt);<br />
selitem.addElement("password").setText(password);<br />
mc="0";<br />
wc="0";<br />
dc="0";<br />
tc="0";<br />
}<br />
<br />
//处理计数器加一操作。<br />
Calendar
currcr=Calendar.getInstance();<br />
//总数器总是加1。<br />
tc
=String.valueOf(Integer.parseInt(tc)+1);<br />
selitem.element("tc").setText(tc);<br />
Date
lastdt = null;<br />
try {<br />
lastdt = DATEFORMATER.parse(rt);<br />
} <br />
catch
(ParseException e) {<br />
lastdt = new java.util.Date();<br />
}<br />
Calendar lastcr =
Calendar.getInstance();<br />
lastcr.setTime(lastdt);<br />
currcr.setTime(currdt);<br />
//System.out.println("上次登记时间："+DATEFORMATER.format(lastdt));<br />
//System.out.println("本次登记时间："+DATEFORMATER.format(currdt));<br />
if(lastcr.get(Calendar.YEAR)==currcr.get(Calendar.YEAR)){<br />
//月相同，月计数加1<br />
if(lastcr.get(Calendar.MONTH)==currcr.get(Calendar.MONTH)){<br />
mc
=
String.valueOf(Integer.parseInt(mc)+1);<br />
}<br />
else{<br />
mc="1";<br />
}<br />
//日相同，日计数加1<br />
if(lastcr.get(Calendar.DAY_OF_YEAR)==currcr.get(Calendar.DAY_OF_YEAR))<br />
dc
= String.valueOf(Integer.parseInt(dc)+1);<br />
else<br />
dc =
"1";<br />
<br />
if(lastcr.get(Calendar.WEEK_OF_YEAR)==currcr.get(Calendar.WEEK_OF_YEAR))<br />
wc
= String.valueOf(Integer.parseInt(wc)+1);<br />
else<br />
wc = "1";<br />
} <br />
else{//年不一样，则月计数器、周计数器日计数器肯定也不一样。<br />
mc="1"; dc="1"; wc="1"; <br />
}<br />
selitem.element("mc").setText(mc);<br />
selitem.element("wc").setText(wc);<br />
selitem.element("dc").setText(dc);<br />
//登记记录时间<br />
selitem.element("rt").setText(DATEFORMATER.format(currdt)); </p>
<p>try {<br />
XMLWriter xw = new XMLWriter(new
FileWriter(FileN));<br />
xw.write(doc);<br />
xw.close();<br />
} <br />
catch (IOException
e) {<br />
e.printStackTrace();<br />
} <br />
return
tc+";"+mc+";"+wc+";"+dc;<br />
}<br />
/**<br />
*功能：服务暴露的接口，也就是指定名称、密码，返回指定的计数，并将计数器加1。&lt;br/&gt;<br />
*编码：王力猛
时间：2007-4-17 上午10:05:22&lt;br/&gt;<br />
*/<br />
public String Counter(String name,
String password){<br />
if(password==null || name==null)return ERRORINFO;<br />
return
countertick(name, password);<br />
}<br />
}</p>
<p><strong>四、客户端编写</strong><br />
客户端是个页面，为了条理清晰，我先写个调用Web
Service的类，其内容如下：<br />
package com.wallimn.WebService;//调试请注意包名</p>
<p>import org.apache.axis.client.Call;<br />
import
org.apache.axis.client.Service;</p>
<p>public class CounterServiceClient {<br />
private String counterarr[];</p>
<p>public boolean getCounter(String CounterName, String password) {<br />
boolean
res = false;<br />
try {<br />
String endpoint =
"http://localhost:8080/axis/WsCounterByWallimn.jws";//此处注意，请与你的开发环境匹配<br />
Service
service = new Service();<br />
Call call = (Call)
service.createCall();<br />
call.setTargetEndpointAddress(new
java.net.URL(endpoint));<br />
call.setOperationName("Counter");<br />
//
填写你要调用的方法名称<br />
String counter = (String) call.invoke(new Object[] { CounterName,
password });<br />
counterarr = counter.split(";");<br />
res = (counterarr != null
&amp;&amp; counterarr.length == 4);<br />
} <br />
catch (Exception e)
{<br />
}<br />
return res;<br />
}</p>
<p>public String getDc() {<br />
return counterarr[3];<br />
}</p>
<p>public String getMc() {<br />
return counterarr[1];<br />
}</p>
<p>public String getTc() {<br />
return counterarr[0];<br />
}</p>
<p>public String getWc() {<br />
return counterarr[2];<br />
}<br />
}</p>
<p>　　到页面(test.jsp)上就简单了，我也把它贴在下面：<br />
&lt;%@ page language="java"
import="com.wallimn.WebService.CounterServiceClient"
pageEncoding="GB18030"%&gt;<br />
&lt;%<br />
CounterServiceClient client = new
CounterServiceClient();<br />
client.getCounter("hello","123");<br />
%&gt;</p>
<p>&lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"&gt;<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;title&gt;计数器测试页面&lt;/title&gt;<br />
<br />
&lt;meta
http-equiv="pragma" content="no-cache"&gt;<br />
&lt;meta
http-equiv="cache-control" content="no-cache"&gt;<br />
&lt;meta
http-equiv="expires" content="0"&gt; <br />
&lt;meta http-equiv="keywords"
content="wallimn,计数器,WebService"&gt;<br />
&lt;meta http-equiv="description"
content="计数器使用示例"&gt;<br />
&lt;/head&gt;<br />
<br />
&lt;body&gt;<br />
&lt;h2
align="center"&gt;计数器详情&lt;/h2&gt;<br />
&lt;hr/&gt; <br />
总访问量:&lt;%=client.getTc()%&gt;
&lt;br/&gt;<br />
今天访问量:&lt;%=client.getDc()%&gt;
&lt;br/&gt;<br />
本周访问量:&lt;%=client.getWc()%&gt;
&lt;br/&gt;<br />
本月访问量:&lt;%=client.getMc()%&gt; &lt;br/&gt; <br />
&lt;hr/&gt; <br />
&lt;p&gt;欢迎交流&lt;br/&gt;博客：http://blog.csdn.net/wallimn&lt;br/&gt;电邮：wallimn@sohu.com&lt;/p&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p>五、结束语</p>
至此一个完整计数器的Web
Service开发、使用的程序的全部完成了。将上面的类、及页面部署到任意的一个上下文中，通过浏览器打开test.jsp，就可以看了结果了。<br />
欢迎访问我的博客(http://blob.csdn.net/wallimn)留言或发邮件(wallimn@sohu.com)交流。
<img src ="http://www.blogjava.net/supercrsky/aggbug/196012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-25 17:02 <a href="http://www.blogjava.net/supercrsky/articles/196012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire完整入门教程</title><link>http://www.blogjava.net/supercrsky/articles/195670.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Thu, 24 Apr 2008 10:00:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/195670.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/195670.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/195670.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/195670.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/195670.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 网上关于XFire入门的教程不少，要么是讲得很简单，就像Hello World一样的程序，要么就是通过IDE集成的工具来开发的，这对于不同的人群有诸多不便，关于XFire的一些详细的信息就不再多讲，可以参考官方网站和相关的文档，这里讲一个完整的入门实例。实例中包括三个情况，我想基本上可以概括所有的需求，或者自己稍加扩展即可。先来看看我们的Interface。&nbsp;1package...&nbsp;&nbsp;<a href='http://www.blogjava.net/supercrsky/articles/195670.html'>阅读全文</a><img src ="http://www.blogjava.net/supercrsky/aggbug/195670.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-24 18:00 <a href="http://www.blogjava.net/supercrsky/articles/195670.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire 最新生火指南（上)</title><link>http://www.blogjava.net/supercrsky/articles/195669.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Thu, 24 Apr 2008 09:59:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/195669.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/195669.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/195669.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/195669.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/195669.html</trackback:ping><description><![CDATA[<p><a name="XFire-XFire最新生火指南（上）">本文来自</a><a href="http://wiki.springside.org.cn/">SpringSide WIki</a><a name="XFire-XFire最新生火指南（上）">，请留意</a><a href="http://wiki.springside.org.cn/display/springside/XFireGuide2">Wiki上的最新版本</a><a name="XFire-XFire最新生火指南（上）">。</a></p>
<p>基于发布在JavaEye的敬畏心情，本文又修改了一遍，与前两天发在blogjava和csdn的版本稍有不同。</p>
<h2>1. 概述</h2>
<p>&nbsp;&nbsp; <a title="Visit page outside Confluence" rel="nofollow" href="http://xfire.codehaus.org/">XFire<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a> 是全球众多牛人在与axis系列对比后一致投票的选择。我比较欣赏的特性有：</p>
<ol>
    <li><a title="Visit page outside Confluence" rel="nofollow" href="http://xfire.codehaus.org/Spring">与Spring整合<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a>，无须生成一堆文件，无须打包独立war，直接将应用中的Pojo导出为Web服务。 </li>
    <li><a title="Visit page outside Confluence" rel="nofollow" href="http://xfire.codehaus.org/Aegis+Binding">Aegis<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a>--超简约的默认Java XML 绑定机制，且可以Plugin其他绑定机制。 </li>
    <li><a title="Visit page outside Confluence" rel="nofollow" href="http://xfire.codehaus.org/JSR+181+Annotations">JSR181--annotatiton驱动<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a>的POJO WebService配置。 </li>
    <li><a title="Visit page outside Confluence" rel="nofollow" href="http://xfire.codehaus.org/Performance">基于Stax的高性能框架<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a>。 </li>
    <li>脱离Web服务器的单元测试能力。 </li>
</ol>
<p>&nbsp;&nbsp; 网上的文档与例子总是不新，请大家抛开所有的文档，所有的Axis习惯，单看这份代表XFire1.2.2最简约做法的指南。</p>
<h2>2. 生火指南</h2>
<h3>2.1 修改web.xml，在Web应用中增加XFire的入口</h3>
<p>&nbsp;&nbsp; 注意XFire有了自己的Servlet，不再依赖Spring MVC的DispatchServlet，也就远离了大家不熟悉的Spring MVC URL Mapping，与Spring达致完美的整合。</p>
<p>&nbsp;&nbsp; 这里指定了路径为/service/* ，即WebService的URL会被默认生成为<a title="Visit page outside Confluence" rel="nofollow" linktext="http://www.springside.org.cn/bookstore/service/BookService" linktype="raw" mce_href="http://www.springside.org.cn/bookstore/service/BookService" href="http://www.springside.org.cn/bookstore/service/BookService">http://www.xxx.com/yyy/service/BookService</a>service/ServiceName<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup>，其中ServiceName默认为下文中的接口名。</p>
<div>
<div>
<pre>
<div>xml 代码</div>
<div>
<ol>
    <li>&lt;servlet&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;xfireservlet-name&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-class&gt;org.codehaus.xfire.spring.XFireSpringServletservlet-class&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;servlet&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&lt;servlet-mapping&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;servlet-name&gt;xfireservlet-name&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;url-pattern&gt;/service/*url-pattern&gt;&nbsp;&nbsp;</li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;servlet-mapping&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</li>
</ol>
</div>
</pre>
<pre>&nbsp;&nbsp; 如果应用使用了Hibernate，使用了OpenSessionInView Filter，注意配置OSIV Filter Filter覆盖xfire servlet的路径，即本例中的/service/*.</pre>
</div>
</div>
<h3>2.2 编写窄接口，抽取POJO中要导出的服务</h3>
<p>&nbsp;&nbsp; 从已有的BookManager.java中，抽取出一个窄接口，仅暴露需要导出为Web Service的方法。而BookManger.java是POJO，不需要任何WebService相关代码。</p>
<p>&nbsp; 窄接口一方面满足了安全要求，不用整个BookManager所有方法导出为Web Service；另一方面，XFire暂时也只支持基于接口的Proxy。</p>
<div>
<div>
<pre>public interface BookService {<br />
List findBooksByCategory(String cateoryId);<br />
}</pre>
</div>
</div>
<h3>&nbsp;2.3 配置Java-XML Binding</h3>
<p>&nbsp;&nbsp; XFire默认的Aegis Binding语法非常简单，在SpringSide的例子里几乎一行配置都不用写，是我见过最简单的binding定义，大大优于其他以设计复杂为终极目标的方案。</p>
<p>&nbsp;&nbsp; 对象的属性、函数的参数和返回值如果为int、String、Date等普通类型以及由普通类型组成的复杂对象都无需定义。我见到只有两种情况需要定义：</p>
<ul>
    <li>无法使用泛型定义Collection中元素的类型时--如List findBooks()。如果能写成List findBooks()就也不需要了。 </li>
    <li>需要为属性定义不同的名字，或者定义复杂对象里的某些属性不要输出。 </li>
</ul>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如果实在需要aegis配置， XFire以约定俗成代替配置(CoC)，所有Service和Entity Bean的binding文件要求命名为xxx.aegis.xml，而且要和原来的类sit together在同一目录里。</p>
<div>
<div>
<ol>
    <li>&lt;mapping&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property&nbsp;name="products"&nbsp;ignore="true"/&gt;&nbsp;&nbsp; </li>
    <li>mapping&gt;&nbsp;&nbsp; </li>
</ol>
</div>
</div>
<p>&nbsp;&nbsp; 其他语法详见<a title="Visit page outside Confluence" rel="nofollow" href="http://xfire.codehaus.org/Aegis+Binding">Aegis<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a>&nbsp;参考。</p>
<h3>2.4 配置Spring导出</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;为了节约配置代码，先配置一个基类。注意导出Web服务的Bean不能lazy-init：</p>
<div>
<div>
<pre>&nbsp;&nbsp;
<li>&lt;import&nbsp;resource="classpath:org/codehaus/xfire/spring/xfire.xml"/&gt;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;</li>
<li>&lt;bean&nbsp;id="baseWebService"&nbsp;class="org.codehaus.xfire.spring.remoting.XFireExporter"&nbsp;lazy-init="false"&nbsp;abstract="true"&gt;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;&lt;property&nbsp;name="serviceFactory"&nbsp;ref="xfire.serviceFactory"/&gt;&nbsp;&nbsp;</li>
<li>&nbsp;&nbsp;&lt;property&nbsp;name="xfire"&nbsp;ref="xfire"/&gt;&nbsp;&nbsp;</li>
<li>&nbsp;bean&gt;&nbsp;&nbsp;</li>
</pre>
</div>
&nbsp;
</div>
<p>&nbsp;每个Web服务的定义：parent为前面定义的基类，serviceClass 为Web Service的接口，serviceBean为Web Service的接口实现类。</p>
<div>xml 代码</div>
<div>
<ol>
    <li>&lt;bean&nbsp;id="bookService"&nbsp;parent="baseWebService"&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&lt;property&nbsp;name="serviceBean"&nbsp;ref="bookManager"/&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;&nbsp;&lt;property&nbsp;name="serviceClass"&nbsp;value="org.springside.bookstore.components.xfire.server.simple.BookService"/&gt;&nbsp;&nbsp; </li>
    <li>&nbsp;bean&gt;&nbsp;&nbsp; </li>
</ol>
</div>
<p><br />
&nbsp;</p>
<hr />
<p>Web服务导出完毕，用户可在<a title="Visit page outside Confluence" rel="nofollow" href="http://localhost/service/BookService?WSDL">http://localhost/service/BookService?WSDL<sup><img alt="" src="http://wiki.springside.org.cn/images/icons/linkext7.gif" align="absmiddle" border="0" height="7" width="7" /></sup></a>查看自动生成的WSDL。&nbsp;</p>
<p>上半章完，关于JSR181,Client API与测试部分请看<a title="XFireGuide2" href="http://wiki.springside.org.cn/display/springside/XFireGuide2">XFire 生火指南(下)</a></p>
<img src ="http://www.blogjava.net/supercrsky/aggbug/195669.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-24 17:59 <a href="http://www.blogjava.net/supercrsky/articles/195669.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire生火指南下半部</title><link>http://www.blogjava.net/supercrsky/articles/195667.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Thu, 24 Apr 2008 09:56:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/195667.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/195667.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/195667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/195667.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/195667.html</trackback:ping><description><![CDATA[<div> XFire生火指南下半部，主要包括JSR181,Client API与测试部分。</div>
<p>作者：江南白衣</p>
<p>本文来自SpringSide WIki，请留意Wiki上的最新版本。(wiki于11.27更新)。</p>
<p>请先阅读：XFire生火指南(上)</p>
<h2>1. JSR181</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp; JSR181式通过annotated POJO ，零配置文件的导出Web服务，是BEA倡导的，JavaEE5里的正规方式， XFire作了良好的支持。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 但是，XFire关于JSR181方式的文档还不够清晰，请完整阅读本节以避免其中的数个陷阱。</p>
<h3>1.1 参考文章</h3>
<ul>
    <li>Spring, Hibernate and XFire<sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup> </li>
    <li>Webservices with Spring, XFire and jsr181<sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup> </li>
    <li>Basic Spring Web services with XFire and JSR 181<sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup> </li>
    <li>XFire JSR181参考文档<sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup> </li>
</ul>
<h3>1.2 ApplicationContext.xml</h3>
<p>&nbsp;&nbsp;&nbsp; 因为配置都写在annotation，applicationContext.xml文件的内容比较固定。需要注意JSR181WebAnnotations与HandlerMapping不能lazy init.</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">beans&nbsp;</span><span style="color: #ff0000;">default-autowire</span><span style="color: #0000ff;">="byName"</span><span style="color: #ff0000;">&nbsp;&nbsp;default-lazy-init</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">引入XFire的预配置文件</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">import&nbsp;</span><span style="color: #ff0000;">resource</span><span style="color: #0000ff;">="classpath:org/codehaus/xfire/spring/xfire.xml"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;">&nbsp;<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;获得applicationContext中所有bean的JSR181&nbsp;annotation&nbsp;</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="webAnnotations"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"</span><span style="color: #ff0000;">&nbsp;&nbsp;lazy-init</span><span style="color: #0000ff;">="false"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;</span><span style="color: #008000;">&lt;!--</span><span style="color: #008000;">&nbsp;定义handler&nbsp;mapping,将所有JSR181定义的bean导出为web&nbsp;service&nbsp;</span><span style="color: #008000;">--&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">bean&nbsp;</span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="jsr181HandlerMapping"</span><span style="color: #ff0000;">&nbsp;class</span><span style="color: #0000ff;">="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"</span><span style="color: #ff0000;">&nbsp;&nbsp;lazy-init</span><span style="color: #0000ff;">="false"</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="xfire"</span><span style="color: #ff0000;">&nbsp;ref</span><span style="color: #0000ff;">="xfire"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;&nbsp;</span><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">property&nbsp;</span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="webAnnotations"</span><span style="color: #ff0000;">&nbsp;ref</span><span style="color: #0000ff;">="webAnnotations"</span><span style="color: #0000ff;">/&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;</span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">&gt;</span><span style="color: #000000;"><br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /></span><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">beans</span><span style="color: #0000ff;">&gt;</span></div>
</div>
<h3>1.3 Interface+Impl模式</h3>
<p>&nbsp;&nbsp; 不同于XFire传统模式，窄接口不是必须的，只是考虑到client如果也使用XFire时，有个接口好生成Client而已。</p>
<p>&nbsp;&nbsp;&nbsp;如果采用Interface，Interface将担任主要的配置工作。</p>
<p>&nbsp;&nbsp; 首先定义@WebService，可定义自己的NameSpace，如果不定义将采用NameSpace的默认生成算法。</p>
<p>&nbsp;&nbsp; 接口中的函数将默认全部导出，不需要再用@WebMethod注释，可以如下例般进行更进一步配置：</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">@WebService(targetNamespace&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">http://www.springside.org.cn</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">interface</span><span style="color: #000000;">&nbsp;BookService&nbsp;{<br />
&nbsp;&nbsp;@WebResult(name&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">SearchResult</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;List</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">Book</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">&nbsp;findBooksByCategory(@WebParam(name&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">category</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;header&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">true</span><span style="color: #000000;">)String&nbsp;cateoryId);<br />
}</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Manager不是纯粹的POJO，需要带上@WebService注释，指明InterFace。</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">@WebService(serviceName&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">BookService</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;<br />
endpointInterface&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">org.springside.bookstore.components.xfire.server.jsr181.BookService</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;BookManager&nbsp;</span><span style="color: #0000ff;">implements</span><span style="color: #000000;">&nbsp;BookService&nbsp;{...}</span></div>
</div>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 陷阱一：XFire JSR181参考文档<sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup>&nbsp;中在Interface中以@WebService(name="<font color="#009100">BookService</font>")来定义ServiceName，这个做法看起来也比较合理，但实际上需要在Manager中以@WebService(serviceName ="BookService") 来定义，比较古怪。</p>
<h3>1.4 纯POJO模式</h3>
<p>&nbsp;&nbsp;&nbsp; 参考文档中的例子，需要配置@WebMethod 指定需要导出的服务</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">@WebService(name&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">EchoService</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;targetNamespace&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">http://www.openuri.org/2004/04/HelloWorld</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span>&nbsp;<span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Jsr181EchoService<br />
{<br />
&nbsp;&nbsp;&nbsp;&nbsp;@WebMethod(operationName&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">echoString</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;action&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">urn:EchoString</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;@WebResult(name&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">echoResult</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;String&nbsp;echo(@WebParam(name&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #000000;">"</span><span style="color: #000000;">echoParam</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;header&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">true</span><span style="color: #000000;">)&nbsp;String&nbsp;input)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;input;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
}</span></div>
</div>
<h3>1.5 Client注意事项</h3>
<p>&nbsp;&nbsp;&nbsp; 陷阱二：和传统模式的client有一点最大的区别，第3个参数需要是实际的Manager类，而不是接口类：</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><span style="color: #000000;">Service&nbsp;serviceModel&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;AnnotationServiceFactory().create(BookManager.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);</span></div>
</div>
<h2>2. Client</h2>
<p>XFire的Client并不算强项，一共有三种模式：</p>
<h3>2.1 Client开发者拥有Web服务端的class</h3>
<p>&nbsp; Client与Server是同一个开发团队也好，Server端团队以jar形式提供开发包也好，反正如果能拿到服务端的接口Class和Entity类及aegis 配置文件的话。</p>
<p>&nbsp; 传统模式：</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><span style="color: #000000;">Service&nbsp;serviceModel&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ObjectServiceFactory().create(BookService.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />BookService&nbsp;service&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BookService)&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;XFireProxyFactory().create(serviceModel,&nbsp;serviceURL);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />service.findBooksByCategory(cateoryId);</span></div>
</div>
<p>&nbsp;&nbsp;JSR181模式，注意这里Server端开发组需要向Client提供BookService的实现类BookManager，而不止于接口类，有点危险：&nbsp;</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><span style="color: #000000;">Service&nbsp;serviceModel&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;AnnotationServiceFactory().create(BookManager.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />BookService&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BookService)&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;XFireProxyFactory().create(serviceModel,&nbsp;serviceURL);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />service.findBooksByCategory(cateoryId);</span></div>
</div>
<p>&nbsp; SpringSide&nbsp;用泛型封装了一个XFireClientFactory，调用代码如下：</p>
<div>
<div>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><span style="color: #000000;">BookService&nbsp;service&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;XFireClientFactory.getClient(serviceURL,&nbsp;BookService.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />BookService&nbsp;service&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;XFireClientFactory.getJSR181Client(serviceURL,&nbsp;BookService.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">,&nbsp;BookManager.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);</span></div>
</div>
</div>
</div>
<h3>2.2 动态模式</h3>
<p>&nbsp;&nbsp;&nbsp; 动态模式不需要服务端的class，不过性能和复杂对象映射等估计做得不会太好。</p>
<div>
<div>
<pre>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">Client&nbsp;client&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Client(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;URL(</span><span style="color: #000000;">"</span><span style="color: #000000;">http://www.webservicex.net/CurrencyConvertor.asmx?WSDL</span><span style="color: #000000;">"</span><span style="color: #000000;">));<br />
<br />
Object[]&nbsp;results&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;client.invoke(</span><span style="color: #000000;">"</span><span style="color: #000000;">ConversionRate</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;Object[]&nbsp;{</span><span style="color: #000000;">"</span><span style="color: #000000;">BRL</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">UGX</span><span style="color: #000000;">"</span><span style="color: #000000;">});</span></div>
</div>
</pre>
</div>
</div>
<h3>2.3 根据WSDL生成Client Stub</h3>
<p>&nbsp;&nbsp;&nbsp; 这才是Web Service Client的王道，可以访问任意编写下的Web Service，将在下一个版本中演示。</p>
<h2>3. 测试</h2>
<p>XFiire很重要的一个特性是提供了无须启动Web容器也能进行单元测试的能力。</p>
<p>原理就是利用XFire的JVM模式，以xfire.local://BookService channel而不是http://localhost/service/BookService<sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup>来访问服务。</p>
<p>测试的方式分两种：</p>
<p>一种是纯服务器角度，不编写客户端代码，以SOAP XML形式发送请求，返回的也是SOAP XML字串，直接对XML进行测试。</p>
<p>一种是编写2.1 中Client代码来进行测试。</p>
<p>前一种的测试的隔离度较高，而后一种比较简便。</p>
<h3>3.1&nbsp;测试基类&nbsp;</h3>
<p>无论那种方式，都使用Xfire的<strong>AbstractXFireSpringTest</strong>基类，实现createContext()回调函数。</p>
<div>
<div>
<pre>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #0000ff;">protected</span><span style="color: #000000;">&nbsp;ApplicationContext&nbsp;createContext()&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;ClassPathXmlApplicationContext(</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;String[]{</span><span style="color: #000000;">"</span><span style="color: #000000;">classpath*:applicationContext*.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">});<br />
&nbsp;}</span></div>
</div>
</pre>
</div>
</div>
<p>另外测试基类还要完成一个很重要的工作就是要解决Hibernate的LazyLoad问题，做到OpenSession In Test。因此，SpringSide专门封装了一个XFireTestCase的基类。</p>
<h3>3.2 用Client代码直接测试</h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 下文直接用client代码调用findBooksByCategory方法，得到返回值后进行各种Assert判断。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 注意和普通client code的两处区别：servericeURL换成local，factory须加入getXFire()作参数。</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">Service&nbsp;serviceModel&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;ObjectServiceFactory().create(BookService.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;XFireProxyFactory&nbsp;factory&nbsp;</span><span style="color: #000000;">=</span>&nbsp;<span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;XFireProxyFactory(getXFire());<br />
&nbsp;&nbsp;BookService&nbsp;service&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(BookService)&nbsp;factory.create(serviceModel,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">xfire.local://BookService</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;List&nbsp;list&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;service.findBooksByCategory(</span><span style="color: #000000;">"</span><span style="color: #000000;">0</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
&nbsp;&nbsp;assertNotNull(list);<br />
&nbsp;&nbsp;...</span></div>
</div>
<h3>3.3 纯服务端测试</h3>
<p>&nbsp;&nbsp; 编写一段SOAP XML，以任意命名保存，下文以"Java"作参数，调用findBooksByName方法。</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><span style="color: #000000;">&lt;</span><span style="color: #000000;">env:Envelope&nbsp;xmlns:env</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">http://schemas.xmlsoap.org/soap/envelope/</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">env:Header</span><span style="color: #000000;">/&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">env:Body</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">findBooksByName&nbsp;xmlns</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">http://www.springside.org.cn</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">in1</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">Java</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">in1</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">findBooksByName</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">env:Body</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br />
</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">env:Envelope</span><span style="color: #000000;">&gt;</span></div>
</div>
<p>&nbsp;&nbsp; 测试代码调用前面的XML，返回XML Document对象，再用基类提供的一些Assert方法检查结果：</p>
<div style="border: 0.5pt solid windowtext; padding: 4px 5.4pt; background: #e6e6e6 none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; width: 95%;">
<div><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" /><span style="color: #000000;">&nbsp;&nbsp;Document&nbsp;doc&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;invokeService(</span><span style="color: #000000;">"</span><span style="color: #000000;">BookService</span><span style="color: #000000;">"</span><span style="color: #000000;">,</span><span style="color: #000000;">"</span><span style="color: #000000;">/org/springside/xfire/BookService.FindBooksByName.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;&nbsp;assertNoFault(doc);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;&nbsp;addNamespace(</span><span style="color: #000000;">"</span><span style="color: #000000;">ss</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;</span><span style="color: #000000;">"</span><span style="color: #000000;">http://domain.commons.bookstore.springside.org</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />
<img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />&nbsp;&nbsp;assertValid(</span><span style="color: #000000;">"</span><span style="color: #000000;">//ss:Book/ss:category/ss:descn=&nbsp;"Java&nbsp;Book"</span><span style="color: #000000;">"</span><span style="color: #000000;">,&nbsp;doc);</span></div>
</div>
<img src ="http://www.blogjava.net/supercrsky/aggbug/195667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-24 17:56 <a href="http://www.blogjava.net/supercrsky/articles/195667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于XFire开发WebServices</title><link>http://www.blogjava.net/supercrsky/articles/195122.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Wed, 23 Apr 2008 07:25:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/195122.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/195122.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/195122.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/195122.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/195122.html</trackback:ping><description><![CDATA[<a>　问一下.Net的开发者，开发Web
Services有多困难?他们会被你的问题逗乐，他们会告诉你所有步骤花费的时间不会超过一分钟。再问一下Java开发者，运气好的话你会碰到上面的回
答，一般情况下，你会得到一个完全不同的答案。从Web
Services引入到Java中至今已经5年了，然而它仍然被认为是一门较新的技术，一个主要的原因就是使用Java实现Web
Services太困难了。现在，随着新一代Web
Services引擎XFire的发布，这种情况将会发生明显的变化。使用XFire，你可以把Java类方法发布为Web
Services而不需要编写额外的代码。在这篇文章中，你将会看到XFire使Web Services开发变得多么容易和简单。</a>
<p><a>　　Web
Services使我们能够在网络上建立分布式系统，应用程序组件可以通过任何平台、任何语言和任何方式访问。无论应用程序如何开发，使用了什么语言，以
及运行在什么操作系统平台上，只要它作为Web
Service，并且为协同解决问题而设计，那么你的应用程序，以任何语言开发或在任何平台上，都可以利用它的服务。这是Web
Service的主要概念。</a></p>
<p><a>　　为了实现Web Services的平台无关性和实现访问独立性，软件行业需要遵循一些作为标准的技术。其中一些包括:</a></p>
<p><a>　　---XML:在Web Services环境中各层之间进行传递的默认数据格式。</a></p>
<p><a>　　---SOAP:封装和交换信息的默认协议。第一次被提出时，它是只取Simple Object
Access
Protocol(简单对象访问协议)的首字母。但是现在SOAP更多被认为是一个特定的名词，以它自己而命名，同样很多人认为这是用词不当:SOAP实
际上不是用来访问对象的。另外，它也不再简单。</a></p>
<p><a>　　---WSDL(Web Services Description Language，Web Services描述语言):描述Web Services的语言。尽管基于XML并且可以被人理解，WSDL主要是由机器处理，由客户端程序读取和理解。</a></p>
<p><a>　　下面的高级层次图表，基于WWW协会发布的&#8220;Web Services Architecture&#8221;(Web Services架构)文档，显示了这些技术在实际的工作环境中是如何发挥作用:</a></p>
<p><a href="http://searchwebservices.techtarget.com.cn/TLimages/picview/?/imagelist/06/39/6fu472rkvoe2.jpg" target="_blank"><img style="border-color: #000000;" alt="点击放大此图片" src="http://www.360doc.com/DownloadImg/73/228251_1.jpg" border="0" /></a></p>
<p>　　这个流程图显示了Web Services中的核心技术是如何工作的。</p>
<p>　　这里，Provider是提供服务的应用程序组件，Requester是使用服务的客户端程序。很多其他技术也会参与到交互中，但是这个图只显示了在Web Services环境中必需的核心技术组件。</p>
<p>　　XFire是一个免费的开源SOAP框架，它不仅可以极大方便地实现这样一个环境，并且可以提供许多Web
Services规范中高级特征，这些特征在多数的商业或者开源工具都没有提供。你要恰当的理解这些单词:great ease and
simplicity(非常轻松和简单)。你将会看到使用XFire创建Web Services是多么的简单。</p>
<div>　　假如你的Web应用有一个Java类，并且你想把它的一个方法发布为Web Services，当使用XFire时，你不需要编写一行额外的Java代码。只需要编辑发布描述符，然后你就会得到一个Web Services。是的，它相当地简单。我们来看一个例子。</div>
<div>&nbsp;</div>
<div><a>&nbsp;</a></div>
<p><a>&nbsp;</a></p>
<p><a>　　<strong>一个简单的Java类</strong></a></p>
<p><a>　　我们的例子是一个银行业应用程序，服务器是运行在J2SE1.4.2_07下的Apache
Tomcat5.5.7。假定你已经了解如何使用Java编写Web应用程序，并知道应该如何把它部署到Apache
Tomcat服务器上。我们的Web应用程序非常简单;它只做一件事——将资金从一个账户转到另外一个账户上。一个普通的Java类
BankingService包含了一个叫做transferFunds()的方法来为我们完成这项工作。它需要四个输入参数:</a></p>
<ul>
    <li><a>　　1、 String fromAccount
    </a></li>
    <li><a>　　2、 String toAccount
    </a></li>
    <li><a>　　3、 double amount
    </a></li>
    <li><a>　　4、 String currency </a></li>
</ul>
<p><a>　　代码如下:</a></p>
<p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">
            <p><font face="Verdana">package com.mybank.xfire.example;</font></p>
            <p><font face="Verdana">import java.text.NumberFormat;<br />
            import java.text.DecimalFormat;</font></p>
            <p><font face="Verdana">/** XFire WebServices sample implementation class. <br />
            */<br />
            public class BankingService implements IBankingService {<br />
            &nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; //Default constructor.<br />
            &nbsp;&nbsp;&nbsp; public BankingService(){&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; /** Transfers fund from one account to another.<br />
            &nbsp;&nbsp;&nbsp; */<br />
            &nbsp;&nbsp;&nbsp; public String transferFunds(<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fromAccount, String toAccount, double amount, String currency){<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String statusMessage = "";<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Call business objects and other components to get the job done.<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Then create a status message and return.<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NumberFormat formatter = new DecimalFormat("###,###,###,###.00");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+ <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e){<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return statusMessage;<br />
            &nbsp;&nbsp;&nbsp; }<br />
            &nbsp;&nbsp;&nbsp; <br />
            }</font></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div><a>　　在这里你看到了什么异常的东西了吗?或许没有，除了默认的构造函数，类型是public。这是必须的。否则，XFire不能够初始化这个类。</a></div>
<div><a>&nbsp;</a></div>
<div><a>&nbsp;
<p>　　因为使用接口的设计是一个好的实践，所以我们的Java类也实现了一个称为IBankingService的接口。代码十分简单:</p>
<p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">
            <p><font face="Verdana">package com.mybank.xfire.example;</font></p>
            <p><font face="Verdana">public interface IBankingService {&nbsp; </font></p>
            <p><font face="Verdana">&nbsp;&nbsp;&nbsp; public String transferFunds(<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fromAccount, String toAccount, double amount, String currency);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            }</font></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>　　在实际实现中，这样一个方法可能包括各种类型的复杂调用、查询和处理操作。但是我们的示例代码已经最小化了，以至于我们可以集中精力在主要目标上:把这个方法发布为Web Services。</p>
<p>　　你可以看到BankingService是一个普通的Java类，没有任何代码告诉我们它将会在Web Services中使用。好的，这里我们不需要增加任何东西。我们所有的工作都在部署描述符里完成。</p>
<p>　　<strong>Web应用的部署描述符</strong></p>
<p>　　在Java中，Web应用程序通常需要至少一个部署描述符(叫做web.xml)对其进行配置。XFire本身是一个基于servlet的应用
程序。因此，我们需要增加必要的引用到描述符文件中。然后我们还必须配置将要创建的Web
Services。我们使用一个称为services.xml的新文件来完成这件事。</p>
<p>　　<strong>web.xml</strong></p>
<p>　　首先，修改web.xml。我们需要增加下面的XFire servlet相关的条目:</p>
<p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">
            <div><font face="Verdana">&lt;servlet&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;display-name&gt;XFire Servlet&lt;/display-name&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-class&gt;org.codehaus.xfire.transport.http.XfireConfigurableServlet<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/servlet-class&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;/servlet&gt;</font></div>
            <div><font face="Verdana">&nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/servlet/XFireServlet/*&lt;/url-pattern&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;<br />
            &nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; &lt;servlet-mapping&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;servlet-name&gt;XFireServlet&lt;/servlet-name&gt;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;url-pattern&gt;/services/*&lt;/url-pattern&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;/servlet-mapping&gt;</font></div>
            </td>
        </tr>
    </tbody>
</table>
</p>
</a><br />
<a>&nbsp;
</a>
<p><a>&nbsp;</a></p>
<p><a>　　<font face="Verdana"><strong>services.xml</strong></font></a></p>
<p><a>　　现在我们不得不说一下我们的Web
Services的由什么组成的了。这由一个叫做services.xml的文件完成，它存放在META-INF/xfire目录下，而这整个目录放在
WEB-INF/classes文件夹中，它在Web应用程序的标准类路径中。这里是services.xml中的基本配置条目:</a></p>
<p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3"><font face="Verdana">&lt;beans xmlns="http://xfire.codehaus.org/config/1.0"&gt;<br />
            &nbsp; <br />
            &nbsp; &lt;service&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;name&gt;Banking&lt;/name&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;namespace&gt;mybank&lt;/namespace&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;serviceClass&gt;com.mybank.xfire.example.IBankingService&lt;/serviceClass&gt;<br />
            &nbsp;&nbsp;&nbsp; &lt;implementationClass&gt;com.mybank.xfire.example.BankingService&lt;/implementationClass&gt;<br />
            &nbsp; &lt;/service&gt;&nbsp; <br />
            &nbsp; <br />
            &lt;/beans&gt;</font></td>
        </tr>
    </tbody>
</table>
</p>
<p><a>&nbsp;　　让我们看看这里都包含了什么内容。Web Services的定义包含在<service>元素中，它还含有一些子元素。第一个子元素是<name>，它可以是你提供任何的合法名字。这将会被客户端程序和其它需要定位你的服务的组件用到。例如，在服务准备好以后，你将在浏览器上使用这个名字来查看WSDL。</name></service></a></p>
<p><a>　　<font face="Verdana">下一个子元素是&lt;namespace&gt;。任何合法的XML名字都是可以的。&lt;namespace&gt;用来唯一标识你的服务的各个参数。<br />
&lt;
serviceClass&gt;元素包含了Java类的名字，它指定了方法签名。在我们的例子中，它是接口IBankingService。如果
Java类没有实现任何接口，你就需要把类的名字放在这里。在你的Java类或者接口中可能有几个方法。只需要一个入口把它们全部发布为Web
Services。</font></a></p>
<p><a><font face="Verdana">　　&lt;implementationClass&gt;保存了实现方法的Java类名。这是一个可选元素。如果上一个元素&lt;serviceClass&gt;包含了一个接口，那么相应的实现类必须在这里指定。</font></a></p>
<p><a><font face="Verdana">　　就是这样。我们的Web Services配置完成了</font>。</a></p>
<p><a>　　<strong>XFire和其它类库</strong></a></p>
<p><a>　　现在是最后一步了，需要得到所有必需的类库。我们怎样得到它们呢?去XFire网站，下载xfire-distribution-1.0.zip，然后解压到一个本地文件夹。复制下面的jar文件和它的库文件夹到WEB-INF/lib中:</a></p>
<ul>
    <li><a>　　&#8226; activation-1.0.2.jar
    </a></li>
    <li><a>　　&#8226; commons-codec-1.3.jar
    </a></li>
    <li><a>　　&#8226; commons-httpclient-3.0.jar
    </a></li>
    <li><a>　　&#8226; commons-logging-1.0.4.jar
    </a></li>
    <li><a>　　&#8226; jaxen-1.1-beta-8.jar
    </a></li>
    <li><a>　　&#8226; jdom-1.0.jar
    </a></li>
    <li><a>　　&#8226; log4j-1.2.x.jar
    </a></li>
    <li><a>　　&#8226; mail-1.3.3_01.jar
    </a></li>
    <li><a>　　&#8226; spring-1.2.x.jar
    </a></li>
    <li><a>　　&#8226; stax-api-1.0.jar
    </a></li>
    <li><a>　　&#8226; wsdl4j-1.5.2.jar
    </a></li>
    <li><a>　　&#8226; wstx-asl-2.9.jar
    </a></li>
    <li><a>　　&#8226; xbean-2.1.0.jar
    </a></li>
    <li><a>　　&#8226; xbean-spring-2.2.jar
    </a></li>
    <li><a>　　&#8226; xfire-all-1.0.jar
    </a></li>
    <li><a>　　&#8226; XmlSchema-1.0.jar </a></li>
</ul>
<p><a>　　一切妥当。我们来部署和启动应用程序。为了部署示例应用，只需要复制websvc.war到Apache
Tomcat的webapps文件夹中，再等待几秒钟。它将会自动启动。这个应用的全部源代码也包含在这个war文件中。我们的程序已经准备作为一个
Web Service了。</a></p>
<a>
<p>　　<strong>我们如何知道Web Service正在工作呢?</strong></p>
<p>　　为了了解Web
Service是否正在工作，我们需要测试。首先，我们测试来看WSDL是否可用。我们在浏览器中输入URL。哪个URL?因为我们的应用程序的war文
件是websvc.war，并且在services.xml中给出的服务名是Banking，WSDL的URL应该是:http:
//localhost:8080/websvc/services/Banking?wsdl。</p>
<p>　　请注意:URL的第一部分，例如，http://localhost:8080，可能会根据你的应用服务器不同而不同。无论怎样，当你输入URL后，将会看到一个XML文档，它的根元素是。这个文档叫做服务的WSDL。如果你看到了，这就是你的应用作为Web Service已经可用的第一个证明。</p>
<p>　　但是这个测试是不够的。可能会发生这种情况，可以看到WSDL，但是从客户端程序可能会访问不到服务。因此为了核实服务是否可以访问了，我们必须使用一个客户端进行服务的实际调用来进行一个真正的测试。</p>
<p>　　<strong>开发一个客户端</strong></p>
<p>　　你可以使用任何的SOAP工具创建客户端，例如，.Net或者Apache
Axis，有很多种方法:使用从WSDL产生的stubs，使用动态代理，等等。在例子中，我们使用一个动态代理，以一个简单的Servlet形式，叫做
WsClient.java。为了保持代码两最小，所有在屏幕显示的元素都放在了doGet()方法中。对Web
Service的实际调用由callWebService()方法完成，它相当地简单。和下面的类似:</p>
<p>
<table style="border: 1px dotted #cccccc; table-layout: fixed;" align="center" border="0" cellpadding="6" cellspacing="0" width="95%">
    <tbody>
        <tr>
            <td bgcolor="#f3f3f3">
            <p><font face="Verdana">/* Call the Web service<br />
            &nbsp;&nbsp;&nbsp; *<br />
            &nbsp;&nbsp;&nbsp; */<br />
            &nbsp;&nbsp;&nbsp; public String callWebService(<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fromAccount, String toAccount, double amount, String currency) <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws MalformedURLException, Exception {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Create a metadata of the service&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Service serviceModel = new ObjectServiceFactory().create(IBankingService.class);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.debug("callSoapServiceLocal(): got service model." );<br />
            &nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Create a proxy for the deployed service<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XFire xfire = XFireFactory.newInstance().getXFire();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XFireProxyFactory factory = new XFireProxyFactory(xfire);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String serviceUrl = "http://localhost:8080/websvc/services/Banking";<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBankingService client = null;<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; client = (IBankingService) factory.create(serviceModel, serviceUrl);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (MalformedURLException e) {<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Invoke the service<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String serviceResponse = "";<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try { <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serviceResponse = client.transferFunds(fromAccount, toAccount, amount, currency);<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } catch (Exception e){<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; serviceResponse = e.toString();<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; log.debug("WsClient.callWebService(): status=" + serviceResponse);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></p>
            <p><font face="Verdana">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Return the response<br />
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return serviceResponse;<br />
            &nbsp;&nbsp;&nbsp; } </font></p>
            </td>
        </tr>
    </tbody>
</table>
</p>
<p>　　这个代码是如何工作的呢?我来解释一下:首先，我们创建一个服务模型，它包含服务的说明——换句话说，就是服务的元数据。我们使用XFire的ObjectServiceFactory从IBankingService.class接口创建这个模型。</p>
<p>　　接着，为XFire获得一个代理工厂对象，它包含了常规的代码，也相当地简单和易懂。这一步中没有任何特定应用的东西。从这个proxyFactory，使用服务模型和服务端点URL(用来获得WSDL)，我们可以得到一个服务的本地代理。</p>
</a>
<p><a>&nbsp;</a></p>
<p><a>　　就是它了。这个代理就是实际的客户端。现在，我们可以调用它的transferFunds()方法来得到我们需要的Web Service。</a></p>
<p><a>　　一旦示例应用发布并启动，就可以尝试servlet URL:</a></p>
<p><a>　　http://localhost:8080/websvc/ws。</a></p>
<p><a>　　这个Servlet使用默认参数来调用Web Service和显示接收到的响应。页面的最后两行应该读取:</a></p>
<p><a>　　Response Received<br />
COMPLETED: CDN$ 500.00 was successfully transferred from A/C# 11111-01234 to A/C# 99999-05678</a></p>
<p><a>　　现在你可以确定Web Service已经发布并且在运行中了。</a></p>
<p><a>　　为了尝试不同的输入值，你可以使用完整的URL，例如:</a></p>
<p><a>　　http://localhost:8080/websvc/ws?from=11-2345&amp;to=77-9876&amp;amt=250.00&amp;cur=EUR。</a></p>
<p><a>　　<strong>基本的Web Services开发步骤清单</strong></a></p>
<p><a>　　这个清单总结了将一个Java方法发布为Web Service所必须的步骤:</a></p>
<ul>
    <li><a>　　1、 检查Java类的方法和默认构造函数确保为public
    </a></li>
    <li><a>　　2、 增加XFire servlet相关条目到web.xml中
    </a></li>
    <li><a>　　3、 创建services.xml，把它放到WEB-INF/classes/META-INF/xfire目录下
    </a></li>
    <li><a>　　4、 增加XFire和第三方包到你的Web应用的WEB-INF/lib文件夹中 </a></li>
</ul>
<p><a>　　这就是所有需要的步骤，是的，相当简单。</a></p>
<p><a>　　<strong>XFire的其他高级特性</strong></a></p>
<p><a>　　XFire的使用可能比较简单，但是在特性和功能性上，它却占据着领导者的位置。下面是它的高级特性:</a></p>
<ul>
    <li><a>　　---本地数据绑定支持POJOs(plain-old
    Java objects)、XMLBeans、JAXB(Java Architecture for XML
    Binding)、Castor等等。数据绑定说明了Web Services的XML请求和映射到Java对象的XML响应。 </a></li>
    <li><a>　　---使用StAX(Streaming API for XML)处理XML文档。同DOM的基于树和SAX的事件驱动的处理方式相比，StAX使用了拉(pull)机制，它使处理更快速，内存效率更高。
    </a></li>
    <li><a>　　---支持多种传输协议，如HTTP、JMS(Java Message Service)和JVM内部传输。
    </a></li>
    <li><a>　　---嵌入式，这是XFire的核心功能之一。你可以把这个SOAP引擎嵌入到你的应用中，完全隐藏所有XFire特定引用，同样所有配置都是程序驱动。
    </a></li>
    <li><a>　　---丰富的API，它使XFire可高度自定义，允许开发者在不同的阶段截获请求，并且对他们进行处理。
    </a></li>
    <li><a>
    ---兼容最新的标准例如SOAP1.1(没有加密远程工程调用，或者RPC)和1.2、WSDL1.1、the Web Services
    Interoperability Organization&#8217;s Basic Profile 1.0、Web Services
    Addressing和WS-Security。 </a></li>
</ul>
<p><a>　　最重要的是，XFire属于新一代Web
Services引擎。不仅仅是营销用语，&#8220;新一代&#8221;有一些重要的意义。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)仅仅在几个星期之后就进行了发布。</a></p>
<p><a>&nbsp;</a></p>
<p><a>　　<strong>性能</strong></a></p>
<p><a>　　Web Services需要消耗很多资源，但是性能方面它们不是那么引人注目。XFire打破了这种趋势。它消耗更少的内存(部分因为 StAX的使用)，但是表现却比多数可比较的SOAP引擎出色。你可以在资源中提供的链接中看到比较的结果。</a></p>
<p><a>　　此外，XFire还提供了各种方法来进一步优化性能。一个方法是使用JVM内置传输(in-JVM
transport)。如果你知道Web
Services和客户端运行在同一个JVM上，你可以选择使用本地传输，它可以大幅提升性能。在示例中的客户端代码，看以下指定服务端点URL的这行:</a></p>
<p><a>　　String serviceUrl = "http://localhost:8080/websvc/services/Banking";</a></p>
<p><a>　　替换为</a></p>
<p><a>　　String serviceUrl = "xfire.local://Banking";</a></p>
<p><a>　　你会看到性能上的明显提高，因为它绕过了整个网络层。</a></p>
<p><a>　　<strong>局限性</strong></a></p>
<p><a>　　XFire有些重要的局限性你应该清楚:</a></p>
<ul>
    <li><a>　　---开发Web
    Services的好的实践是从WSDL开始。大部分的SOAP引擎提供了从WSDL生成服务stub的工具。XFire也提供了这样一个工具。但是它是
    基于注释(annotations-based)的，因此需要J2SE5.0。对于仍坚持使用J2SE1.4.x的人来说，它不是一个令人拍手叫好的工
    具，因为我们有很多其他方式来编写客户端，一个就是文章中演示的方式。 </a></li>
    <li><a>　　---附件支持，它将会包含在未来发行的版本中。
    </a></li>
    <li><a>　　---易于学习的用户向导。XFire团队在这个方面还有很多工作需要做。 </a></li>
</ul>
<p><a>　　<strong>结论</strong></a></p>
<p><a>　　Java当前的趋势是简化技术的使用。因此，我们正看到一波基于POJO的开发成就。同时，面向服务架构
(SOA，Services-oriented architecture)和Web
Services已经变成了当前行业的热点话题。XFire正是在这种情况下产生的。它能够使POJO发布为最少的Web
Services，而只需要付出最小化的努力。从而，它使希望使用这项技术的初级开发者的学习曲线变得平缓。同时，由于它兼容最新标准和提供了丰富的
API，XFire为高级用户提供了更多的大好机会</a></p>
</div>
<img src ="http://www.blogjava.net/supercrsky/aggbug/195122.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-23 15:25 <a href="http://www.blogjava.net/supercrsky/articles/195122.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MyEclipse开发WebServices(基于Annotations)</title><link>http://www.blogjava.net/supercrsky/articles/195099.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Wed, 23 Apr 2008 07:02:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/195099.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/195099.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/195099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/195099.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/195099.html</trackback:ping><description><![CDATA[XFire<span style="font-family: 宋体;">支持</span>JSR 181<span style="font-family: 宋体;">标注方式的</span>Web<span style="font-family: 宋体;">服务开发，另外，所有支持</span>Java EE 5<span style="font-family: 宋体;">的应用服务器（</span>Tomcat<span style="font-family: 宋体;">只是</span>Web<span style="font-family: 宋体;">层的，本身不支持</span>EJB<span style="font-family: 宋体;">和</span>Web<span style="font-family: 宋体;">服务开发），都支持这种开发方式，例如：</span>JBoss<span style="font-family: 宋体;">，</span>GlassFish<span style="font-family: 宋体;">，</span>WebLogic10<span style="font-family: 宋体;">等等，本节就简要讨论使用</span>XFire<span style="font-family: 宋体;">开发标注式</span>Web<span style="font-family: 宋体;">服务和用</span>JBoss<span style="font-family: 宋体;">开发的过程。</span>
<h3>15.4.1 XFire<span style="font-family: 宋体;">的标注服务开发</span></h3>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; XFire<span style="font-family: 宋体;">支持</span>JRS181<span style="font-family: 宋体;">方式的标注服务开发，这样开发的时候只需要编写一个普通的</span>Java<span style="font-family: 宋体;">类，然后加上标注信息后，加入</span>services.xml<span style="font-family: 宋体;">中即可。我们仍然在第</span>2<span style="font-family: 宋体;">节所开发的</span><em>HelloWorldService</em><span style="font-family: 宋体;">项目中进行修改。下面是创建的</span>Web<span style="font-family: 宋体;">服务类</span><strong>echo.Jsr181EchoService</strong><span style="font-family: 宋体;">：</span></p>
<table style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="padding: 0pt 5.4pt; width: 426.1pt;" valign="top" width="568">
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">package</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> echo;</span></p>
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">import</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> javax.jws.WebMethod;</span></p>
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">import</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> javax.jws.WebParam;</span></p>
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">import</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> javax.jws.WebResult;</span></p>
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">import</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> javax.jws.WebService;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: #646464; font-family: 'Courier New';">@WebService</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">(name = </span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"EchoService"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">, serviceName=</span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"EchoServiceTest"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">, targetNamespace = </span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"http://www.openuri.org/2004/04/HelloWorld"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">)</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">public</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">class</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> Jsr181EchoService</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">{</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: #646464; font-family: 'Courier New';">@WebMethod</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">(operationName = </span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"echoString"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">, action = </span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"urn:EchoString"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">)</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: #646464; font-family: 'Courier New';">@WebResult</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">(name = </span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"echoResult"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">)</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">public</span></strong><u><span style="font-size: 10pt; color: blue; font-family: 'Courier New';">String</span></u><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> echo(</span><span style="font-size: 10pt; color: #646464; font-family: 'Courier New';">@WebParam</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">(name = </span><span style="font-size: 10pt; color: #2a00ff; font-family: 'Courier New';">"echoParam"</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">, header = </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">true</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';">) String input)</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; {</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;</span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">return</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> input;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; }</span></p>
            <p><span style="font-size: 10pt; color: black; font-family: 'Courier New';">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体;">这个代码中有很多标注，绝大部分都可以在最后生成的</span>WSDL<span style="font-family: 宋体;">文档中找到对应值。</span></p>
<p style="text-indent: 21pt;"><strong>@WebService</strong><span style="font-family: 宋体;">这个标注放置在</span> Java <span style="font-family: 宋体;">类之前，注明这个类的部分方法可以被发布为</span> Web <span style="font-family: 宋体;">服务（还记得上一章提到的标注嘛？这个标注最终被</span>XFire<span style="font-family: 宋体;">读取后进行分析后会进一步处理成</span>Web<span style="font-family: 宋体;">服务）。它的属性用于设置</span>&nbsp;Web <span style="font-family: 宋体;">服务被发布时的配置信息，常用的属性包括：</span></p>
<p><strong>name</strong><strong><span style="font-family: 宋体;">（可选）</span></strong><span style="font-family: 宋体;">：</span>Web <span style="font-family: 宋体;">服务的名字，</span>WSDL<span style="font-family: 宋体;">中</span> wsdl:portType<span style="font-family: 宋体;">元素的</span> name<span style="font-family: 宋体;">属性和它保持一致，默认是</span> Java<span style="font-family: 宋体;">类或者接口的名字，也可以进行自定义，例如本例中的</span><em>EchoService</em><span style="font-family: 宋体;">。</span>&nbsp;</p>
<p><strong>serviceName</strong><strong><span style="font-family: 宋体;">（可选）</span></strong><span style="font-family: 宋体;">：</span>Web <span style="font-family: 宋体;">服务的服务名，</span>WSDL <span style="font-family: 宋体;">中</span> wsdl:service<span style="font-family: 宋体;">元素的</span> name<span style="font-family: 宋体;">属性和它保持一致，默认是</span>Java<span style="font-family: 宋体;">类的名字（</span><em>Jsr181EchoService</em><span style="font-family: 宋体;">），不过如果设置了</span>name<span style="font-family: 宋体;">属性，则名字改为</span>name<span style="font-family: 宋体;">属性的取值。</span></p>
<p><strong>targetNamespace</strong><strong><span style="font-family: 宋体;">（可选）</span></strong><span style="font-family: 宋体;">：</span> WSDL<span style="font-family: 宋体;">文件所使用的</span> namespace<span style="font-family: 宋体;">，该</span> Web <span style="font-family: 宋体;">服务中所产生的其他</span> XML<span style="font-family: 宋体;">文档同样采用这个作为</span>namespace<span style="font-family: 宋体;">，一般取值为</span>Web<span style="font-family: 宋体;">服务所在网站的名字，不过看起来任意取值并无出错之处。</span></p>
<p style="text-indent: 21pt;"><strong>@WebMethod</strong><strong><span style="font-family: 宋体;">（可选）</span></strong> <span style="font-family: 宋体;">标注放在需要发布成</span> Web <span style="font-family: 宋体;">服务的方法之前，有一些属性可以设置。例如</span><strong>openrationName</strong><span style="font-family: 宋体;">指明了</span>SOAP<span style="font-family: 宋体;">调用时所看到的方法名为</span>echoString<span style="font-family: 宋体;">，而不是类中的方法名</span>echo<span style="font-family: 宋体;">，</span><strong>action</strong><span style="font-family: 宋体;">则定义了操作的类型。一个类里面可以定义多个</span>@WebMethod<span style="font-family: 宋体;">。</span></p>
<p style="text-indent: 21pt;"><strong>@WebResult</strong><strong><span style="font-family: 宋体;">（可选）</span></strong><span style="font-family: 宋体;">标注定义了返回值（</span>SOAP Response Envolope<span style="font-family: 宋体;">）中的</span><strong>name</strong>(<span style="font-family: 宋体;">名字</span>)<span style="font-family: 宋体;">为</span>echoResult<span style="font-family: 宋体;">。</span></p>
<p style="text-indent: 21pt;"><strong>@WebParam</strong><strong><span style="font-family: 宋体;">（可选）</span></strong><span style="font-family: 宋体;">则定义了哪些参数可以作为</span>Web<span style="font-family: 宋体;">服务中的远程可见的参数被调用，</span><strong>name</strong><span style="font-family: 宋体;">设置了其属性。</span></p>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">乍看之下，这个</span>Web<span style="font-family: 宋体;">服务中所用的标注有点多，实际上，这些标注可以不加任何属性，例如只写下</span>@WebService<span style="font-family: 宋体;">，</span>@WebMethod<span style="font-family: 宋体;">即可，甚至于整个类只需要一个</span>@WebService<span style="font-family: 宋体;">标注即可，此时代码如下所示：</span></p>
<table style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="padding: 0pt 5.4pt; width: 426.1pt;" valign="top" width="568">
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">package</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> echo;</span></p>
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">import</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> javax.jws.WebService;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: #646464; font-family: 'Courier New';">@WebService</span></p>
            <p style="text-align: left;" align="left"><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">public</span></strong><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">class</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> Jsr181EchoService {</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">public</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> String echo(</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; String input) {</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong><span style="font-size: 10pt; color: #7f0055; font-family: 'Courier New';">return</span></strong><span style="font-size: 10pt; color: black; font-family: 'Courier New';"> input;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; }</span></p>
            <p><span style="font-size: 10pt; color: black; font-family: 'Courier New';">}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体;">。此时最后所生成的</span>Web<span style="font-family: 宋体;">服务中，所有的操作名，方法名和参数名都和此通</span>Java<span style="font-family: 宋体;">类中的名称一致。在这种情况下，该</span>Web<span style="font-family: 宋体;">服务的访问地址应为：</span></p>
<p><a href="http://localhost:8080/HelloWorldService/services/Jsr181EchoService?wsdl">http://localhost:8080/HelloWorldService/services/Jsr181EchoService?wsdl</a> <span style="font-family: 宋体;">。</span></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体;">最后一步，乃是在</span>XFire<span style="font-family: 宋体;">中配置并发布此服务了，在</span><strong>services.xml</strong><span style="font-family: 宋体;">中加入的</span>Web<span style="font-family: 宋体;">服务配置格式如下：</span></p>
<table style="border: medium none ; border-collapse: collapse;" border="1" cellpadding="0" cellspacing="0">
    <tbody>
        <tr>
            <td style="padding: 0pt 5.4pt; width: 426.1pt;" valign="top" width="568">
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: 'Courier New';">service</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&gt;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">&lt;!-- </span><span style="font-size: 10pt; color: #3f5fbf; font-family: 宋体;">如果配置文件中配置了额外的</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">name</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 宋体;">属性，那么最终的</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">Web Service </span><span style="font-size: 10pt; color: #3f5fbf; font-family: 宋体;">名字将会以此处为准，即：</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServiceName?wsdl</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 宋体;">；同样的</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">namespace</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 宋体;">的取值也会覆盖</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">Java</span><span style="font-size: 10pt; color: #3f5fbf; font-family: 宋体;">类中的标注的值。</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;name&gt;ServiceName&lt;/name&gt;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;namespace&gt;http://www.un.gov/HelloEcho&lt;/namespace&gt;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: #3f5fbf; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --&gt;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: 'Courier New';">serviceClass</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&gt;</span><span style="font-size: 10pt; color: black; font-family: 'Courier New';">echo.Jsr181EchoService</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: 'Courier New';">serviceClass</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&gt;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&lt;</span><span style="font-size: 10pt; color: #3f7f7f; font-family: 'Courier New';">serviceFactory</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&gt;</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; org.codehaus.xfire.annotations.AnnotationServiceFactory</span></p>
            <p style="text-align: left;" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: 'Courier New';">serviceFactory</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&gt;</span></p>
            <p><span style="font-size: 10pt; color: black; font-family: 'Courier New';">&nbsp;&nbsp;&nbsp; </span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&lt;/</span><span style="font-size: 10pt; color: #3f7f7f; font-family: 'Courier New';">service</span><span style="font-size: 10pt; color: teal; font-family: 'Courier New';">&gt;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span style="font-family: 宋体;">，此配置相当的简单，需要注意的是</span>serviceClass<span style="font-family: 宋体;">就是我们写有</span>Web<span style="font-family: 宋体;">服务标注的</span>Java<span style="font-family: 宋体;">类，而</span>serviceFactory<span style="font-family: 宋体;">则必须是</span>AnnotationServiceFactory<span style="font-family: 宋体;">（标注服务工厂），否则此</span>Web<span style="font-family: 宋体;">服务将无法正常发布。</span></p>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">好了，现在按照</span>15.2.4<span style="font-family: 宋体;">一节的内容发布项目并运行后，即可在浏览器中键入下面地址进行测试了：</span></p>
<p><a href="http://localhost:8080/HelloWorldService/services/EchoServiceTest?wsdl">http://localhost:8080/HelloWorldService/services/EchoServiceTest?wsdl</a> <span style="font-family: 宋体;">。</span></p>
<p><strong>EchoServiceTest</strong><span style="font-family: 宋体;">的名字是因为在类中标注了</span>@WebService<span style="font-family: 宋体;">的</span>serviceName<span style="font-family: 宋体;">属性。之后就可以在</span>Web Service Explorer<span style="font-family: 宋体;">中对它进行测试，或者是生成客户端代码。</span></p>
<p style="text-indent: 21pt;"><span style="font-family: 宋体;">从这里看到这种开发方式相对也简单的多，而且您将在下一节看到如果是</span>Java EE 5<span style="font-family: 宋体;">的容器，开发过程将更加的简单，而且不需要</span>XFire<span style="font-family: 宋体;">类库及其配置文件。</span></p>
<img src ="http://www.blogjava.net/supercrsky/aggbug/195099.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-04-23 15:02 <a href="http://www.blogjava.net/supercrsky/articles/195099.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>我的第一个WebServices程序(HelloWorld)</title><link>http://www.blogjava.net/supercrsky/articles/173863.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Wed, 09 Jan 2008 00:20:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/173863.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/173863.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/173863.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/173863.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/173863.html</trackback:ping><description><![CDATA[用MyEclipse创建一个WebService　工程.<br />
<br />
然后创建一个WebService程序:<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.web;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img id="Codehighlighter1_70_194_Open_Image" onclick="this.style.display='none'; Codehighlighter1_70_194_Open_Text.style.display='none'; Codehighlighter1_70_194_Closed_Image.style.display='inline'; Codehighlighter1_70_194_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_70_194_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_70_194_Closed_Text.style.display='none'; Codehighlighter1_70_194_Open_Image.style.display='inline'; Codehighlighter1_70_194_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;HelloWorldImpl&nbsp;</span><span style="color: #0000ff">implements</span><span style="color: #000000">&nbsp;IHelloWorld&nbsp;</span><span id="Codehighlighter1_70_194_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_70_194_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;example(String&nbsp;message)<br />
<img id="Codehighlighter1_114_190_Open_Image" onclick="this.style.display='none'; Codehighlighter1_114_190_Open_Text.style.display='none'; Codehighlighter1_114_190_Closed_Image.style.display='inline'; Codehighlighter1_114_190_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_114_190_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_114_190_Closed_Text.style.display='none'; Codehighlighter1_114_190_Open_Image.style.display='inline'; Codehighlighter1_114_190_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_114_190_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_114_190_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">return</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">Welcome&nbsp;you&nbsp;!!&nbsp;this&nbsp;is&nbsp;first&nbsp;web&nbsp;service&nbsp;program!!</span><span style="color: #000000">"</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">+</span><span style="color: #000000">&nbsp;message;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<br />
IHelloWorld:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.web;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #008000">//</span><span style="color: #008000">Generated&nbsp;by&nbsp;MyEclipse</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">interface</span><span style="color: #000000">&nbsp;IHelloWorld&nbsp;<br />
<img id="Codehighlighter1_73_119_Open_Image" onclick="this.style.display='none'; Codehighlighter1_73_119_Open_Text.style.display='none'; Codehighlighter1_73_119_Closed_Image.style.display='inline'; Codehighlighter1_73_119_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_73_119_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_73_119_Closed_Text.style.display='none'; Codehighlighter1_73_119_Open_Image.style.display='inline'; Codehighlighter1_73_119_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_73_119_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_73_119_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;String&nbsp;example(String&nbsp;message);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span></div>
<br />
这里你可以通过<br />
http://localhost:6666/webserver01/services/HelloWorld?wsdl<br />
进行访问，localhost可以换成你对外公开的IP地址.<br />
<br />
当然也可以通过测试程序访问:<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #0000ff">package</span><span style="color: #000000">&nbsp;com.test;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.codehaus.xfire.XFireFactory;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.codehaus.xfire.client.XFireProxyFactory;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.codehaus.xfire.service.Service;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;org.codehaus.xfire.service.binding.ObjectServiceFactory;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">import</span><span style="color: #000000">&nbsp;com.web.IHelloWorld;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">class</span><span style="color: #000000">&nbsp;HelloWorldClient<br />
<img id="Codehighlighter1_278_807_Open_Image" onclick="this.style.display='none'; Codehighlighter1_278_807_Open_Text.style.display='none'; Codehighlighter1_278_807_Closed_Image.style.display='inline'; Codehighlighter1_278_807_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_278_807_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_278_807_Closed_Text.style.display='none'; Codehighlighter1_278_807_Open_Image.style.display='inline'; Codehighlighter1_278_807_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span id="Codehighlighter1_278_807_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_278_807_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">public</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">static</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">void</span><span style="color: #000000">&nbsp;main(String[]&nbsp;args)<br />
<img id="Codehighlighter1_321_804_Open_Image" onclick="this.style.display='none'; Codehighlighter1_321_804_Open_Text.style.display='none'; Codehighlighter1_321_804_Closed_Image.style.display='inline'; Codehighlighter1_321_804_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_321_804_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_321_804_Closed_Text.style.display='none'; Codehighlighter1_321_804_Open_Image.style.display='inline'; Codehighlighter1_321_804_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_321_804_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_321_804_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Service&nbsp;srvcModel&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;ObjectServiceFactory()<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.create(IHelloWorld.</span><span style="color: #0000ff">class</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XFireProxyFactory&nbsp;factory&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;XFireProxyFactory(XFireFactory<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.newInstance().getXFire());<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;helloWorldURL&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://localhost:6666/webserver01/services/HelloWorld</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff">try</span><span style="color: #000000"><br />
<img id="Codehighlighter1_591_749_Open_Image" onclick="this.style.display='none'; Codehighlighter1_591_749_Open_Text.style.display='none'; Codehighlighter1_591_749_Closed_Image.style.display='inline'; Codehighlighter1_591_749_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_591_749_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_591_749_Closed_Text.style.display='none'; Codehighlighter1_591_749_Open_Image.style.display='inline'; Codehighlighter1_591_749_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_591_749_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_591_749_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHelloWorld&nbsp;srvc&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;(IHelloWorld)&nbsp;factory.create(srvcModel,<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;helloWorldURL);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;result&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;srvc.example(</span><span style="color: #000000">"</span><span style="color: #000000">zdw</span><span style="color: #000000">"</span><span style="color: #000000">);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(result);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">catch</span><span style="color: #000000">&nbsp;(Exception&nbsp;e)<br />
<img id="Codehighlighter1_773_801_Open_Image" onclick="this.style.display='none'; Codehighlighter1_773_801_Open_Text.style.display='none'; Codehighlighter1_773_801_Closed_Image.style.display='inline'; Codehighlighter1_773_801_Closed_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_773_801_Closed_Image" style="display: none" onclick="this.style.display='none'; Codehighlighter1_773_801_Closed_Text.style.display='none'; Codehighlighter1_773_801_Open_Image.style.display='inline'; Codehighlighter1_773_801_Open_Text.style.display='inline';" alt="" src="http://www.blogjava.net/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id="Codehighlighter1_773_801_Closed_Text" style="border-right: #808080 1px solid; border-top: #808080 1px solid; display: none; border-left: #808080 1px solid; border-bottom: #808080 1px solid; background-color: #ffffff"><img alt="" src="http://www.blogjava.net/Images/dot.gif" /></span><span id="Codehighlighter1_773_801_Open_Text"><span style="color: #000000">{<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/InBlock.gif" align="top" /><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="color: #000000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span></div>
详细可以参看MyEclipse自带的Help Contents. <br />
此示例源码下载<a title="点此下载" href="package com.test;">点此下载</a>
 <img src ="http://www.blogjava.net/supercrsky/aggbug/173863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-01-09 08:20 <a href="http://www.blogjava.net/supercrsky/articles/173863.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SOAP和WSDL初识</title><link>http://www.blogjava.net/supercrsky/articles/173841.html</link><dc:creator>々上善若水々</dc:creator><author>々上善若水々</author><pubDate>Tue, 08 Jan 2008 15:51:00 GMT</pubDate><guid>http://www.blogjava.net/supercrsky/articles/173841.html</guid><wfw:comment>http://www.blogjava.net/supercrsky/comments/173841.html</wfw:comment><comments>http://www.blogjava.net/supercrsky/articles/173841.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/supercrsky/comments/commentRss/173841.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/supercrsky/services/trackbacks/173841.html</trackback:ping><description><![CDATA[<span style="font-size: 12pt; font-family: Comic Sans MS"><span style="color: #008000"><span style="font-size: 12pt; font-family: Comic Sans MS">SOA是英文Service-Oriented Architecture，即面向服务架构的缩写。<br style="font-family: " />
<br style="font-family: " />
这个词汇最近一两年频频出现在各种技术期刊上。但是一直以来对于SOA到底是什么没有明确的回答；SOA有什么特点？适合用于解决哪些问题？与其他的技术有什么区别与联系？Web Service和SOA又是什么关系？SOA的出现对于软件架构设计有什么影响？本文将就上面提到的这些问题，尝试根据作者自己的理解给出SOA的定义；总结出SOA特有的三个基本特征；然后以HTTP协议为例对这些特征进行解释；最后简要的说明SOA对今后软件架构设计可能带来的影响。 　<br style="font-family: " />
SOA定义 　　<br style="font-family: " />
下面是作者给SOA下的一个定义：<br style="font-family: " />
SOA是指为了解决在Internet环境下业务集成的需要，通过连接能完成特定任务的独立功能实体实现的一种软件系统架构。从这个定义中我希望表达的前提有下面两点： 　　<br style="font-family: " />
1) 软件系统架构：SOA不是一种语言，也不是一种具体的技术而是一种软件系统架构，它尝试给出在特定环境下推荐采用的一种架构，从这个角度上来说，它更像一种模式(Pattern)。因此它与很多已有的软件技术比如面向对象技术，是互补的而非互斥的。它们分别面向不同的应用场景，用来满足不同的特定需求。 　　<br style="font-family: " />
<br style="font-family: " />
2) SOA的使用范围：需求决定同时也限制功能。SOA并不是包治百病的万灵丹，它最主要的应用场合在于解决在Internet环境下的不同商业应用之间的业务集成问题。<br style="font-family: " />
<br style="font-family: " />
在下面我们会详细讨论Internet的各种特点如何决定SOA的特点，这里我们只需要先简单回顾一下Internet环境区别于Intranet环境的几个特点： 　　<br style="font-family: " />
a) 大量异构系统并存，计算机硬件工作方式不同，操作系统不同、编程语言也不同； 　<br style="font-family: " />
b) 大量、频繁的数据传输仍然速度缓慢并且不稳定； 　　<br style="font-family: " />
c) 版本升级无法完成，我们根本就无法知道互联网上有哪些机器直接或者间接的使用某个服务。 　　<br style="font-family: " />
<br style="font-family: " />
基于上面的前提，下面就让我们一起看一下SOA的基本特征。 　　<br style="font-family: " />
<br style="font-family: " />
SOA三大基本特征 　　<br style="font-family: " />
1 独立的功能实体 　<br style="font-family: " />
在Internet这样松散的使用环境中，任何访问请求都有可能出错，因此任何企图通过Internet进行控制的结构都会面临严重的稳定性问题。SOA非常强调架构中提供服务的功能实体的完全独立自主的能力。传统的组件技术，如.NET Remoting，EJB，COM或者CORBA，都需要有一个宿主(Host或者Server)来存放和管理这些功能实体；当这些宿主运行结束时这些组件的寿命也随之结束。这样当宿主本身或者其它功能部分出现问题的时候，在该宿主上运行的其它应用服务就会受到影响。 　　SOA架构中非常强调实体自我管理和恢复能力。常见的用来进行自我恢复的技术，比如事务处理(Transaction)，消息队列(Message Queue)，冗余部署(Redundant Deployment)和集群系统(Cluster)在SOA中都起到至关重要的作用。 　　<br style="font-family: " />
<br style="font-family: " />
2 大数据量低频率访问 　　<br style="font-family: " />
<br style="font-family: " />
对于.NET Remoting，EJB或者XML-RPC这些传统的分布式计算模型而言，他们的服务提供都是通过函数调用的方式进行的，一个功能的完成往往需要通过客户端和服务器来回很多次函数调用才能完成。在Intranet的环境下，这些调用给系统的响应速度和稳定性带来的影响都可以忽略不计，但是在Internet环境下这些因素往往是决定整个系统是否能正常工作的一个关键决定因素。因此SOA系统推荐采用大数据量的方式一次性进行信息交换。 　　<br style="font-family: " />
<br style="font-family: " />
3 基于文本的消息传递 　　<br style="font-family: " />
由于Internet中大量异构系统的存在决定了SOA系统必须采用基于文本而非二进制的消息传递方式。在COM、CORBA这些传统的组件模型中，从服务器端传往客户端的是一个二进制编码的对象，在客户端通过调用这个对象的方法来完成某些功能；但是在Internet环境下，不同语言，不同平台对数据、甚至是一些基本数据类型定义不同，给不同的服务之间传递对象带来的很大困难。由于基于文本的消息本身是不包含任何处理逻辑和数据类型的，因此服务间只传递文本，对数据的处理依赖于接收端的方式可以帮忙绕过兼容性这个的大泥坑。 　　此外，对于一个服务来说，Internet与局域网最大的一个区别就是在Internet上的版本管理极其困难，传统软件采用的升级方式在这种松散的分布式环境中几乎无法进行。采用基于文本的消息传递方式，数据处理端可以只选择性的处理自己理解的那部分数据，而忽略其它的数据，从而得到的非常理想的兼容性。 　　<br style="font-family: " />
<br style="font-family: " />
HTTP协议：一个典型的SOA实现 　　每一项新技术都是在一些旧的技术基础上发展出来的。正如XML根本思想来自于在60年代就已经出现的早期标记性语言一样，SOA虽然这两年才出现，但是它所表达的观念应该说在网络这种分布式系统结构出现不久就已经广泛应用了。例如我们最熟悉的HTTP协议就是一个非常典型的SOA架构设计。HTTP协议的工作过程简单叙述如下： 　　<br style="font-family: " />
<br style="font-family: " />
1) 客户端，通常是通过浏览器，向服务器端以文本的方式发送一个请求，索取一个Web页面； 　　<br style="font-family: " />
<br style="font-family: " />
2) 服务器端接收到这个请求之后，根据请求的内容进行处理并且返回一个符合HTML语法的文本； 　　<br style="font-family: " />
<br style="font-family: " />
3) 客户端接收到服务器端的响应文本后调用本地的程序，通常还是浏览器，把返回的HTML文本的内容展现出来。 　　<br style="font-family: " />
<br style="font-family: " />
下面来看一下HTTP协议如何满足了SOA的特点： 　　<br style="font-family: " />
* 独立的功能实体：作为服务器端的Web服务器是绝对不会因为客户端的状况变化而改变的，它总是非常稳定地按照自己的内在逻辑运行，响应外部的请求，管理自己的资源和数据。这里一个非常好的例子就是Web服务器对缓存(Cache)的处理，很多Web服务器为了提高性能都或多或少的对数据进行缓存，但是缓存数据、刷新数据这些于客户端完全无关的操作完全由服务器端独立完成，完全不受客户端的影响。 　　<br style="font-family: " />
<br style="font-family: " />
* 大数据量低频率访问：对于一个HTTP请求来说，客户端与服务器之间访问的边界非常简单：就是一个请求，一个响应，没有任何其它的信息往返。无论客户端申请的网页上除了文字之外还有什么信息，对于客户端来说，它发出的请求只是简单的告诉Web服务器它所需要的网页的位置；至于为了生成这个网页，服务器端是否需要访问数据库，执行Servlet或者其它的CGI程序对客户端而言，都是完全透明的。<br style="font-family: " />
<br style="font-family: " />
&nbsp;　　* 基于文本的消息传递：迄今为止兼容性最好的系统可能就是HTTP协议支撑的大部分的web应用了，我们可以在Windows平台下用IE查看互联网上一个Linux＋Apache服务器上的由Perl脚本自动生成的网页。这里的关键就是所有内容都是以格式化的文本方式传递的，不管Perl脚本如何执行，只要它的输出是符合HTML规范的网页，就可以被客户端的浏览器解释。而由于不同的操作系统上对于相同的HTML的解释遵循相同的规范，因此不同操作系统下仍然能够看到一致的用户界面。 　　我们上面基本描述了SOA作为一种软件架构有哪些特点，下面让我们一起看看Web Service与SOA的关系。 　　SOA与Web Service 　　Web Service是就现在而言最适合实现SOA的一些技术的集合，事实上最近SOA的火爆在很大程度上归功于Web Service标准的成熟和应用的普及为广泛的实现SOA架构提供了基础。下面让我们看看Web Service中的各种协议是如何互相工作来满足SOA所需的特点的： 　　<br style="font-family: " />
<br style="font-family: " />
* 独立的功能实体：通过UDDI的目录查找，我们可以动态改变一个服务的提供方而无需影响客户端的应用程序配置。所有的访问都通过SOAP访问进行，只要WSDL接口封装良好，外界客户端是根本没有办法直接访问服务器端的数据的。 　　<br style="font-family: " />
<br style="font-family: " />
* 大数据量低频率访问：通过使用WSDL和基于文本(Literal)的SOAP请求，我们可以实现能一次性接收大量数据的接口。这里需要着重指出的是SOAP请求分文本方式和远程调用(RPC)两种方式，正如上文已经提到的，采用远程调用方式的SOAP请求并不符合这点要求。但是令人遗憾的是现有的大多数SOAP请求采用的仍然是远程调用(RPC)方式，在某些平台上，例如IBM WebSphere的早期版本，甚至没有提供文本方式的SOAP支持。 　　<br style="font-family: " />
<br style="font-family: " />
* 基于文本的消息传递：Web Service所有的通讯是通过SOAP进行的，而SOAP是基于XML的，不同版本之间可以使用不同的DTD或者XML Schema加以辨别和区分。因此只需要我们为不同的版本提供不同的处理就可以轻松实现版本控制的目标。 　　SOA对于软件架构设计的影响 　　无论您现在的系统是否牵涉到基于Internet的业务集成，采用SOA推荐的架构都对提高您系统的扩展性有很大帮助，下面是在系统中引入SOA后需要在软件架构方面做出的改变： 　　<br style="font-family: " />
<br style="font-family: " />
* 使用基于文本方式的SOAP调用，摆脱远程调用中出现的函数参数类型等与数据无关的信息，保证所有SOAP传递的都是有意义的商业数据。依赖于Schema，而不是类定义对这些数据进行解释。 　　<br style="font-family: " />
<br style="font-family: " />
* 传统的三层Web应用将可能变成四层结构：传统意义上的商业逻辑层将被进一步划分为存放每个会话(Session)信息的客户逻辑层和与状态无关Sateless的SOA层。 </span></span><br style="font-family: " />
<br style="font-family: " />
<br style="font-family: " />
<br style="font-family: " />
<span style="color: #0000ff">WSDL <br style="font-family: " />
<br style="font-family: " />
Web Services Description Language的缩写，是一个用来描述Web服务和说明如何与Web服务通信的XML语言。<br style="font-family: " />
<br style="font-family: " />
怎样向别人介绍你的Web service有什么功能，以及每个函数调用时的参数呢？你可能会自己写一套文档，你甚至可能会口头上告诉需要使用你的Web service的人。这些非正式的方法至少都有一个严重的问题：当程序员坐到电脑前，想要使用你的Web service的时候，他们的工具(如Visual Studio)无法给他们提供任何帮助，因为这些工具根本就不了解你的Web service。解决方法是：用机器能阅读的方式提供一个正式的描述文档。Web service描述语言(WSDL)就是这样一个基于XML的语言，用于描述Web service及其函数、参数和返回值。因为是基于XML的，所以WSDL既是机器可阅读的，又是人可阅读的，这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档，又能导入WSDL文档，生成调用相应Web service的代码。 <br style="font-family: " />
================================================================================================<br style="font-family: " />
WSDL用来提供对服务的描述 ，它的主要构成要素有五个: <br style="font-family: " />
1）Types： 定义WSDL定义中所用到的数据类型，即XML Schema Types<br style="font-family: " />
2）Message : 对一组消息的输入和输出参数的定义<br style="font-family: " />
3）portType : 定义Web服务的操作<br style="font-family: " />
4)&nbsp;&nbsp;Binding ：描述特定服务接口的协议、数据格式、安全性和其它属性.<br style="font-family: " />
5)&nbsp;&nbsp;Services : 制定特定服务的URL和提供的调用接口，包含一组端口元素<br style="font-family: " />
</span></span>
<img src ="http://www.blogjava.net/supercrsky/aggbug/173841.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/supercrsky/" target="_blank">々上善若水々</a> 2008-01-08 23:51 <a href="http://www.blogjava.net/supercrsky/articles/173841.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>