本帖最后由 群发软件 于 2017-7-2 21:03 编辑
开始之前,我想就本文即将讨论的主题和读者需要具备的起点知识做一些必需的描叙。本文的主题是讨论SOAP技术,我们将尽可能的讲得通俗易懂一些,所以,我们引入了一个普通的“Hello World”范例来给读者说明它们是怎么运作的,让读者知道它们的运作方式。我认为,如果光看官方文档是很难开始学习这门新技术的,官方文档中包含大量的范例,并解释了所有的特性和优点,但是没解释它们的运作方式。在这篇文章中,我不打算只肤浅的解释SOAP技术的定义,我们假设读者熟悉JAVA语言,Web技术,具有XML语言,XML Namespaces,XML Schema的基础。在这种情况下,理解本文将不存在任何困难。然而,即使没有这些知识,你也不必担心,我们将尽可能的解释得简单,但是当你开始做自己的SOAP应用程序时会遇到一些问题和麻烦。因此,花费一定时间来学习上面的知识是很有必要的。
从技术的角度来说,有必要提一下我们的调试环境。我们使用的是Windows XP操作系统,安装有JAVA 2 SDK 1.4.1,Apache SOAP 2.3.1,JAF 1.0.2,JAVAMAIL 1.3.1和Xerces 2.6.0。上面所提及的都能在Tcomcat 4.1.29 JSP/Servlet容器中正常运行。所有的软件都是免费自由软件,因此你能够很容易的下载它们并自己在任何你喜欢的平台如Windows或UNIX上安装它们。Java SDK,JAF和JAVAMAIL位于SUN的官方网站,其他的软件在Jakarta项目组的官方网站上有down的。可能你在看到我们需要这么多不同的包(package)时已经有点担心和不安了,但是实际上你不应该担心这些的。一旦你懂了基础,那么对你将相当容易。安装不是一件很难的事情,你只需要在设置环境变量的时候仔细些,比如CATALINA_HOME, CLASSPATH, JAVA_HOME 等等,所有这些步骤都是手工的。由于我仅仅是想将你的注意力再次集中到它们身上,所以你能很快的就完成以上配置过程。我只是添加下面的一些字符串到Tomcat的bin/setclasspath.bat文件中:
...
set CATALINA_HOME=C:\Tomcat4.1.29
set CLASSPATH=%JAVA_HOME%\lib\tools.jar
set CLASSPATH=%JAVA_HOME%\soap-2.3.1\lib\soap.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\javamail-1.3.1\mail.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\jaf-1.0.2\activation.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\xerces-2_6_0\xercesImpl.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\xerces-2_6_0\xercesSamples.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\xerces-2_6_0\xml-apis.jar
set CLASSPATH=%CLASSPATH%;%JAVA_HOME%\xerces-2_6_0\xmlParserAPIs.jar
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\common\lib\servlet.jar
set CLASSPATH=%CLASSPATH%;%CATALINA_HOME%\common\lib\tools.jar
...
如果你的安装路径(installation paths)和上面使用的不同,你需要更正它们,然后关闭和重启Tomcat以使它们生效。这样,你就有为运行SOAP作好了准备。但是现在,我要忘记有关的技术部分,来学一点理论知识。
SOAP意思是简单对象访问协议(Simple Object Access Protocol)。的确如它的名字一样,SOAP是很简单的。它是一个基于XML的协议,允许程序组件和应用程序彼此使用一种标准的Internet协议--HTTP来通讯。SOAP是一种独立的平台,它不依赖程序语言,它是简单的,弹性的,很容易扩展的。目前,应用程序能够彼此使用一种基于DCOM和CORBA技术的远程过程调用(RPC)来进行相互通讯,但HTTP不被设计为这个目的。RPC在Internet上应用是非常困难的,它们会出现许多兼容性和安全性的问题,因为防火墙和代理服务器通常都会阻断(block)这些类型的流量。应用程序之间最好的通讯方式是通过HTTP协议,因为HTTP是支持所有Internet浏览器和服务器的。基于这个目的,SOAP协议被创建出来。
那么,它们是如何运作的呢?比如,一个应用程序(A)需要和另一个应用程序(B)在SOAP的帮助下进行彼此通讯。它们将使用下面的框架图来完成这个过程:
这个SOAP信封(SOAP envelope)是一个包含以下内容的XML文档:
正如你看到的,它是非常简单的。它看起来确实就象一个普通的信封或者你的email。你想看看它们是如何动作的吗?下面跟我们一起来吧。其实我们有很多方法是不用SOAP来在创建和运行我们自己的“Hello World”应用程序的,但是因为我们要保持它的简单性,我会给你一个它运作方式的框架图(scheme)。
我们的“Hello World”范例会包含一个SOAP Service。我们的SOAP Client将发送它们的名字到该SOAP Service,并试图得到一些答复或响应。这个SOAP Service需要部署到一个SOAP Admin的工具,以至重定位所有请求的SOAP(Proxy) RPC Router能够知道它们应该使用哪种服务来运作。总而言之,这个是以下面的方式来运作的:
现在,我们来一步步的看看到底发生了什么。在Step 1里,HelloWorldClient将连接一个SOAP RPC Router,请求我们的SOAP Service并将包含我们名字的一个字符串传递给它。该SOAP RPC Router会检查是否它已经部署了这个SOAP Service。如果它被发现是被部署的,那么它将传递数据到这个SOAP Service并调用特定的方法,这个是Step 2。然后SOAP Service方法会被执行,将返回某个字符串值(该值就是SOAP Client的答复或者响应)(Step 3)。在Step4中,SOAP RPC Router将仅仅只是重定向这个数据到SOAP Client。所有在Step1和Step4里传输的数据是通过SOAP Envelope来完成的。正如你所看到的,算法是相当简单的,因此我们只准备关心实际的代码。
首先,我们要创建一个SOAP Service。下面是它的代码,请不要忘记将它放入HelloWorld/ 目录中(必须被包含在你的CLASSPATH中):
1: // SOAPService.java
2: package HelloWorld;
3: public class SOAPService {
4: public String sayHi(String x) {
5: return("Hello my friend, " + x + "! Glad to see you!");
6: }
7: }
添加任何注释也是很容易的。要编译它,只需要用下列命令:
javac SOAPService.java
第二步,一旦我们准备好了SOAP Service,我们需要用SOAP Service Manager来部署它。这个可以通过很多方式来实现,但是为了能让初学SOAP的读者更容易理解SOAP,我提供了一个最容易的方式。我们假设你的Web Server(Tomcat或其他)已经正常运行,并且你已经正确安装了SOAP。那么当浏览器访问http://localhost:8080/soap/,你会看见Apache SOAP的欢迎页面。点击Run the admin client ,然后 Deploy。你会得到一个屏幕显示,在那里你需要填入ID,Scope,Method,Provider Type和JAVA Provider的信息到表单域中。你能忽略其他所有的表单域,除非你真的需要它们的信息。我们的“HelloWorld”例子不需要它们,所以,我们填的下面的值:
ID: urn:HelloWorld_SOAPService
Scope: Application
Methods: sayHi
Provider Type: java
Java Provider - Provider Class: HelloWorld.SOAPService
Java Provider - Static? No
一些注释:ID是我们要从SOAP Client标识我们的SOAP Service的唯一名字。Method包含SOAP Service提供的一系列方法。JAVA Provider-Provider Class是SOAP Service Java类的名字。
现在,点击Deploy 按钮,那么你的服务会被部署。再次强调,请注意正确设置CLASSPATH环境变量。然后,你的HelloWorld.SOAPService类能够被找到,并且所有必需的jar包也能被找到。这是个几乎每个人都会犯的普通错误。现在,你能够点击 List ,将会看见你的服务已经被部署进来。恭喜!
最后,让我们来创建一个SOAP Client。代码看起来有点复杂,但是在现实中不会只有这么点长。
1: // HelloWorldClient.java
2: import java.io.*;
3: import java.net.*;
4: import java.util.*;
5: import org.apache.soap.*;
6: import org.apache.soap.rpc.*;
7: public class HelloWorldClient {
8: public static void main(String[] arg) throws Exception {
9: Call c = null;
10: URL url = null;
11: Vector params = null;
12: Response rep = null;
13: String urName = "Superman";
14: String urUrn = "urn:HelloWorld_SOAPService";
15: String urMethod = "sayHi";
16: url = new URL("http://localhost:8080/soap/servlet/
rpcrouter");
17: System.out.println("Passing to our deployed "+ourUrn+"
our name ("+ourName+"): ");
18: c = new Call();
19: c.setTargetObjectURI(ourUrn);
20: c.setMethodName(ourMethod);
21: c.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
22: params = new Vector();
23: params.addElement(new Parameter("ourName", String.class,
ourName, null));
24: c.setParams(params);
25: System.out.print("and its answer is: ");
26: rep = c.invoke(url, "");
27: if (rep.generatedFault()) {
28: Fault fault = rep.getFault();
29: System.out.println("\nCall failed!");
30: System.out.println("Code = " + fault.getFaultCode());
31: System.out.println("String = " + fault.getFaultString());
32: } else {
33: Parameter result = rep.getReturnValue();
34: System.out.print(result.getValue());
35: System.out.println();
36: }
37: }
38:}
下面我要做一些解释。在第13行,我们设置了我们的名字,这个名字将会传递给SOAP Service。在第14行,我们设置了我们将要调用的服务的ID(service ID),和第15行里设置的服务方法(service method)。有了这个ID,服务能够被部署到SOAP服务管理器(SOAP Service Manager)中。我们没有设置任何其他值,仅仅只用刚才那些基础值就可以正常运作了。你能从SOAP的官方文档上得到相关信息,该文档来自SOAP包中,它们的解释超出了本文的范围。
用以下方式编译这个SOAP Client:
javac HelloWorldClient.java
为了圆满完成它,让我们检查一下针对我们的测试,是否所有事情都准备就绪。Tomcat正在运行,所有的环境变量都正确,SOAP Service被编译和部署,SOAP Client被成功编译。OK,让我们运行它,你将看到这个屏幕:
正如你所看到的,我们的SOAP Client使用SOAP协议成功发送它的名字和接收了一个答复。正如前面所说的,SOAP Service发送和接收的是SOAP envelope。这个是SOAP envelope的源代码。
在IT基础设施中将各种应用软件的数据集成起来是一回事,因为相关方法和实践都经过检验,证明是可行的。但是,在服务导向架构(SOA)上实现数据集成则是另一回事,那可是个新挑战。
“SOA的引入,使数据与应用之间的差别日渐模糊。”SOA市场研究机构ZapThink公司的罗恩·施麦尔泽尔(Ron Schmelzer)总结道。当一套应用软件作为独立的服务,执行某些功能,其运行结果被传递到其他应用软件时,这些结果看起来很像数据。与此类似,对某项服务的查询会启动数据库中的进程,产生的结果看起来很像应用逻辑的导出结果。总之,在服务中,数据与应用逻辑已不再有明显的区别。
重要的是这些结果是否能与下一个操作进行集成。数据的集成目前有几种不同的方式。iWay公司、Software AG公司等企业的产品提供了一些源自于常规企业应用集成的新途径。比如,iWay就拥有一个包括300个适配器(Adapter)的程序库,这些适配器可将应用软件之间或应用软件与数据源之间连接起来。将这些适配器与iWay的Service Manager集成起来,便可解决如何将数据传输至其目的地的问题,从而将不同服务上的数据连接在一起。
方法之一
香水和个人护理产品厂商科蒂公司(Coty)花了半年时间发现,iWay产品恰是它集成联合利华公司(Unilever)的化妆品业务所需要的。它于2005年末收购了后者。
科蒂的首席财务官(CFO)迈克尔·费绍夫(Michael Fishoff)要求首席信息官(CIO)戴夫·拜里(Dave Berry),将两家公司面向客户的数据集成到一起,项目截止到去年6月30日。如果届时无法达成目标,两家公司原有的客户利益就势必受到影响,而且该公司还不得不继续维持两支销售团队、两条供应链、以及两套软件基础设施的现状。
在收购联合利华后不久,拜里就听说,美国联邦百货集团(Federated Department Stores)等大客户纷纷抱怨,两家公司合并后,他们的采购员得分别跟两家公司的销售代表洽谈,或者甚至要经过3个系统才能够拿下订单。
过去,联合利华旗下品牌克罗伊(Chloe)或者卡尔文·克莱恩(Calvin Klein)的香水订单得通过JD Edwards系统才能送达法国的里尔。而科蒂旗下热卖的品牌席琳·迪翁(Celine Dion)或者詹尼弗·洛佩兹(Jennifer Lopez)香水必须通过该公司位于德国卡塞尔的其自主研发的仓库管理系统才能下订单。给其他产品下订单也得通过科蒂位于美国北卡罗莱纳州分销中心中的Oracle销售系统才行。“如果我们自己编写代码,根本无法在半年内完成这几个系统的集成工作。”
而将JD Edwards系统与Oracle应用软件或者将Oracle软件与SAP系统连接起来,那正是iWay的连接器和适配器所要做的。拜里认识到,他需要将某些流程合而为一,正是这些流程导致客户从他的公司采购产品时会收到两张发票。
埃森哲公司(Accenture)的业务流程顾问接受了此项任务。埃森哲的业务分析师首先利用iWay的Service Manager产品来弄清楚科蒂不同的订单录入系统之间的差别,然后进行数据的转换过程。
Service Manager软件中有对JD Edwards和SAP系统有一个图形影射功能,每当业务分析师在这个图形影射上绘制业务流程图师,该软件就会自动在订单录入系统之间完成业务流程线条的数据的自动转换。直到将科蒂和联合利华的订单录入系统的输出结果整合起来,生成单一的发票时,这两个订单录入系统才能协同工作。
现任科蒂北美信息管理副总裁加里·盖兰特(Gary Gallant)负责这一艰难的系统集成项目,此前他曾担任联合利华首席IT经理。盖兰特发现,某一天的订单在发送到iWay系统中后,再也没有出现在公司的分销中心。原来这些订单被赋予了错误的格式,因而无法被转化为正确的目标格式,但是iWay并没有向任何人通报这一点。
“这简直是大海捞针,我们需要提高系统的透明度。”盖兰特回忆说。他最终找到了解决办法,即当订单被挂起在“重试”队列中时,系统会给管理员发送消息。
拜里用这个办法识别那些面向客户的服务,再将这些服务隔离开来,然后用iWay在这些服务间实现数据转换。最后,在6个月的期限结束时,客户使用的已经是完全集成的系统了。
方法之二
并非每个人都热衷于采用iWay系统来集成来自不同服务的数据。“我一直对此心存疑虑。” ZapThink的施麦尔泽尔表示,因为它与以往的应用软件集成非常相近,这种方式需要单独为每组应用软件建立连接,而且不够灵活。
服务需要被重新构建,以使其产生的数据可用于不同的应用软件,而iWay的Service Manager仅可以完成大部分工作,而非全部。公司还要在不改变服务界面的情况下,改变表现数据的方式。但是,iWay系统通常要求对每个数据表现都提供一个界面,而无法生成可被所有数据表现轻易采用的数据。
还有一种集成Web服务数据的办法,那就是利用开源和专有产品。开源数据集成工具Jitterbit可以接收应用软件信息,将之转换为XML格式,再在Web上绘制出来并递送到目标系统。它有赖于Web标准,并且需要具备在不同系统间转换数据的能力。Apatar公司和Talend公司也拥有类似的开源产品。DataDirect公司和 MetaMatrix公司则拥有专有系统,而红帽公司(Red Hat)现正准备收购MetaMatrix,后者的产品也将成为开源系统JBoss的组成部分。
计算机辅助设计和工程软件厂商欧特克公司(AutoDesk)目前在对开源Apatar软件进行评估。欧特克还以软件作为服务(SaaS)的形式提供协作施工项目管理,通过门户网站集成数据,以供参与同一项目的承包商使用。重要的施工项目可以包括40家甚至更多的承包商。
欧特克在自己的产品中将Apatar软件作为集成代理,公司协作项目管理部门技术服务经理杰森·普拉特(Jason Pratt)介绍说。Apatar能在系统间转换数据,并利用Web服务将数据输出给业务合作伙伴。它能在不同的系统间执行提取、转换、以及上载等功能,以使两家彼此尚未建立P2P连接的公司能够共享数据。而且,与定制的P2P连接不同,Apatar连接代码依赖于Web标准,因此无需测试即可确保能够有效使用,Apatar创始人兼首席执行官(CEO)雷纳特·卡桑辛(Renat Khasanshyn)补充道。
利用欧特克服务提供的数据转换,一家承包商的JD Edwards会计系统可将数据输出到另一家承包商的调度系统,这样施工项目的不同方面就可以按时执行并完成了。
Apatar系统“为所有数据提供了管道,从一个系统通向另一个系统的管道,就像乐高(Legos)玩具一样。”普拉特概括道。在无需构建中间件的前提下,这种办法可以提升灵活性,确实很了不起。
现在该轮到你来选择了。iWay和其他厂商能提供通向服务世界的合适的P2P连接;而开源产品现在已能在更高的水平上将源自不同服务的数据集成起来。不管你选择哪个方法,距离成功部署SOA,你又向前跨了一步。
1:在数据服务端安装好mysql数据库,这个是必须的,在自己的ssh或者虚拟机上,数据mysql可以看到相关的提示,说明安装成功:
2:我是用的是tomcat服务器,在这里需要安装好java连接mysql的数据库操作库。我是用的jar包是:mysql-connector-java-3.1.14.tar.gz,
大家可以在网上下载,或者,在官网上下载:
3:把解包后的jar放到tomcat里面的lib文件夹下:
4:在程序的代码段里添加连接函数库和库函数,就可以连接到mysql数据库了:
5:剩下的就是我们使用的时候调用这样的数据了,在jsp里使用mysql数据库中的数据: