一、环境配置
需要的安装jar包:
一共要下载四个软件包,它们都是开源免费的。其中,前两个是Apache的,后两个是SUN网站,如下所示:
一共要下载四个软件包,它们都是开源免费的。其中,前两个是Apache的,后两个是SUN网站,如下所示:
下载后的版本是:JAF1.0.2 + JavaMail 1.3.2 + SOAP2.3.1 + Xerces1.4.4。
1、因为本机已经安装JDK和Tomcat,所以安装不再细述。
2、分别在这四个包的解压目录中找到:xerces.jar、soap.jar、mail.jar、activation.jar(jaf的),将它们复制到Tomcat的“Tomcat 5.0/common/lib”目录下,这个目录是Tomcat的默认包目录,在这个目录中的所有包在Tomcat启动时都会被自动加载。
3、将c:/jdk/lib/路径下的tools.jar也复制到Tomcat的“Tomcat 5.0/common/lib”目录下。
注:在显示SOAP的管理页面需要用到这个包,设置classpath指向c:/jdk/lib/tools.jar是没有用的,所以需要将他放到Tomcat 5.0/common/lib目录下。
4、将soap解压目录的webapps目录下的soap.war文件,复制到Tomcat的“Tomcat 5.0/webapps”目录下,这个目录是Tomcat的WEB应用所在目录,soap.war是SOAP的网站。
5、启动Tomcat服务,可以通过“http://localhost:8080/soap/”查看SOAP。
二、编写SOAP程序
编写SOAP程序分三大步:
编写SOAP程序分三大步:
1)、编写服务器端的程序,此程序和普通程序没有什么区别
2)、配置SOAP,将相关请求指向到服务器端的程序
3)、编写客户端的程序,客户端的程序带有很深的SOAP的烙印,里面会用到很多SOAP包的类和方法。
1、编写服务器和客户端程序:
SimpleMathString.java是服务器端的程序,其代码如下。这个程序中有两个方法,和普通程序类似,
一个返回double类型,一个返回字符串类型。
package test;
public class SimpleMathString
{
public double getSinValue(double input)
{
double ret = Math.sin(input);
return ret;
}
public String getName(String str)
{
return "Hello "+str;
}
}
SimpleMathString.java是服务器端的程序,其代码如下。这个程序中有两个方法,和普通程序类似,
一个返回double类型,一个返回字符串类型。
package test;
public class SimpleMathString
{
public double getSinValue(double input)
{
double ret = Math.sin(input);
return ret;
}
public String getName(String str)
{
return "Hello "+str;
}
}
SimpleMathStringClient.java是客户端访问程序
package test;
package test;
import java.io.*;
import java.net.*;
import java.util.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
import java.net.*;
import java.util.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.rpc.*;
public class SimpleMathStringClient {
public static void main(String[] args) throws Exception {
System.err.println("SOAP call testing");
double value = Math.random();
SimpleMathStringClient smc = new SimpleMathStringClient();
// 调用远程的SOAP服务
double returnValue = smc.doRequest(value);
System.err.println("the sin value of " + value + "is: " + returnValue);
String str = smc.doRequest("liujinmei");
System.err.println("字符串是: " + str);
}
public static void main(String[] args) throws Exception {
System.err.println("SOAP call testing");
double value = Math.random();
SimpleMathStringClient smc = new SimpleMathStringClient();
// 调用远程的SOAP服务
double returnValue = smc.doRequest(value);
System.err.println("the sin value of " + value + "is: " + returnValue);
String str = smc.doRequest("liujinmei");
System.err.println("字符串是: " + str);
}
public double doRequest(double value) throws Exception {
// Build the call.
Call call = new Call();
// 设置远程对象的URI
call.setTargetObjectURI("urn:test.math.sin");
// 设置调用的方法名
call.setMethodName("getSinValue");
// 设置编码风格
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
// 设置方法调用的参数
Vector params = new Vector();
params.addElement(new Parameter("input", double.class,
new Double(value), null));
call.setParams(params);
// 发送RPC请求
Response resp = call.invoke(new URL(" http://127.0.0.1:8080/soap/servlet/rpcrouter"), "");
if (resp.generatedFault()) { // 远程调用出错处理
Fault fault = resp.getFault();
System.out.println("the call failed: ");
System.out.println(" Fault Code = " + fault.getFaultCode());
System.out.println(" Fault String = " + fault.getFaultString());
return 0.0d;
} else { // 调用成功,获取返回值
Parameter result = resp.getReturnValue();
return ((Double) result.getValue()).doubleValue();
}
}
public String doRequest(String str) throws Exception {
// Build the call.
Call call = new Call();
// 设置远程对象的URI
call.setTargetObjectURI("urn:HelloName");
// 设置调用的方法名
call.setMethodName("getName");
// 设置编码风格
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
// 设置方法调用的参数
Vector params = new Vector();
params.addElement(new Parameter("name", String.class,
str, null));
call.setParams(params);
// 发送RPC请求
Response resp = call.invoke(new URL(" http://127.0.0.1:8080/soap/servlet/rpcrouter"), "");
if (resp.generatedFault()) { // 远程调用出错处理
Fault fault = resp.getFault();
System.out.println("the call failed: ");
System.out.println(" Fault Code = " + fault.getFaultCode());
System.out.println(" Fault String = " + fault.getFaultString());
return "error";
} else { // 调用成功,获取返回值
Parameter result = resp.getReturnValue();
return result.getValue().toString();
}
}
}
// Build the call.
Call call = new Call();
// 设置远程对象的URI
call.setTargetObjectURI("urn:test.math.sin");
// 设置调用的方法名
call.setMethodName("getSinValue");
// 设置编码风格
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
// 设置方法调用的参数
Vector params = new Vector();
params.addElement(new Parameter("input", double.class,
new Double(value), null));
call.setParams(params);
// 发送RPC请求
Response resp = call.invoke(new URL(" http://127.0.0.1:8080/soap/servlet/rpcrouter"), "");
if (resp.generatedFault()) { // 远程调用出错处理
Fault fault = resp.getFault();
System.out.println("the call failed: ");
System.out.println(" Fault Code = " + fault.getFaultCode());
System.out.println(" Fault String = " + fault.getFaultString());
return 0.0d;
} else { // 调用成功,获取返回值
Parameter result = resp.getReturnValue();
return ((Double) result.getValue()).doubleValue();
}
}
public String doRequest(String str) throws Exception {
// Build the call.
Call call = new Call();
// 设置远程对象的URI
call.setTargetObjectURI("urn:HelloName");
// 设置调用的方法名
call.setMethodName("getName");
// 设置编码风格
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
// 设置方法调用的参数
Vector params = new Vector();
params.addElement(new Parameter("name", String.class,
str, null));
call.setParams(params);
// 发送RPC请求
Response resp = call.invoke(new URL(" http://127.0.0.1:8080/soap/servlet/rpcrouter"), "");
if (resp.generatedFault()) { // 远程调用出错处理
Fault fault = resp.getFault();
System.out.println("the call failed: ");
System.out.println(" Fault Code = " + fault.getFaultCode());
System.out.println(" Fault String = " + fault.getFaultString());
return "error";
} else { // 调用成功,获取返回值
Parameter result = resp.getReturnValue();
return result.getValue().toString();
}
}
}
2、将服务端程序SimpleMathString.java的编译文件SimpleMathString.class复制到Tomact中。
在“Tomcat 5.0/common/classes/”路径下新建一个“test”目录结构,这个目录结构要和SimpleMathString.class的所在包名一样的,然后将SimpleMathString.class复制到此目录下。
注意:还有一种方法是比较普遍使用的,就是将所有服务器端的class文件打成一个JAR包,然后将这个JAR包放在“Tomcat 5.0/common/lib”目录下。
3、发布SOAP服务器端的程序:SimpleMathString.java
发布服务器端程序必须设置好两个环境变量,是因为发布命令的需要
TOMCAT_HOME = D:/Tomcat 5.0
在“Tomcat 5.0/common/classes/”路径下新建一个“test”目录结构,这个目录结构要和SimpleMathString.class的所在包名一样的,然后将SimpleMathString.class复制到此目录下。
注意:还有一种方法是比较普遍使用的,就是将所有服务器端的class文件打成一个JAR包,然后将这个JAR包放在“Tomcat 5.0/common/lib”目录下。
3、发布SOAP服务器端的程序:SimpleMathString.java
发布服务器端程序必须设置好两个环境变量,是因为发布命令的需要
TOMCAT_HOME = D:/Tomcat 5.0
classpath = %TOMCAT_HOME%/common/lib/soap.jar;%TOMCAT_HOME%/common/lib
/mail.jar;%TOMCAT_HOME%/common/lib/activation.jar;%TOMCAT_HOME%/common/lib/xerces.jar
/mail.jar;%TOMCAT_HOME%/common/lib/activation.jar;%TOMCAT_HOME%/common/lib/xerces.jar
就我所知有两中方法可以发布SOAP服务器端的程序:
(一)编写XML文件来注册SOAP服务的方法
1)、SimpleMathString.xml文件。此文件可以放置到任何地方,它和SimpleMathString.java的位置没有必然的关系。
(一)编写XML文件来注册SOAP服务的方法
1)、SimpleMathString.xml文件。此文件可以放置到任何地方,它和SimpleMathString.java的位置没有必然的关系。
<?xml version='1.0'?>
<isd:service xmlns:isd='http://xml.apache.org/xml-soap/deployment' id='urn:test.math.sin'>
<isd:provider type='java' scope='Request' methods='getSinValue'>
<isd:java class='test.SimpleMathString' static='false'/>
</isd:provider>
</isd:service>
代码说明:
urn:test.math.sin是服务名,它要求系统唯一。
getSinValue是提供的服务方法,也就是类服务端程序的方法名(如果同时发布多个方法的话,可以用空格格开,如getName getgetSinValue)
<isd:java class=要求填入全类名(包名+类名)
2)、进入DOS窗口,并定位到SimpleMathString.xml所在的目录,然后运行如下命令(一行)。如果执行正确,则应该没有任何显示;如果命令错误则会输出错误信息。
java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter deploy SimpleMathString.xml
java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter deploy SimpleMathString.xml
另外两个常用命令:
a、显示已经注册的SOAP服务:
a、显示已经注册的SOAP服务:
java org.apache.soap.server.ServiceManagerClient
http://127.0.0.1:8080/soap/servlet/rpcrouter list
b、取消发布:
java org.apache.soap.server.ServiceManagerClient
http://127.0.0.1:8080/soap/servlet/rpcrouter undeploy 'urn:test.math.sin'
c、还可以查询服务属性:
java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter query urn:test.math.sin
(二)进入SOAP网站的去发布,查看和取消
使用IE浏览器浏览 http://localhost:8080/soap/admin/index.html,进入Deploy,填写如下信息:
ID: urn:HelloName
Scope: Request
Methods getName (如果同时发布多个方法的话,可以用空格格开,如getName getgetSinValue)
Provider Type: Java
Java Provider Provider Class: test.SimpleMathString
Java Provider Static: NO
确认发布
另外可以点List查看已发布服务,也可以点Un-deploy删除已发布的服务
java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter query urn:test.math.sin
(二)进入SOAP网站的去发布,查看和取消
使用IE浏览器浏览 http://localhost:8080/soap/admin/index.html,进入Deploy,填写如下信息:
ID: urn:HelloName
Scope: Request
Methods getName (如果同时发布多个方法的话,可以用空格格开,如getName getgetSinValue)
Provider Type: Java
Java Provider Provider Class: test.SimpleMathString
Java Provider Static: NO
确认发布
另外可以点List查看已发布服务,也可以点Un-deploy删除已发布的服务
4、运行客户端程序,向普通应用程序那样运行就可以。
遇到的问题:
查看已发布服务:
java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter list
时提示:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/soap/server/ServiceManagerClien
查看已发布服务:
java org.apache.soap.server.ServiceManagerClient http://127.0.0.1:8080/soap/servlet/rpcrouter list
时提示:Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/soap/server/ServiceManagerClien
解决问题:确保classpath变量已经添加了四个jar文件,并且版本正确
其他资料:
apache soap 网址是
http://xml.apache.org/soap 提供java的soap工具箱
IBM SOAP4J IBM的soap实现。
微软的soap只支持com一类的对象,不支持java,如果要与com或vb组件通信,强烈推荐下载微软的soap工具包,网址为
http://msdn.microsoft.com/library/defaule.asp?url=/nhp/Default.asp?contentid=28000523,还有许多其它soap资源
Axis 是下一代soap工具包,也是在Apache XML大旗下开发的。此项目是由SAX,而Apache SOAP则基于DOM,而且,Axis在Apache SOAP中忽略的首部交互上提供了更易用的方式。
TrackFrom:
http://blog.sina.com.cn/u/4b2fd935010006po