从技术的角度来说Q有必要提一下我们的调试环境。我们用的?a target="_blank">Windows XP操作pȝ Q安装有JAVA 2 SDK 1.4.1QApache SOAP 2.3.1QJAF 1.0.2Q?a target="_blank">JavaMail 1.3.1和Xerces 2.6.0。上面所提及的都能在Tcomcat 4.1.29 JSP /Servlet 容器中正常运行。所有的软g都是免费自由软gQ因此你能够很容易的下蝲 它们q自己在M你喜Ƣ的q_如Windows或UNIX上安装它们。Java SDKQJAF和JAVAMAIL位于SUN的官方网站( http://java.sun.com Q,其他的Y件在Jakarta目l的官方|站Q?/span> http://jakarta.apache.org Q上有down的。可能你在看到我们需要这么多不同的包QpackageQ时已经有点担心和不安了Q但是实际上你不应该担心q些的。一旦你懂了基础Q那么对你将相当Ҏ。安装不是一件很隄事情Q你只需要在讄环境变量的时候仔l些Q比?em>CATALINA_HOME , CLASSPATH , JAVA_HOME {等Q所有这些步骤都是手工的。由于我仅仅是想你的注意力再次集中到它们n上,所以你能很快的完成以上配|过E。我只是d下面的一些字W串到Tomcat?em>bin/setclasspath.bat 文g中:
... 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 ...
如果你的安装路径Qinstallation pathsQ和上面使用的不同,你需要更正它们,然后关闭和重启Tomcat以它们生效。这P你就有ؓq行SOAP作好了准备。但是现在,我要忘记有关的技术部分,来学一点理论知识?/span>
SOAP意思是单对象访问协议(S imple O bject A ccess P rotocolQ。的如它的名字一PSOAP是很单的。它是一个基于XML的协议,允许E序lg和应用程序彼此用一U标准的Internet协议 --HTTP来通讯。SOAP是一U独立的q_Q它不依赖程序语aQ它是简单的Q弹性的Q很Ҏ扩展的。目前,应用E序能够彼此使用一U基于DCOM? CORBA技术的q程q程调用QRPCQ来q行怺通讯Q但HTTP不被设计个目的。RPC在Internet上应用是非常困难的,它们会出现许多兼 Ҏ和安全性的问题Q因?a target="_blank">防火?/span> 和代?a target="_blank">服务?/span> 通常都会LQblockQ这些类型的量。应用程序之间最好的通讯方式是通过HTTP协议Q因为HTTP是支持所有Internet览器和服务器的。基于这个目的,SOAP协议被创建出来?/span>
那么Q它们是如何q作的呢Q比如,一个应用程序(AQ需要和另一个应用程序(BQ在SOAP的帮助下q行彼此通讯。它们将使用下面的框架图来完成这个过E:
q个SOAP信封QSOAP envelopeQ是一个包含以下内容的XML文档Q?/span>
正如你看到的Q它是非常简单的。它看v来确实就象一个普通的信封或者你? email。你想看看它们是如何动作的吗Q下面跟我们一h吧。其实我们有很多Ҏ是不用SOAP来在创徏和运行我们自q“Hello World”应用E序的,但是因ؓ我们要保持它的简单性,我会l你一个它q作方式的框架图QschemeQ?/span>
我们?#8220;Hello World”范例会包含一个SOAP Service。我们的SOAP Client发送它们的名字到该SOAP ServiceQƈ试图得到一些答复或响应。这个SOAP Service需要部|到一个SOAP Admin的工P以至重定位所有请求的SOAPQProxyQ?RPC Router能够知道它们应该使用哪种服务来运作。总而言之,q个是以下面的方式来q作的:
现在Q我们来一步步的看看到底发生了什么。在Step 1里,HelloWorldClient连接一个SOAP RPC RouterQ请求我们的SOAP Serviceq将包含我们名字的一个字W串传递给它。该SOAP RPC Router会检查是否它已经部v了这个SOAP Service。如果它被发现是被部|的Q那么它传递数据到q个SOAP Serviceq调用特定的ҎQ这个是Step 2。然后SOAP ServiceҎ会被执行Q将q回某个字符串|该值就是SOAP Client的答复或者响应)QStep 3Q。在Step4中,SOAP RPC Router仅仅只是重定向q个数据到SOAP Client。所有在Step1和Step4里传输的数据是通过SOAP Envelope来完成的。正如你所看到的,法是相当简单的Q因此我们只准备兛_实际的代码?/span>
首先Q我们要创徏一个SOAP Service。下面是它的代码Q请不要忘记它攑օHelloWorld/ 目录中(必须被包含在你的CLASSPATH中)Q?/span>
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: }
dM注释也是很容易的。要~译它,只需要用下列命oQ?/span>
javac SOAPService.java
W二步,一旦我们准备好了SOAP ServiceQ我们需要用SOAP Service Manager来部|它。这个可以通过很多方式来实玎ͼ但是Z能让初学SOAP的读者更Ҏ理解SOAPQ我提供了一个最Ҏ的方式。我们假设你?a target="_blank">Web ServerQTomcat或其他)已经正常q行Qƈ且你已经正确安装了SOAP。那么当览器访?/span> http://localhost:8080/soap/ Q你会看见Apache SOAP的欢q页面。点?em>Run the admin client Q然?Deploy ?你会得到一个屏q显C,在那里你需要填入IDQScopeQMethodQProvider 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提供的一pdҎ。JAVA Provider-Provider Class是SOAP Service Javacȝ名字?/span>
现在Q点?em>Deploy 按钮Q那么你的服务会被部|Ӏ再ơ强调,h意正设|CLASSPATH环境变量。然后,你的HelloWorld.SOAPServicec能够被扑ֈQƈ且所有必需的jar包也能被扑ֈ。这是个几乎每个人都会犯的普通错误。现在,你能够点?List Q将会看见你的服务已l被部vq来。恭喜!
最后,让我们来创徏一个SOAP Client。代码看h有点复杂Q但是在现实中不会只有这么点ѝ?/span>
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 ourName = "Superman"; 14: String ourUrn = "urn:HelloWorld_SOAPService"; 15: String ourMethod = "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:}
下面我要做一些解释。在W?3行,我们讄了我们的名字Q这个名字将会传递给 SOAP Service。在W?4行,我们讄了我们将要调用的服务的IDQservice IDQ,和第15行里讄的服务方法(service methodQ。有了这个IDQ服务能够被部v到SOAP服务理器(SOAP Service ManagerQ中。我们没有设|Q何其他|仅仅只用刚才那些基础值就可以正常q作了。你能从SOAP的官Ҏ档上得到相关信息Q该文档来自SOAP?中,它们的解释超Z本文的范围?/span>
用以下方式编译这个SOAP ClientQ?/span>
javac HelloWorldClient.java
Z圆满完成它,让我们检查一下针Ҏ们的试Q是否所有事情都准备qA。Tomcat正在q行Q所有的环境变量都正,SOAP Service被编译和部vQSOAP Client被成功编译。OKQ让我们q行它,你将看到q个屏幕Q?/span>
正如你所看到的,我们的SOAP Client使用SOAP协议成功发送它的名字和接收了一个答复。正如前面所说的QSOAP Service发送和接收的是SOAP envelope。这个是SOAP envelope的源代码?/span>
?strong>发?/strong> 到SOAP Service的SOAP Envelope
<?XML version='1.0' encoding='UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/ soap/envelope/" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:sayHi xmlns:ns1="urn:HelloWorld_SOAPService" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/ soap/encoding/"> <ourName xsi:type="xsd:string">Superman</ourName> </ns1:sayHi> </SOAP-ENV:Body> </SOAP-ENV:Envelope>:
从SOAP Service接收 的SOAP Envelope
<?xml version='1.0' encoding='UTF-8'?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/ soap/envelope/" xmlns:xsi="http://www.w3.org/2001/ XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <SOAP-ENV:Body> <ns1:sayHiResponse xmlns:ns1="urn:HelloWorld_SOAPService" SOAP-ENV:encodingStyle="http://schemas.xmlsoap. org/soap/encoding/"> <return xsi:type="xsd:string">Hello my friend, Superman! Glad to see you!</return> </ns1:sayHiResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>
要理解SOAP Envelope中的所有标{含义Q我你花一Ҏ间阅?http://www.w3.org/2001/06/soap-envelope 命名I间规范?/span>
我希望本文能够在你理解SOAP技术上有一定帮助。这个技术是单的Q有的Q强大的Q弹性的。它被用在许多Web应用中,q些应用的数量也在不断增加。学习SOAP是值得的,臛_你要知道它是什么和它是怎么q作?/span>