??xml version="1.0" encoding="utf-8" standalone="yes"?>国产99久久精品一区二区永久免费,av电影在线地址,91精品中文字幕一区二区三区http://www.aygfsteel.com/supercrsky/category/28819.html专注于JavaWeb开?/description>zh-cnThu, 15 May 2008 10:30:12 GMTThu, 15 May 2008 10:30:12 GMT60ZSOAP报文的纯服务端测?/title><link>http://www.aygfsteel.com/supercrsky/articles/200663.html</link><dc:creator>々上善若水?/dc:creator><author>々上善若水?/author><pubDate>Thu, 15 May 2008 07:57:00 GMT</pubDate><guid>http://www.aygfsteel.com/supercrsky/articles/200663.html</guid><wfw:comment>http://www.aygfsteel.com/supercrsky/comments/200663.html</wfw:comment><comments>http://www.aygfsteel.com/supercrsky/articles/200663.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/supercrsky/comments/commentRss/200663.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/supercrsky/services/trackbacks/200663.html</trackback:ping><description><![CDATA[<p style="text-indent: 21pt">AbstractXFireTest扩展于JUnit标准的TestCasec,提供了向某个Web Service发送SOAPh报文q对q回的SOAP响应报文q行验的能力。该试cL供了若干个方便的断言ҎQ分别介l如下:</p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">?nbsp; void assertNoFault(Document node)Q确认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)Q确认在DOM节点特定路径下有对应的元素,路径通过XPath表达式进行定义,该方法还匹配的元素以List对象q回Q用户可以对匚w的元素进行进一步检验;</p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">?nbsp; void assertXPathEquals(java.lang.String xpath, java.lang.String value, Document node)Q确认特定\径DOM节点为某一特定|</p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">?nbsp; assertInvalid(java.lang.String xpath, java.lang.Object node)Q确认DOM节点特定路径下未包含元素?/p> <p style="text-indent: 21pt">AbstractXFireSpringTest是AbstractXFireTest的子c,在Spring中用户只需要扩展该cdƈ实现该类的抽象方法ApplicationContext createContext()Q就可以对Spring容器中用XFire定义的Web Serviceq行试了?/p> <p style="text-indent: 21pt">Z试Web ServiceQ我们必d备一个SOAPh报文Q用户可以简单地手工~写一个,或通过SOAP报文截取工具Q如前面我们介绍的TcpTrace、SOAPScope、Apache Axis的TCPMon{)获得一些可用的SOAPh报文。代码清?6-6是一个访问BbtForumService 服务的请求SOAP报文Q?/p> <p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-6  request_soap.xmlQSOAP报文层面试</p> <p style="text-indent: 0cm"> </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.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff"><</span><span style="color: #800000">soap:Envelope </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.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />    xmlns:xsd</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="color: #ff0000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />    xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />    </span><span style="color: #0000ff"><</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />        </span><span style="color: #0000ff"><</span><span style="color: #800000">getRefinedTopicCount<br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />            </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://server.xfire.baobaotao.com"</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />            </span><span style="color: #0000ff"><</span><span style="color: #800000">in0 </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://server.xfire.baobaotao.com"</span><span style="color: #0000ff">></span><span style="color: #000000">20</span><span style="color: #0000ff"></</span><span style="color: #800000">in0</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />        </span><span style="color: #0000ff"></</span><span style="color: #800000">getRefinedTopicCount</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />    </span><span style="color: #0000ff"></</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff"></</span><span style="color: #800000">soap:Envelope</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span></div> <p style="text-indent: 0cm"> </p> <p style="text-indent: 21pt">我们其保存在request_soap.xml文g中,攄在类路径com/baobaotao/xfire/server下。当该SOAPh报文发送给BbtForumService的Web Service后,我们预计它应该返回如代码清单16-7所C的正确的SOAP响应报文Q?/p> <p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-7  SOAP响应报文</p> <p style="text-indent: 0cm"> </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.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><span style="color: #0000ff"><?</span><span style="color: #ff00ff">xml version="1.0" encoding="UTF-8"</span><span style="color: #0000ff">?></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff"><</span><span style="color: #800000">soap:Envelope </span><span style="color: #ff0000">xmlns:soap</span><span style="color: #0000ff">="http://schemas.xmlsoap.org/soap/envelope/"</span><span style="color: #ff0000"> xmlns:xsd</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema"</span><span style="color: #ff0000"> xmlns:xsi</span><span style="color: #0000ff">="http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />  </span><span style="color: #0000ff"><</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />    </span><span style="color: #0000ff"><</span><span style="color: #800000">getRefinedTopicCountResponse </span><span style="color: #ff0000">xmlns</span><span style="color: #0000ff">="http://www.baobaotao.com"</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />      </span><span style="color: #0000ff"><</span><span style="color: #800000">out</span><span style="color: #0000ff">></span><span style="color: #000000">32</span><span style="color: #0000ff"></</span><span style="color: #800000">out</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />    </span><span style="color: #0000ff"></</span><span style="color: #800000">getRefinedTopicCountResponse</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" />  </span><span style="color: #0000ff"></</span><span style="color: #800000">soap:Body</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span><span style="color: #0000ff"></</span><span style="color: #800000">soap:Envelope</span><span style="color: #0000ff">></span><span style="color: #000000"><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /><br /> <img src="http://www.aygfsteel.com/images/OutliningIndicators/None.gif" align="top" alt="" /></span></div> <p style="text-indent: 0cm"> </p> <p style="text-indent: 21pt">下面Q我们着手编写测试BbtForumService Web Service的测试类Q以验证实际SOAP响应报文是否和代码清?6-7中的一P</p> <p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-8  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容器Q如①所C。当Spring容器启动ӞXFire自动让容器中的Web Service生效Q仅q行试Q不能对外提供服务)?/p> <p style="text-indent: 21pt">W二步需要向Web Service发送一个SOAPh报文以得C个SOAP响应报文Q如②所C。接下来Q通过AbstractXFireTest提供的检DOM内容的方法对报文q行正确性验证。由于代码清?6?的SOAP报文体中对应?lt;getRefinedTopicCountResponse>元素及内部元素都位于http://www.baobaotao.com命名I间中,报文体中没有个命名空间定义相应的别名Qؓ了在后箋断言Ҏ中能够用简单的方式定义XPath表达式,我们在④处ؓhttp://www.baobaotao.com命名I间定义了一个别名?/p> <p style="text-indent: 21pt">理解以上试代码中几个断aҎ的关键在于理解XPath表达式语aQXPath语法内容很丰富,不可能在q里逐一讲解Q我们只介绍一些典型的XPath语法以满_见的试需求:</p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">??#8220;/”为前~的\径表CZDOM根\径开始,?#8220;/soap:Envelope/soap:Body”Q?/p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">??#8220;//”为前~的\径表CZDOML元素开始查询,?#8220;//out”表示L元素为out的元素;</p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">?元素的属性通过@attrName表示Q如“//xsd:complexType[@name=""Book""]”表示DOM中Q意元素名为complexTypeq且拥有一个gؓBook的name属性的元素Q?/p> <p style="margin-left: 33.05pt; text-indent: -12.05pt">?元素的值通过text()表示Q如“//test:Response[text()='32']”表示DOM中Q意gؓ32、元素名为ResponseQ且位于test命名I间中的元素?/p> <p style="text-indent: 21pt">现在回过头来看⑤、⑥两处的断aҎQ相信大家就可以很容易地理解断言规则了,⑤处的断aSOAP响应报文是否包含某一特定元素Q而⑥处的断言则对元素内的D行检。我们也可以通过printNode()Ҏ一个节点输出到控制CQ以便于查看?/p> <h3>16.5.2  在JVM模式通过客户端进行测?/h3> <p style="text-indent: 21pt">能够不启动Web服务器的情况下通过客户端程序测试Web Service的功能,q一崭新的测试方法对于开发h员来说一定颇具吸引力。因为,q意味着用户可以完全在IDE环境中运行测试,不需要外部环境的支持。不qn受这一试好处的应用必M证客L和服务端的Web Service都位于同一JVM中,q时h报文和响应报文直接在JVM内部通道中传输。当使用JVM内部通道传输h和响应的SOAP报文Ӟ我们只需要调整服务的地址可以了Q?/p> <p style="margin: 7.2pt 0cm 3.6pt; text-indent: 21.6pt">代码清单16-9  TextBbtForumService  JVM模式试</p> <p style="text-indent: 0cm"><img height="392" src="http://book.csdn.net/BookFiles/466/img/image079.jpg" width="544" alt="" />  </p> <p style="text-indent: 21pt">以上代码中,①处的服务地址采用了JVM模式的地址Q和其对应的HTTP地址则是http://localhost:8080/baobaotao/service/BbtForumServiceQ所以只需要将服务名前的部分替换ؓ“xfire.local://”可以了?/p> <img src ="http://www.aygfsteel.com/supercrsky/aggbug/200663.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/supercrsky/" target="_blank">々上善若水?/a> 2008-05-15 15:57 <a href="http://www.aygfsteel.com/supercrsky/articles/200663.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire客户端流E分?/title><link>http://www.aygfsteel.com/supercrsky/articles/198899.html</link><dc:creator>々上善若水?/dc:creator><author>々上善若水?/author><pubDate>Wed, 07 May 2008 03:09:00 GMT</pubDate><guid>http://www.aygfsteel.com/supercrsky/articles/198899.html</guid><wfw:comment>http://www.aygfsteel.com/supercrsky/comments/198899.html</wfw:comment><comments>http://www.aygfsteel.com/supercrsky/articles/198899.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/supercrsky/comments/commentRss/198899.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/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: 宋体">框架Q以其卓的性能和简单易用的Ҏ博得了q大开发者的青睐。目?/span>XFire<span style="font-family: 宋体">已经演变?/span>Apache<span style="font-family: 宋体">?/span>CXF<span style="font-family: 宋体">目Q但仍有大量用户在?/span>XFire<span style="font-family: 宋体">?/span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">下面?/span>XFire<span style="font-family: 宋体">客户端调用的程分析图,本文后箋本分围l该囑ֱ开?/span></p> <p style="text-indent: 21pt"><a href="http://www.aygfsteel.com/images/blogjava_net/hywavesoft/5589/o_xfireClient.jpg"><img height="320" alt="" src="http://www.aygfsteel.com/images/blogjava_net/hywavesoft/5589/r_xfireClient.jpg" width="640" border="0" /></a></p> <p style="text-indent: 21pt">XFire<span style="font-family: 宋体">客户端的调用非常灉|Q可以有很多U方式,如通过配置调用、通过</span>API<span style="font-family: 宋体">~程调用或者与</span>Spring<span style="font-family: 宋体">{?/span>IoC<span style="font-family: 宋体">框架集成使用。虽然调用方式灵zdP但万变不d中,其内部流E是一致的?/span></p> <h3><span style="font-family: 宋体">创徏服务模型</span></h3> <p style="text-indent: 21pt"><span style="font-family: 宋体">服务模型?/span>XFire<span style="font-family: 宋体">中非帔R要的概念之一Q包含了服务的接口信息、操作信息?/span>Binding<span style="font-family: 宋体">信息{诸多服务调用过E中需要的信息。因此在q行服务调用之前首先要创建服务模型。创建服务模型的工作是由服务工厂</span>ServiceFactory<span style="font-family: 宋体">完成的,用户需要ؓ服务工程提供服务接口、名U、命名空间等一些信息,其中服务接口是必ȝQ其他ؓ可选信息?/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: 宋体">客户端的核心l成部分Q间接的代表了一个服务。当为具体某个服务配|拦截器Q?/span>Handler<span style="font-family: 宋体">Q有很多U译法如拦截器、处理器、过滤器{,本文l一用拦截器Q时Q其实是拦截器信息应用?/span>Client<span style="font-family: 宋体">实例上?/span>Client<span style="font-family: 宋体">可以手工创徏也可以由</span>XFireProxyFactory<span style="font-family: 宋体">创徏Q无论通过哪种方式Q?/span>Client<span style="font-family: 宋体">在初始化q程中最重要的一步都是在</span>out<span style="font-family: 宋体">拦截器堆栈中增加一?/span>OutMessageSender<span style="font-family: 宋体">拦截器。该拦截器负责最l将服务调用通过</span>HTTP<span style="font-family: 宋体">发送到服务提供者ƈq回处理l果。本文后l部分还会对</span>OutMessageSender<span style="font-family: 宋体">做更加详l的讲解?/span></p> <h3><span style="font-family: 宋体">创徏服务代理对象</span></h3> <p style="text-indent: 21pt">XFireProxy<span style="font-family: 宋体">Q?/span>XFire SOAP<span style="font-family: 宋体">客户端代理实玎ͼ用户调用服务Ӟ?/span>Hello.echo(“tony”)<span style="font-family: 宋体">Q就是通过该对象的</span>invoke<span style="font-family: 宋体">Ҏ来执行。实际上Q?/span>XFireProxy<span style="font-family: 宋体">只是调用代理到</span>Client<span style="font-family: 宋体">实例Q最l执行服务的q是</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: 宋体">Ҏ在执行时Q生成了一?/span>Invocation<span style="font-family: 宋体">对象Q该对象构造了一ơ完整的调用信息Q包?/span>OutMessage<span style="font-family: 宋体">?/span>MessageContext<span style="font-family: 宋体">{。同?/span>Invocation<span style="font-family: 宋体">q负责构造一个拦截器道Q?/span>HandlerPipeline<span style="font-family: 宋体">Q,该管道包含了本次调用需要执行的所有拦截器Q当然也包括</span>OutMessageSender<span style="font-family: 宋体">。这些拦截器会分不同的阶D|执行Q这也是</span>XFire<span style="font-family: 宋体">一个特性?/span>XFire<span style="font-family: 宋体">默认定义了很多阶D(</span>Phase<span style="font-family: 宋体">Q,每个阶段都会有若q拦截器被调用?/span></p> <h3><span style="font-family: 宋体">循环调用拦截?/span></h3> <p style="text-indent: 21pt"><span style="font-family: 宋体">拦截器(</span>Handler<span style="font-family: 宋体">Q是</span>XFire<span style="font-family: 宋体">中最为重要的概念Q一ơ服务调用就是由若干拦截器组合完成的?/span>XFire<span style="font-family: 宋体">默认提供了很多预定义的拦截器Q用户也可以定义自己的拦截器。基本上Q通过拦截器可以媄?/span>XFire<span style="font-family: 宋体">执行q程中的M步骤Q你可以为所ƲؓQ)</span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">拦截器有两个重要的概念,一个是阶段Q?/span>Phase<span style="font-family: 宋体">Q,一个是序Q?/span>Order<span style="font-family: 宋体">Q。这两个因素共同军_了拦截器的执行顺序。可以在三个不同的地斚w|拦截器Q?/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'">         </span></span>XFire<span style="font-family: 宋体">实例Q全局拦截器,Ҏ有通道上的所有服务v作用</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'">         </span></span>Transport<span style="font-family: 宋体">Q通道特定的拦截器Q只对该通道Q如</span>HTTP<span style="font-family: 宋体">?/span>JMS<span style="font-family: 宋体">Qv作用</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'">         </span></span><span style="font-family: 宋体">具体服务Q服务特定的拦截器,只对该服务v作用</span></p> <p style="text-indent: 21pt"><span style="font-family: 宋体">其实Q具体服务上的拦截器最l是配置?/span>Client<span style="font-family: 宋体">上。对于同一个阶D上的拦截器Q执行顺序ؓ“具体服务?/span>>Transport<span style="font-family: 宋体">?/span>>XFire<span style="font-family: 宋体">实例”。千万不要忽视这些顺序,q对你正的使用拦截器非常有帮助?/span></p> <h3><span style="font-family: 宋体">发送远E服务请?/span></h3> <p style="text-indent: 21pt"><span style="font-family: 宋体">q是整个调用链中最后的一环,也是最关键的一步?/span>OutMessageHandler<span style="font-family: 宋体">Q前文已l有所提及Q是一个特D的拦截器,?/span>Client<span style="font-family: 宋体">初始化时创徏q加入调用链中。该拦截器处于拦截器调用铄</span>Phase.SEND<span style="font-family: 宋体">阶段Q基本上也是最后的阶段?/span>OutMessageHandler<span style="font-family: 宋体">从当前调用的消息上下文(</span>MessageContext<span style="font-family: 宋体">Q中获取h的服务地址</span>URI<span style="font-family: 宋体">以及</span>SOAP<span style="font-family: 宋体">消息Q然后通过</span>HTTP<span style="font-family: 宋体">?/span>SOAP<span style="font-family: 宋体">h发送到q程服务器(针对</span>HTTP<span style="font-family: 宋体">通道Q如果是</span>JMS<span style="font-family: 宋体">通道则发送到指定的目的地Q。最l将q程服务器的响应逐q回l调用者?/span></p> <h3><span style="font-family: 宋体">案例分析</span></h3> <p style="text-indent: 21pt"><span style="font-family: 宋体">前文很多地方都提?/span>Handler<span style="font-family: 宋体">非常重要Q那么具体有那些应用场景呢?本部分通过两个案例逐步演示</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'">             </span></strong><strong><span style="font-family: 宋体">单安全验?/span></strong></p> <p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">q是一个非常典型的应用场景Q假?/span>A<span style="font-family: 宋体">公司对外提供了一个旅E信息查询服务,该服务通过</span>XFire<span style="font-family: 宋体">对外发布。但?/span>A<span style="font-family: 宋体">公司只希望其合作伙伴才能使用该服务,那么</span>A<span style="font-family: 宋体">公司可以服务配置一?/span>Handler<span style="font-family: 宋体">Q该</span>Handler<span style="font-family: 宋体">?/span>SOAP<span style="font-family: 宋体">的消息头中获取认证字W串Q只有通过验证的请求才被执行。下面是单的CZ代码Q真实情况要比这复杂得多?/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();   </span></p> <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">     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'">     </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'">        </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'">  }</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: 宋体">的消息头中包含上面代码中的验证字W串Q否则服务将被拒l。下面是单的CZ代码Q?/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'">    </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'">        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'">        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'">        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'">        header.addContent(authCode);</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: 42pt; text-indent: -21pt; tab-stops: list 42.0pt"><strong>二?span style="font: 7pt 'Times New Roman'">             </span></strong><strong><span style="font-family: 宋体">查找真实服务</span></strong></p> <p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">q是一个比较特D的应用场景Q假?/span>A<span style="font-family: 宋体">公司已经初步实现</span>SOA<span style="font-family: 宋体">Q拥有一个服务注册中心,所有的</span>XFire<span style="font-family: 宋体">服务都在该中心注册。客L在调用服务时需要动态的从该服务注册中心获取当前的服务地址及版本。通过其他方式肯定也可以实现该需求,但是通过</span>Handler<span style="font-family: 宋体">来实C非常的幽雅,而且对应用不需要做M变动。我们先来看一?/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'">    </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'">            </span><span style="font-size: 10pt; color: #3f7f5f; font-family: 'Courier New'">// 1.</span><span style="font-size: 10pt; color: #3f7f5f; font-family: 宋体">d</span></p> <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">            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'">    </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'">        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'">        </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'">            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'">        } </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'">            </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'">        }</span></p> <p style="line-height: normal; text-align: left" align="left"><span style="font-size: 10pt; color: black; font-family: 'Courier New'">        context.getOutMessage().setUri(uri);</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: 宋体">正如代码所C,只需要从</span>context<span style="font-family: 宋体">中获取当前请求的服务</span>URI<span style="font-family: 宋体">地址Q然后用当前h环境信息及服?/span>URI<span style="font-family: 宋体">地址到服务注册中心查扄实的服务Qƈ重新讄服务的地址?/span></p> <h3><span style="font-family: 宋体">l束?/span></h3> <p style="margin-left: 21pt; text-indent: 21pt"><span style="font-family: 宋体">本文_略的介l了</span>XFire<span style="font-family: 宋体">客户端的调用程Qƈ着重讲解了</span>Handler<span style="font-family: 宋体">的扩展机制及其应用场景,力求读者能够通过本文?/span>XFire<span style="font-family: 宋体">能有更加深入的了解和掌握。文中难免存在不之处,Ƣ迎M形式的交?/span></p> <img src ="http://www.aygfsteel.com/supercrsky/aggbug/198899.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/supercrsky/" target="_blank">々上善若水?/a> 2008-05-07 11:09 <a href="http://www.aygfsteel.com/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) http://www.aygfsteel.com/supercrsky/articles/198898.html々上善若水?/dc:creator>々上善若水?/author>Wed, 07 May 2008 03:08:00 GMThttp://www.aygfsteel.com/supercrsky/articles/198898.htmlhttp://www.aygfsteel.com/supercrsky/comments/198898.htmlhttp://www.aygfsteel.com/supercrsky/articles/198898.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/198898.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/198898.html阅读全文

]]>
图文q茂——用xfire~写webservice,q过C#调用http://www.aygfsteel.com/supercrsky/articles/197283.html々上善若水?/dc:creator>々上善若水?/author>Tue, 29 Apr 2008 07:41:00 GMThttp://www.aygfsteel.com/supercrsky/articles/197283.htmlhttp://www.aygfsteel.com/supercrsky/comments/197283.htmlhttp://www.aygfsteel.com/supercrsky/articles/197283.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/197283.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/197283.html 1.首先建立一个web service工程Q?br />       new_wizard1.gif
new_wizard2.gif

