TOMCAT中的SOAP简单应用
SOAP的主页:http://ws.apache.org/soap/
SOAP RPC 的工作原理非常类似于WEB的请求/响应方式,两者都以HTTP作为通信协议,不同之处在于WEB客户和WEB服务器之间传输的是HTML数据,而在SOAP RPC模式中,SOAP客户和服务之间传输的是符合SOAP规范的XML数据。本文通过一个简单的SOAP应用来说明SOAP RPC的工作方式。
在Eclipse里面创建SOAP工程,把从SOAP主页上下载到的SOAP分发版本中的webapps/soap/目录中的文件拷贝过来,再把mail.jar/activation.jar/soap.jar拷贝到WEB-INF/lib/目录下。(mail.jar和activation.jar请在SUN网站上找,soap.jar在SOAP分发版本的lib目录中)
目录结构如下:
?
soap/
|--src/
| |--org.eleaf.soap/
| |--HelloClient.java
| |--HelloService.java
|--WebRoot/
|--admin/
|--META-INF/
|--WEB-INF/
|--DeploymentDescriptor.xml
|--web.xml
|--lib/
|--soap.jar
|--mail.jar
|--activation.jar
在TOMCAT的conf/server.xml文件中添加一个名为soap的Context标记:
?
<Context path="/soap" docBase="D:\work\eclipse\soap\WebRoot" workDir="D:\work\eclipse\soap\j2src" reloadable="true" debug="0"/>
</Host>
……
然后启动TOMCAT,访问http://jim:4001/soap/,可以看到SOAP的控制页面:
?
<!--StartFragment -->Apache-SOAP
Hello! Welcome to Apache-SOAP.
What do you want to do today?
Run the admin client Visit the SOAP RPC router URL for this SOAP serverApache-SOAPHello! Welcome to Apache-SOAP.
What do you want to do today?
Run the admin client Visit the SOAP RPC router URL for this SOAP serverSOAP服务器端程序:包含三个可供客户端调用的方法。
package org.eleaf.soap;
import java.util.Date;
public class HelloService {
public String sayHello(String username)
{
return "Hello:" + username;
}
public Date getDate()
{
return new Date();
}
public int sum(int i, int j)
{
return i+j;
}
}
SOAP服务配置文件:DeploymentDescriptor.xml:
?
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
D:\work\eclipse\soap\WebRoot\WEB-INF>set classpath=%classpath%;D:\jakarta-tomcat
-5.0.28\shared\lib\activation.jar;D:\jakarta-tomcat-5.0.28\shared\lib\mail.jar;D
:\work\eclipse\soap\WebRoot\WEB-INF\lib\soap.jar
D:\work\eclipse\soap\WebRoot\WEB-INF>
发布SOAP服务:
?
D:\work\eclipse\soap\WebRoot\WEB-INF>java org.apache.soap.server.ServiceManagerC
lient http://jim:4001/soap/servlet/rpcrouter deploy DeploymentDescriptor.xml
D:\work\eclipse\soap\WebRoot\WEB-INF>
查看已发布的SOAP服务:
?
?
D:\work\eclipse\soap\WebRoot\WEB-INF>java org.apache.soap.server.ServiceManagerC
lient http://jim:4001/soap/servlet/rpcrouter list
Deployed Services:
urn:helloservice
D:\work\eclipse\soap\WebRoot\WEB-INF>
编写客户端调用程序:该类将通过SOAP发出RPC请求,来调用服务器端的三个方法。
?
package org.eleaf.soap;
import java.net.URL;
import java.util.Vector;
import org.apache.soap.Constants;
import org.apache.soap.Fault;
import org.apache.soap.rpc.Call;
import org.apache.soap.rpc.Parameter;
import org.apache.soap.rpc.Response;
public class HelloClient {
/**
* @param args
*/
public static void main(String[] args) throws Exception{
URL url = new URL("http://jim:4001/soap/servlet/rpcrouter");
Call call = new Call();
call.setTargetObjectURI("urn:helloservice");
call.setMethodName("sayHello");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
Vector params = new Vector();
params.addElement(new Parameter("username", String.class, "bitan", null));
call.setParams(params);
Response resp = call.invoke(url, "");
if (resp.generatedFault())
{
Fault fault = resp.getFault();
System.out.println("[code:" + fault.getFaultCode() +
"];[description:" + fault.getFaultString() + "]");
}
else
{
Parameter result = resp.getReturnValue();
System.out.println("[value:" + result.getValue() + "];[name:" +
result.getName() + "];[class:" + result.getClass() +
"];[type:" + result.getType() + "];[encoding:" +
result.getEncodingStyleURI() + "]");
}
call.setMethodName("getDate");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
call.setParams(null);
resp = call.invoke(url, "");
if (resp.generatedFault())
{
Fault fault = resp.getFault();
System.out.println("[code:" + fault.getFaultCode() +
"];[description:" + fault.getFaultString() + "]");
}
else
{
Parameter result = resp.getReturnValue();
System.out.println("[value:" + result.getValue() + "];[name:" +
result.getName() + "];[class:" + result.getClass() +
"];[type:" + result.getType() + "];[encoding:" +
result.getEncodingStyleURI() + "]");
}
call.setMethodName("sum");
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
params = new Vector();
params.addElement(new Parameter("i", int.class, new Integer(24), null));
params.addElement(new Parameter("j", int.class, new Integer(37), null));
call.setParams(params);
resp = call.invoke(url, "");
if (resp.generatedFault())
{
Fault fault = resp.getFault();
System.out.println("[code:" + fault.getFaultCode() +
"];[description:" + fault.getFaultString() + "]");
}
else
{
Parameter result = resp.getReturnValue();
System.out.println("[value:" + result.getValue() + "];[name:" +
result.getName() + "];[class:" + result.getClass() +
"];[type:" + result.getType() + "];[encoding:" +
result.getEncodingStyleURI() + "]");
}
}
}
执行结果:
?
D:\work\eclipse\soap\WebRoot\WEB-INF\classes>java org.eleaf.soap.HelloClient
[value:Hello:bitan];[name:return];[class:class org.apache.soap.rpc.Parameter];[t
ype:class java.lang.String];[encoding:null]
[value:Wed Oct 19 14:32:29 CST 2005];[name:return];[class:class org.apache.soap.
rpc.Parameter];[type:class java.util.Date];[encoding:null]
[value:61];[name:return];[class:class org.apache.soap.rpc.Parameter];[type:int];
[encoding:null]
D:\work\eclipse\soap\WebRoot\WEB-INF\classes>
删除已发布的SOAP服务:
?
D:\work\eclipse\soap\WebRoot\WEB-INF>java org.apache.soap.server.ServiceManagerC
lient http://jim:4001/soap/servlet/rpcrouter undeploy urn:helloservice
D:\work\eclipse\soap\WebRoot\WEB-INF>java org.apache.soap.server.ServiceManagerC
lient http://jim:4001/soap/servlet/rpcrouter list
Deployed Services:
D:\work\eclipse\soap\WebRoot\WEB-INF>
再次调用客户程序,由于服务已被删除,客户端再次调用时返回错误代码:
?
D:\work\eclipse\soap\WebRoot\WEB-INF>cd classes
D:\work\eclipse\soap\WebRoot\WEB-INF\classes>java org.eleaf.soap.HelloClient
[code:SOAP-ENV:Server];[description:service 'urn:helloservice' unknown]
[code:SOAP-ENV:Server];[description:service 'urn:helloservice' unknown]
[code:SOAP-ENV:Server];[description:service 'urn:helloservice' unknown]
D:\work\eclipse\soap\WebRoot\WEB-INF\classes>