new_wizard3.gif
4.BMP


点击finish之后Qmyeclipse自动帮你生成services.xml以及web应用目录l构Q其中的services.xml是你导出服务的配|文Ӟ注意在WEB-INF/web.xml文g中配|了xfire自己的servlet.
<servlet>
    
<servlet-name>XFireServlet</servlet-name>
    
<servlet-class>org.codehaus.xfire.transport.http.XFireConfigurableServlet</servlet-class>
    
<load-on-startup>0</load-on-startup>
  
</servlet>
  
<servlet-mapping>
    
<servlet-name>XFireServlet</servlet-name>
    
<url-pattern>/services/*</url-pattern>
  
</servlet-mapping>


2.接下来,现在~写要导出的pojoc,首先是接口:
package net.rubyeye.webservicedemo;

//Generated by MyEclipse

public interface IHelloWorldService {
    
    
public String sayHello(String name);
    
}

q个接口我们只提供一个方?sayHello()Q我们没有采用JSR181标注式的声明方式Q还是采用xml配置文g。然后是实现c:
package net.rubyeye.webservicedemo;

//Generated by MyEclipse

public class HelloWorldServiceImpl implements IHelloWorldService {
    
    
public String sayHello(String name){
        
return "hello,"+name;
    }
    
    
}

最后,配置下services.xml文g:
<service>
        
<name>HelloWorldService</name>
        
<serviceClass>
            net.rubyeye.webservicedemo.IHelloWorldService
        
</serviceClass>
        
<implementationClass>
            net.rubyeye.webservicedemo.HelloWorldServiceImpl
        
</implementationClass>
        
<style>wrapped</style>
        
<use>literal</use>
        
<scope>application</scope>
    
</service>

我们的web服务名称叫做HelloWorldServiceQ接口是IHelloWorldServiceQ实现类?/span>HelloWorldServiceImpl?strong>注意Q其实我们这三个步骤可以一步完成,只要直接使用myeclipse的new web service向导卛_

new_webservice_wiz1.gif
new_webservice_wiz1_codefirst2.gif


3.然后此工程部v到tomcat上,通过http://localhost:8081/HelloWorld/services/HelloWorldService?wsdl可以看到生成的wsdl文g。注意,在部|之后,services会被拯到WEB-INF\classes\META-INF\xfire目录下,xfire会自动搜索此目录q加载配|文件。我们可以编写一个client来测试web服务Q你也可以点击myeclipse上的Launch the Web Services来测试web服务

webexplorer_launch.gif


4.~写client代码Q?br />
package net.rubyeye.webservicedemo;

import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;

import org.codehaus.xfire.XFireFactory;
import org.codehaus.xfire.client.XFireProxyFactory;
import org.codehaus.xfire.service.Service;
import org.codehaus.xfire.service.binding.ObjectServiceFactory;

public class HelloWorldClient {
    
public static void main(String args[]) {
        Service srvcModel 
= new ObjectServiceFactory()
                .create(IHelloWorldService.
class);
        XFireProxyFactory factory 
= new XFireProxyFactory(XFireFactory
                .newInstance().getXFire());
        
        String helloWorldURL 
= "http://localhost:8081/HelloWorld/services/HelloWorldService";
        
try {
            IHelloWorldService srvc 
= (IHelloWorldService) factory.create(
                    srvcModel, helloWorldURL);
            System.out.print(srvc.sayHello(
"dennis"));
        } 
catch (MalformedURLException e) {
            e.printStackTrace();
        }

    }
}

执行Q打华ͼhello,dennis

注意Q你也可以用MyEclipse的new webservice client向导自动生成clientQ同时生成供客户端调用的stubcȝ?br />
最后,我们再编写一个C#调用此web service的例子?br /> 1.在vs.net中新Z个windows 应用E序目Qƈd一个buttonQ和一个label
c1.BMP
c2.BMP

2.目菜单——》添加web应用Q输入我们要调用的web服务的wsdl文g的urlQƈ点击前往?br /> c3.BMP


3.d引用之后Qvs.net会自动帮你生成提供给客户端调用的stub{,q些文g在名为localhost的命名空间下。此I间下将有一个类Q名为HelloWorldService。最后,在button1的onclick事g中添加代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace MyProject
{
    
public partial class Form1 : Form
    {
        localhost.HelloWorldService helloService 
= new localhost.HelloWorldService();
        
public Form1()
        {
            InitializeComponent();
        }

        
private void button1_Click(object sender, EventArgs e)
        {
            label1.Text 
= helloService.sayHello("dennis");
        }
    }
}

我们new一?/span>HelloWorldService Qƈ调用sayHelloҎQ将l果昄在label?/span>
4.执行ctr+F5

c4.BMP


c5.BMP


]]>
.Net/C# ?J2EE/Java Web Service 互操作完整实?http://www.aygfsteel.com/supercrsky/articles/197050.html々上善若水?/dc:creator>々上善若水?/author>Tue, 29 Apr 2008 03:00:00 GMThttp://www.aygfsteel.com/supercrsky/articles/197050.htmlhttp://www.aygfsteel.com/supercrsky/comments/197050.htmlhttp://www.aygfsteel.com/supercrsky/articles/197050.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/197050.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/197050.html阅读全文

]]>
XPath详解http://www.aygfsteel.com/supercrsky/articles/196011.html々上善若水?/dc:creator>々上善若水?/author>Fri, 25 Apr 2008 09:02:00 GMThttp://www.aygfsteel.com/supercrsky/articles/196011.htmlhttp://www.aygfsteel.com/supercrsky/comments/196011.htmlhttp://www.aygfsteel.com/supercrsky/articles/196011.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/196011.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/196011.html阅读全文

]]>
Java开发WebService实例--计数?/title><link>http://www.aygfsteel.com/supercrsky/articles/196012.html</link><dc:creator>々上善若水?/dc:creator><author>々上善若水?/author><pubDate>Fri, 25 Apr 2008 09:02:00 GMT</pubDate><guid>http://www.aygfsteel.com/supercrsky/articles/196012.html</guid><wfw:comment>http://www.aygfsteel.com/supercrsky/comments/196012.html</wfw:comment><comments>http://www.aygfsteel.com/supercrsky/articles/196012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/supercrsky/comments/commentRss/196012.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/supercrsky/services/trackbacks/196012.html</trackback:ping><description><![CDATA[  如果使用GOOGLE、BAIDU{搜索工P搜烦WebService的相关知识,可以查到N多的|页Q我是通过q些|页的学习,逐渐掌握了些WebService的相关知识。这里对那些无私奉献知识的h一q表C感谢? <p> |上关于WebService的例子,多是一些简单得不能再简单的hello world的例子,单得以至于你对WebService没有什么感觉。有了WebService的基本知识后Q我一直再惻I可以把什么样的即单又实用 的东东做成WebServiceQ开展示一下其功能特点。今天终于想C个:计数器,计数器用得比较多Q功能比较独立,做成WebService可以一? 气Rؓ不同pȝQ不是JSPqASPQ这是WebService的突Z点)、不同应用节省此cȝ码工作,可以说以后再也不用写计数器了。只要用p 了?<br /> <br />   说了q么多废话,下面我们开始。本教程介绍一下WebService环境搭徏、服务部|的相关知识Q然后介l一个计数器的开发? <br /> <br /> q行图:</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引擎Q它是Apache的一个开源web service引擎。它目前最为成熟的开源web service引擎之一。下面我主要介绍一下如何用Axis搭徏web service 服务的环境?<br /> ①安装tomcat5.0应用服务器(也可以装5.5Q不q我一直在?.0Q? <br /> ②解压下载( http://ws.apache.org/AxisQ后的axis包,包中axis目录复制到tomcat目录下的webapps目录下;   <br /> ③将axis/WEB-INF/lib目录下类文g复制到tomcat目录下的common/lib目录下; <br /> ④重新启动tomcat,讉Khttp://localhost:8080/axis/happyaxis.jsp,如果能访问,表示安装成功Q? <br /> 注意Qaxis有几个可选的包,如email.jar....Q你可以找来攑ֈtomcat目录下的common/lib目录下,如果不用相关的功能也可以不用? <br /> q样Q开发环境就搭徏好了? <br /> <br /> <br /> 2.如何部vWeb Service<br /> 部v有三U方式:Dynamic Invocation Interface(DII)、Stubs方式、Dynamic Proxy方式Q这里就介绍一下简单,也是我用的方式QDII? <br /> DII方式中,先写好服务的JAVA文gQ假讑֐字ؓhelloworld.javaQ,然后把它Q注意是源文Ӟ拯到webapps/axis目录 中,后缀Ҏjws(此时文g名ؓQhelloworld.jws)Q然后访问连接http://localhost: 8080/Axis/helloworld.jws?wsdlQ页面显CAxis自动生成的wsdlQ这样一个Web Service部|好了。怎么P是不是很?<br /> 我的计数器服务就是以q种方式部v的,下文中我会只说将计数器服务部|好Q你可不要说Q怎么部vQ我不会呀。那在古代就要被打手板了。所以我惻I古代只学四书五经也是件好事呀。现在要学这么多东西Q半天学不会Q手要被打烂了? </p> <p><strong>三、计数器服务的编?/strong> <br /> 计数器大安知道了,比较单。我的计数器也同L单,有以下功能及特点Q提供四U计数器QL器、月计数器、周计数器及日计数器Q;考虑到Web Service要服务于多种应用Q这个计数器q支持多个用P使用XML文g来记录数据?br /> 记录文g名ؓQd:"counter.xml。注意,此文件在服务里是编码,如果修改名字Q请在服务程序中也进行相应的修改。文件内Ҏ式如下: <br /> <?xml version="1.0" encoding="UTF-8"?><br /> <counter><br /> <item><br /> <name>wallimn</name><br /> <password>123</password><br /> <dc>59</dc><br /> <wc>59</wc><br /> <mc>59</mc><br /> <tc>59</tc><br /> <rt>2007-4-16 16:01:29</rt><br /> </item><br /> <counter><br /> 说是计数器服务,其实跟编写普通的JAVA应用没有什么两栗我的计数器代码比较单,我就不做q多的介l了Q把它脓在下面,源码中有量注释Q相信大家不看注释也看得懂。服务有只有一个接口:Counter(String name, String password),以后在客L拿来用就可以了。还多说一句,我和E序使用Cdom4j解析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 /> *功能Q提供计数器服务的WebServiceQ可以ؓ多用h供服务?lt;br/><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 /> //出错的情况下q回的?br /> private final static String ERRORINFO="-1;-1;-1;-1";<br /> public WsCounterByWallimn(){ }<br /> <br /> <br /> /**<br /> *功能Q打开计数器文?lt;br/><br /> *~码Q王力猛 旉Q?007-4-16 下午04:44:29<br/><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 /> *功能Q取指定名称计数器的详细信息Qƈ讄计数器加1?lt;br/><br /> *~码Q王力猛 旉Q?007-4-16 下午04:49:57<br/><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;//密码不对Q直接返?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为空Q说明没有个名字的计数器。则d一个?br /> if(selitem==null){<br /> //System.out.println("没有扑ֈq个名字的计数器Q?+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 /> //L器L??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("上次登记旉Q?+DATEFORMATER.format(lastdt));<br /> //System.out.println("本次登记旉Q?+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{//q不一P则月计数器、周计数器日计数器肯定也不一栗?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 /> *功能Q服务暴露的接口Q也是指定名称、密码,q回指定的计敎ͼq将计数器加1?lt;br/><br /> *~码Q王力猛 旉Q?007-4-17 上午10:05:22<br/><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>四、客L~写</strong><br /> 客户端是个页面,Z条理清晰Q我先写个调用Web Service的类Q其内容如下Q?br /> package com.wallimn.WebService;//调试h意包?/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";//此处注意Q请与你的开发环境匹?br /> Service service = new Service();<br /> Call call = (Call) service.createCall();<br /> call.setTargetEndpointAddress(new java.net.URL(endpoint));<br /> call.setOperationName("Counter");<br /> // 填写你要调用的方法名U?br /> String counter = (String) call.invoke(new Object[] { CounterName, password });<br /> counterarr = counter.split(";");<br /> res = (counterarr != null && 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)上就单了Q我也把它脓在下面:<br /> <%@ page language="java" import="com.wallimn.WebService.CounterServiceClient" pageEncoding="GB18030"%><br /> <%<br /> CounterServiceClient client = new CounterServiceClient();<br /> client.getCounter("hello","123");<br /> %></p> <p><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><br /> <html><br /> <head><br /> <title>计数器测试页?lt;/title><br /> <br /> <meta http-equiv="pragma" content="no-cache"><br /> <meta http-equiv="cache-control" content="no-cache"><br /> <meta http-equiv="expires" content="0"> <br /> <meta http-equiv="keywords" content="wallimn,计数?WebService"><br /> <meta http-equiv="description" content="计数器用示?><br /> </head><br /> <br /> <body><br /> <h2 align="center">计数器详?lt;/h2><br /> <hr/> <br /> 总访问量:<%=client.getTc()%> <br/><br /> 今天讉K?<%=client.getDc()%> <br/><br /> 本周讉K?<%=client.getWc()%> <br/><br /> 本月讉K?<%=client.getMc()%> <br/> <br /> <hr/> <br /> <p>Ƣ迎交流<br/>博客Qhttp://blog.csdn.net/wallimn<br/>电邮Qwallimn@sohu.com</p><br /> </body><br /> </html></p> <p>五、结束语</p> x一个完整计数器的Web Service开发、用的E序的全部完成了。将上面的类、及面部vCQ意的一个上下文中,通过览器打开test.jspQ就可以看了l果了?br /> Ƣ迎讉K我的博客(http://blob.csdn.net/wallimn)留言或发邮g(wallimn@sohu.com)交流? <img src ="http://www.aygfsteel.com/supercrsky/aggbug/196012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/supercrsky/" target="_blank">々上善若水?/a> 2008-04-25 17:02 <a href="http://www.aygfsteel.com/supercrsky/articles/196012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XFire完整入门教程http://www.aygfsteel.com/supercrsky/articles/195670.html々上善若水?/dc:creator>々上善若水?/author>Thu, 24 Apr 2008 10:00:00 GMThttp://www.aygfsteel.com/supercrsky/articles/195670.htmlhttp://www.aygfsteel.com/supercrsky/comments/195670.htmlhttp://www.aygfsteel.com/supercrsky/articles/195670.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/195670.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/195670.html阅读全文

]]>
XFire 最新生火指南(?http://www.aygfsteel.com/supercrsky/articles/195669.html々上善若水?/dc:creator>々上善若水?/author>Thu, 24 Apr 2008 09:59:00 GMThttp://www.aygfsteel.com/supercrsky/articles/195669.htmlhttp://www.aygfsteel.com/supercrsky/comments/195669.htmlhttp://www.aygfsteel.com/supercrsky/articles/195669.html#Feedback2http://www.aygfsteel.com/supercrsky/comments/commentRss/195669.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/195669.html本文来自SpringSide WIkiQ请留意Wiki上的最新版?/a>?/a>

Z发布在JavaEye的敬畏心情,本文又修改了一遍,与前两天发在blogjava和csdn的版本稍有不同?/p>

1. 概述

   XFire 是全球众多牛人在与axispdҎ后一致投的选择。我比较ƣ赏的特性有Q?/p>

  1. 与Spring整合Q无ȝ成一堆文Ӟ无须打包独立warQ直接将应用中的Pojo导出为Web服务?
  2. Aegis--简U的默认Java XML l定机制Q且可以Plugin其他l定机制?
  3. JSR181--annotatiton驱动的POJO WebService配置?
  4. ZStax的高性能框架?
  5. qWeb服务器的单元试能力?

   |上的文档与例子L不新Q请大家抛开所有的文档Q所有的Axis习惯Q单看这份代表XFire1.2.2最U做法的指南?/p>

2. 生火指南

2.1 修改web.xmlQ在Web应用中增加XFire的入?/h3>

   注意XFire有了自己的ServletQ不再依赖Spring MVC的DispatchServletQ也pM大家不熟悉的Spring MVC URL MappingQ与Spring达致完美的整合?/p>

   q里指定了\径ؓ/service/* Q即WebService的URL会被默认生成?a title="Visit page outside Confluence" rel="nofollow" linktext="http://www.springside.org.cn/bookstore/service/BookService" linktype="raw" mce_ >http://www.xxx.com/yyy/service/BookServiceservice/ServiceNameQ其中ServiceName默认Z文中的接口名?/p>

xml 代码
  1. <servlet>  
  2.      <servlet-name>xfireservlet-name>  
  3.      <servlet-class>org.codehaus.xfire.spring.XFireSpringServletservlet-class>  
  4.  servlet>  
  5.  <servlet-mapping>  
  6.      <servlet-name>xfireservlet-name>  
  7.      <url-pattern>/service/*url-pattern>  
  8.     servlet-mapping>     
   如果应用使用了HibernateQ用了OpenSessionInView FilterQ注意配|OSIV Filter Filter覆盖xfire servlet的\径,x例中?service/*.

2.2 ~写H接口,抽取POJO中要导出的服?/h3>

   从已有的BookManager.java中,抽取Z个窄接口Q仅暴露需要导ZؓWeb Service的方法。而BookManger.java是POJOQ不需要Q何WebService相关代码?/p>

  H接口一斚w满了安全要求,不用整个BookManager所有方法导ZؓWeb ServiceQ另一斚wQXFire暂时也只支持Z接口的Proxy?/p>

public interface BookService {
List findBooksByCategory(String cateoryId);
}

 2.3 配置Java-XML Binding

   XFire默认的Aegis Binding语法非常单,在SpringSide的例子里几乎一行配|都不用写,是我见过最单的binding定义Q大大优于其他以设计复杂为终极目标的Ҏ?/p>

   对象的属性、函数的参数和返回值如果ؓint、String、Date{普通类型以及由普通类型组成的复杂对象都无需定义。我见到只有两种情况需要定义:

  • 无法使用泛型定义Collection中元素的cd?-如List findBooks()。如果能写成List findBooks()׃不需要了?
  • 需要ؓ属性定义不同的名字Q或者定义复杂对象里的某些属性不要输出?

     如果实在需要aegis配置Q?XFire以约定俗成代曉K|?CoC)Q所有Service和Entity Bean的binding文g要求命名为xxx.aegis.xmlQ而且要和原来的类sit together在同一目录里?/p>

  1. <mapping>  
  2.           
  3.        <property name="products" ignore="true"/>  
  4. mapping>  

   其他语法详见Aegis 参考?/p>

2.4 配置Spring导出

    Z节约配置代码Q先配置一个基cR注意导出Web服务的Bean不能lazy-initQ?/p>

  
  • <import resource="classpath:org/codehaus/xfire/spring/xfire.xml"/>  
  •   
  • <bean id="baseWebService" class="org.codehaus.xfire.spring.remoting.XFireExporter" lazy-init="false" abstract="true">  
  •   <property name="serviceFactory" ref="xfire.serviceFactory"/>  
  •   <property name="xfire" ref="xfire"/>  
  •  bean>  
  •  

     每个Web服务的定义:parent为前面定义的基类QserviceClass 为Web Service的接口,serviceBean为Web Service的接口实现类?/p>

    xml 代码
    1. <bean id="bookService" parent="baseWebService">  
    2.   <property name="serviceBean" ref="bookManager"/>  
    3.   <property name="serviceClass" value="org.springside.bookstore.components.xfire.server.simple.BookService"/>  
    4.  bean>  


     


    Web服务导出完毕Q用户可?a title="Visit page outside Confluence" rel="nofollow" href="http://localhost/service/BookService?WSDL">http://localhost/service/BookService?WSDL查看自动生成的WSDL?nbsp;

    上半章完Q关于JSR181,Client API与测试部分请?a title="XFireGuide2" >XFire 生火指南(?



    ]]>
    XFire生火指南下半?/title><link>http://www.aygfsteel.com/supercrsky/articles/195667.html</link><dc:creator>々上善若水?/dc:creator><author>々上善若水?/author><pubDate>Thu, 24 Apr 2008 09:56:00 GMT</pubDate><guid>http://www.aygfsteel.com/supercrsky/articles/195667.html</guid><wfw:comment>http://www.aygfsteel.com/supercrsky/comments/195667.html</wfw:comment><comments>http://www.aygfsteel.com/supercrsky/articles/195667.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/supercrsky/comments/commentRss/195667.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/supercrsky/services/trackbacks/195667.html</trackback:ping><description><![CDATA[<div> XFire生火指南下半部,主要包括JSR181,Client API与测试部分?/div> <p>作者:江南白衣</p> <p>本文来自SpringSide WIkiQ请留意Wiki上的最新版本?wiki?1.27更新)?/p> <p>请先阅读QXFire生火指南(?</p> <h2>1. JSR181</h2> <p>     JSR181式通过annotated POJO Q零配置文g的导出Web服务Q是BEA倡导的,JavaEE5里的正规方式Q?XFire作了良好的支持?/p> <p>     但是QXFire关于JSR181方式的文档还不够清晰Q请完整阅读本节以避免其中的C陷阱?/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>    因ؓ配置都写在annotationQapplicationContext.xml文g的内Ҏ较固定。需要注意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;"><</span><span style="color: #800000;">beans </span><span style="color: #ff0000;">default-autowire</span><span style="color: #0000ff;">="byName"</span><span style="color: #ff0000;">  default-lazy-init</span><span style="color: #0000ff;">="true"</span><span style="color: #0000ff;">></span><span style="color: #000000;"><br /> <img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />  </span><span style="color: #008000;"><!--</span><span style="color: #008000;">引入XFire的预配置文g</span><span style="color: #008000;">--></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;"><</span><span style="color: #800000;">import </span><span style="color: #ff0000;">resource</span><span style="color: #0000ff;">="classpath:org/codehaus/xfire/spring/xfire.xml"</span><span style="color: #0000ff;">/></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" /> </span><span style="color: #008000;"><!--</span><span style="color: #008000;"> 获得applicationContext中所有bean的JSR181 annotation </span><span style="color: #008000;">--></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;"><</span><span style="color: #800000;">bean </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="webAnnotations"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="org.codehaus.xfire.annotations.jsr181.Jsr181WebAnnotations"</span><span style="color: #ff0000;">  lazy-init</span><span style="color: #0000ff;">="false"</span><span style="color: #0000ff;">/></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" /> </span><span style="color: #008000;"><!--</span><span style="color: #008000;"> 定义handler mapping,所有JSR181定义的bean导出为web service </span><span style="color: #008000;">--></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;"><</span><span style="color: #800000;">bean </span><span style="color: #ff0000;">id</span><span style="color: #0000ff;">="jsr181HandlerMapping"</span><span style="color: #ff0000;"> class</span><span style="color: #0000ff;">="org.codehaus.xfire.spring.remoting.Jsr181HandlerMapping"</span><span style="color: #ff0000;">  lazy-init</span><span style="color: #0000ff;">="false"</span><span style="color: #0000ff;">></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;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="xfire"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="xfire"</span><span style="color: #0000ff;">/></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;"><</span><span style="color: #800000;">property </span><span style="color: #ff0000;">name</span><span style="color: #0000ff;">="webAnnotations"</span><span style="color: #ff0000;"> ref</span><span style="color: #0000ff;">="webAnnotations"</span><span style="color: #0000ff;">/></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;"></</span><span style="color: #800000;">bean</span><span style="color: #0000ff;">></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;"></</span><span style="color: #800000;">beans</span><span style="color: #0000ff;">></span></div> </div> <h3>1.3 Interface+Impl模式</h3> <p>   不同于XFire传统模式Q窄接口不是必须的,只是考虑到client如果也用XFireӞ有个接口好生成Client而已?/p> <p>   如果采用InterfaceQInterface担M要的配置工作?/p> <p>   首先定义@WebServiceQ可定义自己的NameSpaceQ如果不定义采用NameSpace的默认生成算法?/p> <p>   接口中的函数默认全部导出,不需要再用@WebMethod注释Q可以如下例般进行更q一步配|:</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 </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;">)<br /> </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">interface</span><span style="color: #000000;"> BookService {<br />   @WebResult(name </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">SearchResult</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />   List</span><span style="color: #000000;"><</span><span style="color: #000000;">Book</span><span style="color: #000000;">></span><span style="color: #000000;"> findBooksByCategory(@WebParam(name </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">category</span><span style="color: #000000;">"</span><span style="color: #000000;">, header </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">)String cateoryId);<br /> }</span></div> </div> <p>       Manager不是Ua的POJOQ需要带上@WebService注释Q指明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 </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">BookService</span><span style="color: #000000;">"</span><span style="color: #000000;">, <br /> endpointInterface </span><span style="color: #000000;">=</span> <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> <span style="color: #0000ff;">class</span><span style="color: #000000;"> BookManager </span><span style="color: #0000ff;">implements</span><span style="color: #000000;"> BookService {...}</span></div> </div> <p>      陷阱一QXFire JSR181参考文?sup><img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547211.gif" align="absmiddle" border="0" height="7" width="7" /></sup> 中在Interface中以@WebService(name="<font color="#009100">BookService</font>")来定义ServiceNameQ这个做法看h也比较合理,但实际上需要在Manager中以@WebService(serviceName ="BookService") 来定义,比较古怪?/p> <h3>1.4 UPOJO模式</h3> <p>    参考文档中的例子,需要配|@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 </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">EchoService</span><span style="color: #000000;">"</span><span style="color: #000000;">, targetNamespace </span><span style="color: #000000;">=</span> <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 />         </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> Jsr181EchoService<br /> {<br />     @WebMethod(operationName </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">echoString</span><span style="color: #000000;">"</span><span style="color: #000000;">, action </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">urn:EchoString</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />     @WebResult(name </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">echoResult</span><span style="color: #000000;">"</span><span style="color: #000000;">)<br />     </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String echo(@WebParam(name </span><span style="color: #000000;">=</span> <span style="color: #000000;">"</span><span style="color: #000000;">echoParam</span><span style="color: #000000;">"</span><span style="color: #000000;">, header </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">) String input)<br />     {<br />         </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> input;<br />     }<br /> }</span></div> </div> <h3>1.5 Client注意事项</h3> <p>    陷阱二:和传l模式的client有一Ҏ大的区别Q第3个参数需要是实际的Managerc,而不是接口类Q?/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 serviceModel </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> AnnotationServiceFactory().create(BookManager.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);</span></div> </div> <h2>2. Client</h2> <p>XFire的Clientq不强,一共有三种模式Q?/p> <h3>2.1 Client开发者拥有Web服务端的class</h3> <p>  Client与Server是同一个开发团队也好,Server端团队以jar形式提供开发包也好Q反正如果能拿到服务端的接口Class和Entitycdaegis 配置文g的话?/p> <p>  传统模式Q?/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 serviceModel </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> 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 service </span><span style="color: #000000;">=</span><span style="color: #000000;"> (BookService) </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> XFireProxyFactory().create(serviceModel, serviceURL);<br /> <img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />service.findBooksByCategory(cateoryId);</span></div> </div> <p>  JSR181模式Q注意这里Server端开发组需要向Client提供BookService的实现类BookManagerQ而不止于接口c,有点危险Q?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 serviceModel </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> 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 </span><span style="color: #000000;">=</span><span style="color: #000000;"> (BookService) </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> XFireProxyFactory().create(serviceModel, serviceURL);<br /> <img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />service.findBooksByCategory(cateoryId);</span></div> </div> <p>  SpringSide 用泛型封装了一个XFireClientFactoryQ调用代码如下:</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 service </span><span style="color: #000000;">=</span><span style="color: #000000;"> XFireClientFactory.getClient(serviceURL, 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 service </span><span style="color: #000000;">=</span><span style="color: #000000;"> XFireClientFactory.getJSR181Client(serviceURL, BookService.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">, BookManager.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);</span></div> </div> </div> </div> <h3>2.2 动态模?/h3> <p>    动态模式不需要服务端的classQ不q性能和复杂对象映等估计做得不会太好?/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 client </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> Client(</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> 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[] results </span><span style="color: #000000;">=</span><span style="color: #000000;"> client.invoke(</span><span style="color: #000000;">"</span><span style="color: #000000;">ConversionRate</span><span style="color: #000000;">"</span><span style="color: #000000;">, </span><span style="color: #0000ff;">new</span><span style="color: #000000;"> Object[] {</span><span style="color: #000000;">"</span><span style="color: #000000;">BRL</span><span style="color: #000000;">"</span><span style="color: #000000;">, </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>    q才是Web Service Client的王道,可以讉KL~写下的Web ServiceQ将在下一个版本中演示?/p> <h2>3. 试</h2> <p>XFiire很重要的一个特性是提供了无d动Web容器也能q行单元试的能力?/p> <p>原理是利用XFire的JVM模式Q以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>试的方式分两种Q?/p> <p>一U是U服务器角度Q不~写客户端代码,以SOAP XML形式发送请求,q回的也是SOAP XML字串Q直接对XMLq行试?/p> <p>一U是~写2.1 中Client代码来进行测试?/p> <p>前一U的试的隔d较高Q而后一U比较简ѝ?/p> <h3>3.1 试基类 </h3> <p>无论那种方式Q都使用Xfire?strong>AbstractXFireSpringTest</strong>基类Q实现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;"> ApplicationContext createContext() {<br />       </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> ClassPathXmlApplicationContext(</span><span style="color: #0000ff;">new</span><span style="color: #000000;"> 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 />  }</span></div> </div> </pre> </div> </div> <p>另外试基类q要完成一个很重要的工作就是要解决Hibernate的LazyLoad问题Q做到OpenSession In Test。因此,SpringSide专门装了一个XFireTestCase的基cR?/p> <h3>3.2 用Client代码直接试</h3> <p>     下文直接用client代码调用findBooksByCategoryҎQ得到返回值后q行各种Assert判断?/p> <p>     注意和普通client code的两处区别:servericeURL换成localQfactoryd入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 serviceModel </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> ObjectServiceFactory().create(BookService.</span><span style="color: #0000ff;">class</span><span style="color: #000000;">);<br />   XFireProxyFactory factory </span><span style="color: #000000;">=</span> <span style="color: #0000ff;">new</span><span style="color: #000000;"> XFireProxyFactory(getXFire());<br />   BookService service </span><span style="color: #000000;">=</span><span style="color: #000000;"> (BookService) factory.create(serviceModel, </span><span style="color: #000000;">"</span><span style="color: #000000;">xfire.local://BookService</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />   List list </span><span style="color: #000000;">=</span><span style="color: #000000;"> service.findBooksByCategory(</span><span style="color: #000000;">"</span><span style="color: #000000;">0</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br />   assertNotNull(list);<br />   ...</span></div> </div> <h3>3.3 U服务端试</h3> <p>   ~写一DSOAP XMLQ以L命名保存Q下文以"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;"><</span><span style="color: #000000;">env:Envelope 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;">></span><span style="color: #000000;"><br />     </span><span style="color: #000000;"><</span><span style="color: #000000;">env:Header</span><span style="color: #000000;">/></span><span style="color: #000000;"><br />     </span><span style="color: #000000;"><</span><span style="color: #000000;">env:Body</span><span style="color: #000000;">></span><span style="color: #000000;"><br />         </span><span style="color: #000000;"><</span><span style="color: #000000;">findBooksByName 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;">></span><span style="color: #000000;"><br />             </span><span style="color: #000000;"><</span><span style="color: #000000;">in1</span><span style="color: #000000;">></span><span style="color: #000000;">Java</span><span style="color: #000000;"></</span><span style="color: #000000;">in1</span><span style="color: #000000;">></span><span style="color: #000000;"><br />         </span><span style="color: #000000;"></</span><span style="color: #000000;">findBooksByName</span><span style="color: #000000;">></span><span style="color: #000000;"><br />     </span><span style="color: #000000;"></</span><span style="color: #000000;">env:Body</span><span style="color: #000000;">></span><span style="color: #000000;"><br /> </span><span style="color: #000000;"></</span><span style="color: #000000;">env:Envelope</span><span style="color: #000000;">></span></div> </div> <p>   试代码调用前面的XMLQ返回XML Document对象Q再用基cL供的一些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;">  Document doc </span><span style="color: #000000;">=</span><span style="color: #000000;"> 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" />  assertNoFault(doc);<br /> <img alt="" src="http://www.qqgb.com/Program/image/200701/20071183547177.gif" align="top" />  addNamespace(</span><span style="color: #000000;">"</span><span style="color: #000000;">ss</span><span style="color: #000000;">"</span><span style="color: #000000;">, </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" />  assertValid(</span><span style="color: #000000;">"</span><span style="color: #000000;">//ss:Book/ss:category/ss:descn= "Java Book"</span><span style="color: #000000;">"</span><span style="color: #000000;">, doc);</span></div> </div> <img src ="http://www.aygfsteel.com/supercrsky/aggbug/195667.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/supercrsky/" target="_blank">々上善若水?/a> 2008-04-24 17:56 <a href="http://www.aygfsteel.com/supercrsky/articles/195667.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ZXFire开发WebServiceshttp://www.aygfsteel.com/supercrsky/articles/195122.html々上善若水?/dc:creator>々上善若水?/author>Wed, 23 Apr 2008 07:25:00 GMThttp://www.aygfsteel.com/supercrsky/articles/195122.htmlhttp://www.aygfsteel.com/supercrsky/comments/195122.htmlhttp://www.aygfsteel.com/supercrsky/articles/195122.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/195122.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/195122.html 问一?Net的开发者,开发Web Services有多困难?他们会被你的问题逗乐Q他们会告诉你所有步骤花费的旉不会过一分钟。再问一下Java开发者,q气好的话你会碰C面的? {,一般情况下Q你会得C个完全不同的{案。从Web Services引入到Java中至今已l?q了Q然而它仍然被认为是一门较新的技术,一个主要的原因是使用Java实现Web Services太困难了。现在,随着C代Web Services引擎XFire的发布,q种情况会发生明显的变化。用XFireQ你可以把JavacL法发布ؓWeb Services而不需要编写额外的代码。在q篇文章中,你将会看到XFire使Web Services开发变得多么容易和单?/a>

      Web Services使我们能够在|络上徏立分布式pȝQ应用程序组件可以通过Mq_、Q何语a和Q何方式访问。无论应用程序如何开发,使用了什么语aQ以 及运行在什么操作系l^CQ只要它作ؓWeb ServiceQƈ且ؓ协同解决问题而设计,那么你的应用E序Q以M语言开发或在Q何^CQ都可以利用它的服务。这是Web Service的主要概c?/a>

      Z实现Web Services的^台无x和实现讉K独立性,软g行业需要遵循一些作为标准的技术。其中一些包?

      ---XML:在Web Services环境中各层之间进行传递的默认数据格式?/a>

      ---SOAP:装和交换信息的默认协议。第一ơ被提出Ӟ它是只取Simple Object Access Protocol(单对象访问协?的首字母。但是现在SOAP更多被认为是一个特定的名词Q以它自p命名,同样很多是用词不?SOAP? 际上不是用来讉K对象的。另外,它也不再单?/a>

      ---WSDL(Web Services Description LanguageQWeb Services描述语言):描述Web Services的语a。尽基于XMLq且可以被h理解QWSDL主要是由机器处理Q由客户端程序读取和理解?/a>

      下面的高U层ơ图表,ZWWW协会发布?#8220;Web Services Architecture”(Web Services架构)文档Q显CZq些技术在实际的工作环境中是如何发挥作?

    点击攑֤此图? src=

      q个程图显CZWeb Services中的核心技术是如何工作的?/p>

      q里QProvider是提供服务的应用E序lgQRequester是用服务的客户端程序。很多其他技术也会参与到交互中,但是q个囑֏昄了在Web Services环境中必需的核心技术组件?/p>

      XFire是一个免费的开源SOAP框架Q它不仅可以极大方便地实现这样一个环境,q且可以提供许多Web Services规范中高U特征,q些特征在多数的商业或者开源工具都没有提供。你要恰当的理解q些单词:great ease and simplicity(非常L和简?。你会看到使用XFire创徏Web Services是多么的单?/p>

      假如你的Web应用有一个Javac,q且你想把它的一个方法发布ؓWeb ServicesQ当使用XFireӞ你不需要编写一行额外的Java代码。只需要编辑发布描q符Q然后你׃得到一个Web Services。是的,它相当地单。我们来看一个例子?/div>
     

     

      一个简单的Javac?/strong>

      我们的例子是一个银行业应用E序Q服务器是运行在J2SE1.4.2_07下的Apache Tomcat5.5.7。假定你已经了解如何使用Java~写Web应用E序Qƈ知道应该如何把它部v到Apache Tomcat服务器上。我们的Web应用E序非常?它只做一件事——将资金从一个̎戯{到另外一个̎户上。一个普通的Javac? BankingService包含了一个叫做transferFunds()的方法来为我们完成这工作。它需要四个输入参?

      代码如下:

    package com.mybank.xfire.example;

    import java.text.NumberFormat;
    import java.text.DecimalFormat;

    /** XFire WebServices sample implementation class.
    */
    public class BankingService implements IBankingService {
       
        //Default constructor.
        public BankingService(){   
        }
       
        /** Transfers fund from one account to another.
        */
        public String transferFunds(
            String fromAccount, String toAccount, double amount, String currency){
           
            String statusMessage = "";
                         
            //Call business objects and other components to get the job done.
            //Then create a status message and return.
            try {
                NumberFormat formatter = new DecimalFormat("###,###,###,###.00");      
                statusMessage = "COMPLETED: " + currency + " " + formatter.format(amount)+
                " was successfully transferred from A/C# " + fromAccount + " to A/C# " + toAccount;
            } catch (Exception e){
                statusMessage = "BankingService.transferFunds(): EXCEPTION: " + e.toString();
            }
            return statusMessage;
        }
       
    }

     

      因ؓ使用接口的设计是一个好的实践,所以我们的JavacM实现了一个称为IBankingService的接口。代码十分简?

    package com.mybank.xfire.example;

    public interface IBankingService { 

        public String transferFunds(
            String fromAccount, String toAccount, double amount, String currency);
           
    }

      在实际实CQ这样一个方法可能包括各U类型的复杂调用、查询和处理操作。但是我们的CZ代码已经最化了,以至于我们可以集中精力在主要目标?把这个方法发布ؓWeb Services?/p>

      你可以看到BankingService是一个普通的Javac,没有M代码告诉我们它将会在Web Services中用。好的,q里我们不需要增加Q何东ѝ我们所有的工作都在部v描述W里完成?/p>

      Web应用的部|描q符

      在Java中,Web应用E序通常需要至一个部|描q符(叫做web.xml)对其q行配置。XFire本n是一个基于servlet的应? E序。因此,我们需要增加必要的引用到描q符文g中。然后我们还必须配置要创徏的Web Services。我们用一个称为services.xml的新文g来完成这件事?/p>

      web.xml

      首先Q修改web.xml。我们需要增加下面的XFire servlet相关的条?

    <servlet>
            <servlet-name>XFireServlet</servlet-name>
            <display-name>XFire Servlet</display-name>
            <servlet-class>org.codehaus.xfire.transport.http.XfireConfigurableServlet
             </servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>XFireServlet</servlet-name>
            <url-pattern>/servlet/XFireServlet/*</url-pattern>
        </servlet-mapping>
       
        <servlet-mapping>
            <servlet-name>XFireServlet</servlet-name>
            <url-pattern>/services/*</url-pattern>
        </servlet-mapping>


     

     

      services.xml

      现在我们不得不说一下我们的Web Services的由什么组成的了。这׃个叫做services.xml的文件完成,它存攑֜META-INF/xfire目录下,而这整个目录攑֜ WEB-INF/classes文g夹中Q它在Web应用E序的标准类路径中。这里是services.xml中的基本配置条目:

    <beans xmlns="http://xfire.codehaus.org/config/1.0">
     
      <service>
        <name>Banking</name>
        <namespace>mybank</namespace>
        <serviceClass>com.mybank.xfire.example.IBankingService</serviceClass>
        <implementationClass>com.mybank.xfire.example.BankingService</implementationClass>
      </service> 
     
    </beans>

       让我们看看这里都包含了什么内宏VWeb Services的定义包含在元素中,它还含有一些子元素。第一个子元素?name>Q它可以是你提供M的合法名字。这会被客LE序和其它需要定位你的服务的lg用到。例如,在服务准备好以后Q你在览器上使用q个名字来查看WSDL?/name>

      下一个子元素?lt;namespace>。Q何合法的XML名字都是可以的?lt;namespace>用来唯一标识你的服务的各个参数?br /> < serviceClass>元素包含了Javacȝ名字Q它指定了方法签名。在我们的例子中Q它是接口IBankingService。如? JavacL有实CQ何接口,你就需要把cȝ名字攑֜q里。在你的JavacL者接口中可能有几个方法。只需要一个入口把它们全部发布为Web Services?/font>

      <implementationClass>保存了实现方法的Javacd。这是一个可选元素。如果上一个元?lt;serviceClass>包含了一个接口,那么相应的实现类必须在这里指定?/font>

      是q样。我们的Web Services配置完成?/font>?/a>

      XFire和其它类?/strong>

      现在是最后一步了Q需要得到所有必需的类库。我们怎样得到它们?去XFire|站Q下载xfire-distribution-1.0.zipQ然后解压到一个本地文件夹。复制下面的jar文g和它的库文g夹到WEB-INF/lib?

      一切妥当。我们来部v和启动应用程序。ؓ了部|示例应用,只需要复制websvc.war到Apache Tomcat的webapps文g夹中Q再{待几秒钟。它会自动启动。这个应用的全部源代码也包含在这个war文g中。我们的E序已经准备作ؓ一? Web Service了?/a>

      我们如何知道Web Service正在工作?

      Z了解Web Service是否正在工作Q我们需要测试。首先,我们试来看WSDL是否可用。我们在览器中输入URL。哪个URL?因ؓ我们的应用程序的war? 件是websvc.warQƈ且在services.xml中给出的服务名是BankingQWSDL的URL应该?http: //localhost:8080/websvc/services/Banking?wsdl?/p>

      h?URL的第一部分Q例如,http://localhost:8080Q可能会Ҏ你的应用服务器不同而不同。无论怎样Q当你输入URL后,会看到一个XML文档Q它的根元素是。这个文档叫做服务的WSDL。如果你看到了,q就是你的应用作为Web Service已经可用的第一个证明?/p>

      但是q个试是不够的。可能会发生q种情况Q可以看到WSDLQ但是从客户端程序可能会讉K不到服务。因此ؓ了核实服务是否可以访问了Q我们必M用一个客Lq行服务的实际调用来q行一个真正的试?/p>

      开发一个客L

      你可以用Q何的SOAP工具创徏客户端,例如Q?Net或者Apache AxisQ有很多U方?使用从WSDL产生的stubsQ用动态代理,{等。在例子中,我们使用一个动态代理,以一个简单的Servlet形式Q叫? WsClient.java。ؓ了保持代码两最,所有在屏幕昄的元素都攑֜了doGet()Ҏ中。对Web Service的实际调用由callWebService()Ҏ完成Q它相当地简单。和下面的类?

    /* Call the Web service
        *
        */
        public String callWebService(
            String fromAccount, String toAccount, double amount, String currency)
            throws MalformedURLException, Exception {
           
            //Create a metadata of the service     
            Service serviceModel = new ObjectServiceFactory().create(IBankingService.class);       
            log.debug("callSoapServiceLocal(): got service model." );
      
            //Create a proxy for the deployed service
            XFire xfire = XFireFactory.newInstance().getXFire();
            XFireProxyFactory factory = new XFireProxyFactory(xfire);     
       
            String serviceUrl = "http://localhost:8080/websvc/services/Banking";
           
            IBankingService client = null;
            try {
                client = (IBankingService) factory.create(serviceModel, serviceUrl);
            } catch (MalformedURLException e) {
                log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());
            }   
                  
            //Invoke the service
            String serviceResponse = "";
            try {
                serviceResponse = client.transferFunds(fromAccount, toAccount, amount, currency);
           } catch (Exception e){
                log.error("WsClient.callWebService(): EXCEPTION: " + e.toString());                
                serviceResponse = e.toString();
            }       
            log.debug("WsClient.callWebService(): status=" + serviceResponse);             

            //Return the response
            return serviceResponse;
        }

      q个代码是如何工作的?我来解释一?首先Q我们创Z个服务模型,它包含服务的说明——换句话_是服务的元数据。我们用XFire的ObjectServiceFactory从IBankingService.class接口创徏q个模型?/p>

      接着QؓXFire获得一个代理工厂对象,它包含了常规的代码,也相当地单和易懂。这一步中没有M特定应用的东ѝ从q个proxyFactoryQ用服务模型和服务端点URL(用来获得WSDL)Q我们可以得C个服务的本地代理?/p>

     

      是它了。这个代理就是实际的客户端。现在,我们可以调用它的transferFunds()Ҏ来得到我们需要的Web Service?/a>

      一旦示例应用发布ƈ启动Q就可以试servlet URL:

      http://localhost:8080/websvc/ws?/a>

      q个Servlet使用默认参数来调用Web Service和显C接收到的响应。页面的最后两行应该读?

      Response Received
    COMPLETED: CDN$ 500.00 was successfully transferred from A/C# 11111-01234 to A/C# 99999-05678

      现在你可以确定Web Service已经发布q且在运行中了?/a>

      Z试不同的输入|你可以用完整的URLQ例?

      http://localhost:8080/websvc/ws?from=11-2345&to=77-9876&amt=250.00&cur=EUR?/a>

      基本的Web Services开发步骤清?/strong>

      q个清单ȝ了将一个JavaҎ发布为Web Service所必须的步?

      q就是所有需要的步骤Q是的,相当单?/a>

      XFire的其他高U特?/strong>

      XFire的用可能比较简单,但是在特性和功能性上Q它却占据着领导者的位置。下面是它的高Ҏ?

      最重要的是QXFire属于C代Web Services引擎。不仅仅是营销用语Q?#8220;C?#8221;有一些重要的意义。Apache Axis是第一代Java语言的Web Services引擎Q已l成Z所有后来工L参考标准。在q去的几q里QAxis以及q些其它的工具已l在很多生环境中进行了实地试。从中得出的 一个关键的问题是Web Servicesq不最适合RPCcd的通信。对于性能和效率,面向文档的消息Ş式是最好的方式。但是Apache Axis和很多其他的Web Services引擎都被设计成了面向RPC?管它们支持文档形式)。现在,整个行业正在开发新一代的SOAP引擎Q设计ؓ面向文档的。Apache 已经宣布l束旧版本的Axis引擎开发,现在专注于Axis2Q现在它的预发布版本?.95。XFire在今q的2月䆾发布了它的第一个品版? (1.0)。它的下一个版?1.1)仅仅在几个星期之后就q行了发布?/a>

     

      性能

      Web Services需要消耗很多资源,但是性能斚w它们不是那么引h注目。XFire打破了这U趋ѝ它消耗更的内存(部分因ؓ StAX的?Q但是表现却比多数可比较的SOAP引擎。你可以在资源中提供的链接中看到比较的结果?/a>

      此外QXFireq提供了各种Ҏ来进一步优化性能。一个方法是使用JVM内置传输(in-JVM transport)。如果你知道Web Services和客Lq行在同一个JVM上,你可以选择使用本地传输Q它可以大幅提升性能。在CZ中的客户端代码,看以下指定服务端点URL的这?

      String serviceUrl = "http://localhost:8080/websvc/services/Banking";

      替换?/a>

      String serviceUrl = "xfire.local://Banking";

      你会看到性能上的明显提高Q因为它l过了整个网l层?/a>

      局限?/strong>

      XFire有些重要的局限性你应该清楚:

      l论

      Java当前的趋势是化技术的使用。因此,我们正看C波基于POJO的开发成。同Ӟ面向服务架构 (SOAQServices-oriented architecture)和Web Services已经变成了当前行业的热点话题。XFire正是在这U情况下产生的。它能够使POJO发布为最的Web ServicesQ而只需要付出最化的努力。从而,它希望使用q项技术的初开发者的学习曲线变得q缓。同Ӟ׃它兼Ҏ新标准和提供了丰富的 APIQXFire为高U用h供了更多的大好机?/a>



    ]]>MyEclipse开发WebServices(ZAnnotations)http://www.aygfsteel.com/supercrsky/articles/195099.html々上善若水?/dc:creator>々上善若水?/author>Wed, 23 Apr 2008 07:02:00 GMThttp://www.aygfsteel.com/supercrsky/articles/195099.htmlhttp://www.aygfsteel.com/supercrsky/comments/195099.htmlhttp://www.aygfsteel.com/supercrsky/articles/195099.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/195099.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/195099.html支持JSR 181标注方式?/span>Web服务开发,另外Q所有支?/span>Java EE 5的应用服务器Q?/span>Tomcat只是Web层的Q本w不支持EJB?/span>Web服务开发)Q都支持q种开发方式,例如Q?/span>JBossQ?/span>GlassFishQ?/span>WebLogic10{等Q本节就要讨Z?/span>XFire开发标注式Web服务和用JBoss开发的q程?/span>

    15.4.1 XFire的标注服务开?/span>

           XFire支持JRS181方式的标注服务开发,q样开发的时候只需要编写一个普通的Javac,然后加上标注信息后,加入services.xml中即可。我们仍然在W?/span>2节所开发的HelloWorldService目中进行修攏V下面是创徏?/span>Web服务c?/span>echo.Jsr181EchoServiceQ?/span>

    package echo;

    import javax.jws.WebMethod;

    import javax.jws.WebParam;

    import javax.jws.WebResult;

    import javax.jws.WebService;

    @WebService(name = "EchoService", serviceName="EchoServiceTest", targetNamespace = "http://www.openuri.org/2004/04/HelloWorld")

            publicclass Jsr181EchoService

    {

        @WebMethod(operationName = "echoString", action = "urn:EchoString")

        @WebResult(name = "echoResult")

        publicString echo(@WebParam(name = "echoParam", header = true) String input)

        {

            return input;

        }

    }

    q个代码中有很多标注Q绝大部分都可以在最后生成的WSDL文档中找到对应倹{?/span>

    @WebServiceq个标注攄?/span> Java cM前,注明q个cȝ部分Ҏ可以被发布ؓ Web 服务Q还记得上一章提到的标注嘛?q个标注最l被XFired后进行分析后会进一步处理成Web服务Q。它的属性用于设|?/span> Web 服务被发布时的配|信息,常用的属性包括:

    nameQ可选)Q?/span>Web 服务的名字,WSDL?/span> wsdl:portType元素?/span> name属性和它保持一_默认?/span> JavacL者接口的名字Q也可以q行自定义,例如本例中的EchoService?/span> 

    serviceNameQ可选)Q?/span>Web 服务的服务名Q?/span>WSDL ?/span> wsdl:service元素?/span> name属性和它保持一_默认?/span>Javacȝ名字Q?/span>Jsr181EchoServiceQ,不过如果讄?/span>name属性,则名字改?/span>name属性的取倹{?/span>

    targetNamespaceQ可选)Q?/span> WSDL文g所使用?/span> namespaceQ该 Web 服务中所产生的其?/span> XML文档同样采用q个作ؓnamespaceQ一般取gؓWeb服务所在网站的名字Q不q看hL取值ƈ无出错之处?/span>

    @WebMethodQ可选) 标注攑֜需要发布成 Web 服务的方法之前,有一些属性可以设|。例?/span>openrationName指明?/span>SOAP调用时所看到的方法名?/span>echoStringQ而不是类中的Ҏ?/span>echoQ?/span>action则定义了操作的类型。一个类里面可以定义多个@WebMethod?/span>

    @WebResultQ可选)标注定义了返回|SOAP Response EnvolopeQ中?/span>name(名字)?/span>echoResult?/span>

    @WebParamQ可选)则定义了哪些参数可以作ؓWeb服务中的q程可见的参数被调用Q?/span>name讄了其属性?/span>

    乍看之下Q这?/span>Web服务中所用的标注有点多,实际上,q些标注可以不加M属性,例如只写?/span>@WebServiceQ?/span>@WebMethod卛_Q甚至于整个cd需要一?/span>@WebService标注卛_Q此时代码如下所C:

    package echo;

    import javax.jws.WebService;

    @WebService

    publicclass Jsr181EchoService {

        public String echo(

        String input) {

           return input;

        }

    }

    。此时最后所生成?/span>Web服务中,所有的操作名,Ҏ名和参数名都和此?/span>JavacM的名UC致。在q种情况下,?/span>Web服务的访问地址应ؓQ?/span>

    http://localhost:8080/HelloWorldService/services/Jsr181EchoService?wsdl ?/span>

           最后一步,乃是?/span>XFire中配|ƈ发布此服务了Q在services.xml中加入的Web服务配置格式如下Q?/span>

        <service>

           <!-- 如果配置文g中配|了额外?/span>name属性,那么最l的Web Service 名字会以此处ؓ准,卻I

               ServiceName?wsdlQ同Lnamespace的取g会覆?/span>JavacM的标注的倹{?/span>

               <name>ServiceName</name>

               <namespace>http://www.un.gov/HelloEcho</namespace>

           -->

           <serviceClass>echo.Jsr181EchoService</serviceClass>

           <serviceFactory>

               org.codehaus.xfire.annotations.AnnotationServiceFactory

           </serviceFactory>

        </service>

    Q此配置相当的简单,需要注意的?/span>serviceClass是我们写有Web服务标注?/span>Javac,?/span>serviceFactory则必LAnnotationServiceFactoryQ标注服务工厂)Q否则此Web服务无法正常发布?/span>

    好了Q现在按?/span>15.2.4一节的内容发布目q运行后Q即可在览器中键入下面地址q行试了:

    http://localhost:8080/HelloWorldService/services/EchoServiceTest?wsdl ?/span>

    EchoServiceTest的名字是因ؓ在类中标注了@WebService?/span>serviceName属性。之后就可以?/span>Web Service Explorer中对它进行测试,或者是生成客户端代码?/span>

    从这里看到这U开发方式相对也单的多,而且您将在下一节看到如果是Java EE 5的容器,开发过E将更加的简单,而且不需?/span>XFirecd及其配置文g?/span>



    ]]>
    我的W一个WebServicesE序(HelloWorld)http://www.aygfsteel.com/supercrsky/articles/173863.html々上善若水?/dc:creator>々上善若水?/author>Wed, 09 Jan 2008 00:20:00 GMThttp://www.aygfsteel.com/supercrsky/articles/173863.htmlhttp://www.aygfsteel.com/supercrsky/comments/173863.htmlhttp://www.aygfsteel.com/supercrsky/articles/173863.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/173863.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/173863.html
    然后创徏一个WebServiceE序:

    package com.web;


    public class HelloWorldImpl implements IHelloWorld {
        
        
    public String example(String message)
        
    {
            
    return "Welcome you !! this is first web service program!!" + message;
        }

        
    }

    IHelloWorld:
    package com.web;
    //Generated by MyEclipse

    public interface IHelloWorld 
    {
        
        
    public String example(String message);
        
    }

    q里你可以通过
    http://localhost:6666/webserver01/services/HelloWorld?wsdl
    q行讉KQlocalhost可以换成你对外公开的IP地址.

    当然也可以通过试E序讉K:
    package com.test;

    import org.codehaus.xfire.XFireFactory;
    import org.codehaus.xfire.client.XFireProxyFactory;
    import org.codehaus.xfire.service.Service;
    import org.codehaus.xfire.service.binding.ObjectServiceFactory;

    import com.web.IHelloWorld;

    public class HelloWorldClient
    {
        
    public static void main(String[] args)
        
    {
            Service srvcModel 
    = new ObjectServiceFactory()
                    .create(IHelloWorld.
    class);
            XFireProxyFactory factory 
    = new XFireProxyFactory(XFireFactory
                    .newInstance().getXFire());
            String helloWorldURL 
    = "http://localhost:6666/webserver01/services/HelloWorld";
            
    try
            
    {
                IHelloWorld srvc 
    = (IHelloWorld) factory.create(srvcModel,
                        helloWorldURL);
                String result 
    = srvc.example("zdw");
                System.out.println(result);
            }
     catch (Exception e)
            
    {
                e.printStackTrace();
            }

        }


    }

    详细可以参看MyEclipse自带的Help Contents.
    此示例源码下?a title="Ҏ下蝲" href="package com.test;">Ҏ下蝲

    ]]>
    SOAP和WSDL初识http://www.aygfsteel.com/supercrsky/articles/173841.html々上善若水?/dc:creator>々上善若水?/author>Tue, 08 Jan 2008 15:51:00 GMThttp://www.aygfsteel.com/supercrsky/articles/173841.htmlhttp://www.aygfsteel.com/supercrsky/comments/173841.htmlhttp://www.aygfsteel.com/supercrsky/articles/173841.html#Feedback0http://www.aygfsteel.com/supercrsky/comments/commentRss/173841.htmlhttp://www.aygfsteel.com/supercrsky/services/trackbacks/173841.htmlSOA是英文Service-Oriented ArchitectureQ即面向服务架构的羃写?br style="font-family: " />
    q个词汇最q一两年频频出现在各U技术期刊上。但是一直以来对于SOA到底是什么没有明的回答QSOA有什么特点?适合用于解决哪些问题Q与其他的技术有什么区别与联系QWeb Service和SOA又是什么关p?SOA的出现对于Y件架构设计有什么媄响?本文就上面提到的这些问题,试Ҏ作者自q理解l出SOA的定义;ȝ出SOAҎ的三个基本特征;然后以HTTP协议Z对这些特征进行解释;最后简要的说明SOA对今后Y件架构设计可能带来的影响? 
    SOA定义   
    下面是作者给SOA下的一个定义:
    SOA是指Z解决在Internet环境下业务集成的需要,通过q接能完成特定Q务的独立功能实体实现的一UY件系l架构。从q个定义中我希望表达的前提有下面两点Q?  
    1) 软gpȝ架构QSOA不是一U语aQ也不是一U具体的技术而是一UY件系l架构,它尝试给出在特定环境下推荐采用的一U架构,从这个角度上来说Q它更像一U模?Pattern)。因此它与很多已有的软g技术比如面向对象技术,是互补的而非互斥的。它们分别面向不同的应用场景Q用来满不同的特定需求?  

    2) SOA的用范_需求决定同时也限制功能。SOAq不是包ȝ病的万灵丹,它最主要的应用场合在于解军_Internet环境下的不同商业应用之间的业务集成问题?br style="font-family: " />
    在下面我们会详细讨论Internet的各U特点如何决定SOA的特点,q里我们只需要先单回一下Internet环境区别于Intranet环境的几个特点:   
    a) 大量异构pȝq存Q计机g工作方式不同Q操作系l不同、编E语a也不同;  
    b) 大量、频J的数据传输仍然速度~慢q且不稳定;   
    c) 版本升无法完成Q我们根本就无法知道互联|上有哪些机器直接或者间接的使用某个服务?  

    Z上面的前提,下面p我们一L一下SOA的基本特征?  

    SOA三大基本特征   
    1 独立的功能实? 
    在Internetq样松散的用环境中QQ何访问请求都有可能出错,因此M企图通过Internetq行控制的结构都会面临严重的E_性问题。SOA非常架构中提供服务的功能实体的完全独立自ȝ能力。传l的lg技术,?NET RemotingQEJBQCOM或者CORBAQ都需要有一个宿?Host或者Server)来存攑֒理q些功能实体Q当q些宿主q行l束时这些组件的寿命也随之结束。这样当宿主本n或者其它功能部分出现问题的时候,在该宿主上运行的其它应用服务׃受到影响?  SOA架构中非常强调实体自我管理和恢复能力。常见的用来q行自我恢复的技术,比如事务处理(Transaction)Q消息队?Message Queue)Q冗余部|?Redundant Deployment)和集系l?Cluster)在SOA中都起到臛_重要的作用?  

    2 大数据量低频率访?  

    对于.NET RemotingQEJB或者XML-RPCq些传统的分布式计算模型而言Q他们的服务提供都是通过函数调用的方式进行的Q一个功能的完成往往需要通过客户端和服务器来回很多次函数调用才能完成。在Intranet的环境下Q这些调用给pȝ的响应速度和稳定性带来的影响都可以忽略不计,但是在Internet环境下这些因素往往是决定整个系l是否能正常工作的一个关键决定因素。因此SOApȝ推荐采用大数据量的方式一ơ性进行信息交换?  

    3 Z文本的消息传?  
    ׃Internet中大量异构系l的存在军_了SOApȝ必须采用Z文本而非二进制的消息传递方式。在COM、CORBAq些传统的组件模型中Q从服务器端传往客户端的是一个二q制~码的对象,在客L通过调用q个对象的方法来完成某些功能Q但是在Internet环境下,不同语言Q不同^台对数据、甚x一些基本数据类型定义不同,l不同的服务之间传递对象带来的很大困难。由于基于文本的消息本n是不包含M处理逻辑和数据类型的Q因此服务间只传递文本,Ҏ据的处理依赖于接收端的方式可以帮忙绕q兼Ҏ这个的大惔坑?  此外Q对于一个服务来_Internet与局域网最大的一个区别就是在Internet上的版本理极其困难Q传lY仉用的升方式在这U松散的分布式环境中几乎无法q行。采用基于文本的消息传递方式,数据处理端可以只选择性的处理自己理解的那部分数据Q而忽略其它的数据Q从而得到的非常理想的兼Ҏ?  

    HTTP协议Q一个典型的SOA实现   每一Ҏ技术都是在一些旧的技术基上发展出来的。正如XMLҎ思想来自于在60q代已l出现的早期标记性语a一PSOA虽然q两q才出现Q但是它所表达的观念应该说在网l这U分布式pȝl构出现不久已l广泛应用了。例如我们最熟悉的HTTP协议是一个非常典型的SOA架构设计。HTTP协议的工作过E简单叙q如下:   

    1) 客户端,通常是通过览器,向服务器端以文本的方式发送一个请求,索取一个Web面Q?  

    2) 服务器端接收到这个请求之后,Ҏh的内容进行处理ƈ且返回一个符合HTML语法的文本;   

    3) 客户端接收到服务器端的响应文本后调用本地的程序,通常q是览器,把返回的HTML文本的内容展现出来?  

    下面来看一下HTTP协议如何满了SOA的特点:   
    * 独立的功能实体:作ؓ服务器端的Web服务器是l对不会因ؓ客户端的状况变化而改变的Q它L非常E_地按照自q内在逻辑q行Q响应外部的hQ管理自q资源和数据。这里一个非常好的例子就是Web服务器对~存(Cache)的处理,很多Web服务器ؓ了提高性能都或多或的Ҏ据进行缓存,但是~存数据、刷新数据这些于客户端完全无关的操作完全由服务器端独立完成,完全不受客户端的影响?  

    * 大数据量低频率访问:对于一个HTTPh来说Q客L与服务器之间讉K的边界非常简单:是一个请求,一个响应,没有M其它的信息往q。无论客L甌的网上除了文字之外q有什么信息,对于客户端来_它发出的h只是单的告诉Web服务器它所需要的|页的位|;至于Z生成q个|页Q服务器端是否需要访问数据库Q执行Servlet或者其它的CGIE序对客L而言Q都是完全透明的?br style="font-family: " />
       * Z文本的消息传递:q今为止兼容性最好的pȝ可能是HTTP协议支撑的大部分的web应用了,我们可以在Windowsq_下用IE查看互联|上一个LinuxQApache服务器上的由Perl脚本自动生成的网c这里的关键是所有内定w是以格式化的文本方式传递的Q不Perl脚本如何执行Q只要它的输出是W合HTML规范的网,可以被客户端的览器解释。而由于不同的操作pȝ上对于相同的HTML的解释遵循相同的规范Q因此不同操作系l下仍然能够看到一致的用户界面?  我们上面基本描述了SOA作ؓ一UY件架构有哪些特点Q下面让我们一L看Web Service与SOA的关pR?  SOA与Web Service   Web Service是就现在而言最适合实现SOA的一些技术的集合Q事实上最qSOA的火爆在很大E度上归功于Web Service标准的成熟和应用的普及ؓq泛的实现SOA架构提供了基。下面让我们看看Web Service中的各种协议是如何互相工作来满SOA所需的特点的Q?  

    * 独立的功能实体:通过UDDI的目录查找,我们可以动态改变一个服务的提供方而无需影响客户端的应用E序配置。所有的讉K都通过SOAP讉Kq行Q只要WSDL接口装良好Q外界客L是根本没有办法直接访问服务器端的数据的?  

    * 大数据量低频率访问:通过使用WSDL和基于文?Literal)的SOAPhQ我们可以实现能一ơ性接收大量数据的接口。这里需要着重指出的是SOAPh分文本方式和q程调用(RPC)两种方式Q正如上文已l提到的Q采用远E调用方式的SOAPhq不W合q点要求。但是o人遗憄是现有的大多数SOAPh采用的仍然是q程调用(RPC)方式Q在某些q_上,例如IBM WebSphere的早期版本,甚至没有提供文本方式的SOAP支持?  

    * Z文本的消息传递:Web Service所有的通讯是通过SOAPq行的,而SOAP是基于XML的,不同版本之间可以使用不同的DTD或者XML Schema加以辨别和区分。因此只需要我们ؓ不同的版本提供不同的处理可以轻村֮现版本控制的目标?  SOA对于软g架构设计的媄?  无论您现在的pȝ是否牉|到基于Internet的业务集成,采用SOA推荐的架构都Ҏ高您pȝ的扩展性有很大帮助Q下面是在系l中引入SOA后需要在软g架构斚w做出的改变:   

    * 使用Z文本方式的SOAP调用Q摆pE调用中出现的函数参数类型等与数据无关的信息Q保证所有SOAP传递的都是有意义的商业数据。依赖于SchemaQ而不是类定义对这些数据进行解释?  

    * 传统的三层Web应用可能变成四层结构:传统意义上的商业逻辑层将被进一步划分ؓ存放每个会话(Session)信息的客户逻辑层和与状态无关Sateless的SOA层?




    WSDL

    Web Services Description Language的羃写,是一个用来描qWeb服务和说明如何与Web服务通信的XML语言?br style="font-family: " />
    怎样向别Zl你的Web service有什么功能,以及每个函数调用时的参数呢?你可能会自己写一套文档,你甚臛_能会口头上告诉需要用你的Web service的h。这些非正式的方法至都有一个严重的问题Q当E序员坐到电脑前Q想要用你的Web service的时候,他们的工?如Visual Studio)无法l他们提供Q何帮助,因ؓq些工具Ҏ׃了解你的Web service。解x法是Q用机器能阅ȝ方式提供一个正式的描述文档。Web service描述语言(WSDL)是q样一个基于XML的语aQ用于描qWeb service及其函数、参数和q回倹{因为是ZXML的,所以WSDL既是机器可阅ȝQ又是h可阅ȝQ这是一个很大的好处。一些最新的开发工h能根据你的Web service生成WSDL文档Q又能导入WSDL文档Q生成调用相应Web service的代码?
    ================================================================================================
    WSDL用来提供Ҏ务的描述 Q它的主要构成要素有五个:
    1QTypesQ?定义WSDL定义中所用到的数据类型,即XML Schema Types
    2QMessage : 对一l消息的输入和输出参数的定义
    3QportType : 定义Web服务的操?br style="font-family: " /> 4)  Binding Q描q特定服务接口的协议、数据格式、安全性和其它属?
    5)  Services : 制定特定服务的URL和提供的调用接口Q包含一l端口元?br style="font-family: " />


    ]]>
    վ֩ģ壺 ®| | ƽ| | ֯| ŷ| | º| | ɽ| ̰| ԭ| Դ| | ͬ| | ƽ| | | ϴ| | ̶| | | | Ȫ| | | ɽ| ͨ| | ͨ| ٲ| | ײ| | | з| | | ̫|