CSDN - 專家門診 - Java J2SE / 基礎(chǔ)類問(wèn)題
回復(fù)人: panq(漫隨天外) ( ) 信譽(yù):100 2001-10-25 13:40:12Z 得分:300
簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議(SOAP):
用于Internet上的分布式計(jì)算,可以實(shí)現(xiàn)跨平臺(tái)跨編程語(yǔ)言的對(duì)象訪問(wèn)和方法調(diào)用.
它通過(guò)HTTP協(xié)議實(shí)現(xiàn)參數(shù)的傳輸,同時(shí)以特定的XML格式表示參數(shù).這樣,只需要一個(gè)支持H
TTP協(xié)議的WEB服務(wù)器和一個(gè)XML解析器就可以實(shí)現(xiàn)簡(jiǎn)單的SOAP功能.由于成為了標(biāo)準(zhǔn),所以
會(huì)有越來(lái)越多的軟件支持它.大家若有興趣的話可以去看SOAP1.1標(biāo)準(zhǔn).
同時(shí),還有許多SOAP的開(kāi)發(fā)工具,以簡(jiǎn)化SOAP的開(kāi)發(fā).隨著這些開(kāi)發(fā)工具的完善,我們
甚至可以不用管具體的SOAP格式就可以開(kāi)發(fā)SOAP應(yīng)用.
下面以APACHE的SOAP包為例,舉個(gè)例子:
服務(wù)器端的Class:
package samples.soap;
public class SOAPCal {
double rate;
public SOAPCal() {
rate = 8.7;
}
public void setRate(double rate) {
this.rate = rate;
}
public Double calculate(int direction, double value) {
Double retVal;
switch(direction) {
case 0:
retVal = new Double(value * rate);
break;
case 1:
retVal = new Double(value / rate);
break;
default:
retVal = null;
}
return retVal;
}
}
客戶端Class:
package samples.soap;
import java.io.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class SOAPCalUser {
public static void main(String[] args) throws Exception {
if (args.length != 3
&& (args.length != 4 || !args[0].startsWith("-"))) {
System.err.println("Usage:");
System.err.println(" java " + SOAPCalUser.class.getName() +
" [-encodingStyleURI] SOAP-router-URL name " +
"(0: dollor to yuan | 1: yuan to dollor) value");
System.exit (1);
}
int offset = 4 - args.length;
String encodingStyleURI = args.length == 11
? args[0].substring(1)
: Constants.NS_URI_SOAP_ENC;
URL url = new URL(args[1 - offset]);
int direction = Integer.parseInt(args[2 - offset]);
double value = Double.parseDouble(args[3 - offset]);
Call call = new Call();
call.setTargetObjectURI("urn:SOAPCal");
call.setMethodName("calculate");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector();
params.add(new Parameter("direction", int.class, new
Integer(direction), null));
params.add(new Parameter("value", double.class, new Double(value),
null));
call.setParams(params);
Response resp;
try {
resp = call.invoke(url, "");
} catch (SOAPException e) {
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
// Check the response.
if (!resp.generatedFault()) {
Parameter ret = resp.getReturnValue();
Object retVal = ret.getValue();
System.out.println(retVal != null ? "\n" + retVal : "I don't
know.");
} else {
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code = " +
fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
}
和
package samples.soap;
import java.io.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class SOAPCalAdmin {
public static void main(String[] args) throws Exception {
if (args.length != 2
&& (args.length != 3 || !args[0].startsWith("-"))) {
System.err.println("Usage:");
System.err.println(" java " + SOAPCalAdmin.class.getName()
+ " [-encodingStyleURI] SOAP-router-URL name " +
"rate ");
System.exit (1);
}
int offset = 3 - args.length;
String encodingStyleURI = args.length == 11
? args[0].substring(1)
: Constants.NS_URI_SOAP_ENC;
URL url = new URL(args[1 - offset]);
double rate = Double.parseDouble(args[2 - offset]);
Call call = new Call();
call.setTargetObjectURI("urn:SOAPCal");
call.setMethodName("setRate");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector();
params.add(new Parameter("rate", double.class, new Double(rate),
null));
call.setParams(params);
Response resp;
try {
resp = call.invoke(url, "");
} catch (SOAPException e) {
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
// Check the response.
if (!resp.generatedFault()) {
System.out.println("The rate has been changed.");
} else {
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code = " +
fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
}
發(fā)布用的XML文件dd.xml:
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:SOAPCal">
<isd:provider type="java"
scope="Application"
methods="setRate calculate">
<isd:java class="samples.soap.SOAPCal"/>
</isd:provider>
</isd:service>
這個(gè)程序的功能是設(shè)置和計(jì)算美元/人民幣的兌換價(jià)格,用
java org.apache.soap.server.ServiceManagerClient
http://sb3server:8080/soap/servlet/rpcrouter deploy dd.xml
把服務(wù)器端程序發(fā)布到TOMCAT上,然后在客戶端用:
java samples.soap.SOAPCalAdmin http://sb3server:8080/soap/servlet/rpcrouter
XX.XX
來(lái)設(shè)置匯率(1美元兌換多少人民幣), 用
java samples.soap.SOAPCalUser http://sb3server:8080/soap/servlet/rpcrouter
(1|0) XX.XX
來(lái)?yè)Q算,其中1和0代表從人民幣到美元和從美元到人民幣,下一個(gè)參數(shù)是要換算的錢數(shù).
另外,在http://www.xmethods.com/gettingstarted/apache.html
有一個(gè)簡(jiǎn)單的教程介紹怎樣用APACHE的SOAP包寫SOAP客戶端程序.講解比較詳細(xì).
注意點(diǎn):
*如果SOAP傳回來(lái)的參數(shù)是一個(gè)CLASS,這個(gè)CALSS會(huì)被序列化(Serializer)為一段XML
代碼,在客戶端接這個(gè)CLASS時(shí),仍然需要一個(gè)同名CLASS,而且那些被傳遞過(guò)來(lái)的數(shù)據(jù)的SE
T和GET方法名和參數(shù)名要相同.如果是自定義的CLASS,就要做maping聲明.聲明方法見(jiàn)APA
CHE SOAP包的samples\addressbook\DeploymentDescriptor.xml文件中isd:mappings的
寫法.
在客戶端調(diào)用時(shí)要加上
SOAPMappingRegistry smr = new SOAPMappingRegistry();
BeanSerializer beanSer = new BeanSerializer();
smr.mapTypes(/*encodingStyle*/Constants.NS_URI_SOAP_ENC,
new QName(/*Namespace URI*/"urn:xml-soap-address-demo", /*Local
Part*/"address"),
/*Class type*/Address.class, /*java2XMLClassName*/beanSer,
/*xml2JavaClassName*/beanSer);
call.setSOAPMappingRegistry(smr);
*目前不是所有的CLASS都能被序列化,如Hashtable就不行,所以最好用簡(jiǎn)單的數(shù)據(jù)類
型,如String,String,Integer,Double及其數(shù)組來(lái)傳遞變量,對(duì)復(fù)雜的參數(shù),可以直接做成
XML Document傳遞(使用Constants.NS_URI_LITERAL_XML作為EncodingStyleURI),這樣就
省得客戶端專門做個(gè)CLASS來(lái)接參數(shù),也方便跨語(yǔ)言的調(diào)用.在使用APACHE的SOAP包時(shí),XML
Document在客戶端會(huì)被轉(zhuǎn)換為XML DOM的Element class.
現(xiàn)在唯一的方法是自己寫進(jìn)行序列化的程序,不過(guò)以后也許會(huì)有標(biāo)準(zhǔn)的序列化方法.
*CLASS被序列化時(shí)CLASS中的靜態(tài)的變量是不會(huì)被加入的來(lái)的,這一點(diǎn)要注意.
回復(fù)人: panq(漫隨天外) ( ) 信譽(yù):100 2001-10-25 13:40:12Z 得分:300
簡(jiǎn)單對(duì)象訪問(wèn)協(xié)議(SOAP):
用于Internet上的分布式計(jì)算,可以實(shí)現(xiàn)跨平臺(tái)跨編程語(yǔ)言的對(duì)象訪問(wèn)和方法調(diào)用.
它通過(guò)HTTP協(xié)議實(shí)現(xiàn)參數(shù)的傳輸,同時(shí)以特定的XML格式表示參數(shù).這樣,只需要一個(gè)支持H
TTP協(xié)議的WEB服務(wù)器和一個(gè)XML解析器就可以實(shí)現(xiàn)簡(jiǎn)單的SOAP功能.由于成為了標(biāo)準(zhǔn),所以
會(huì)有越來(lái)越多的軟件支持它.大家若有興趣的話可以去看SOAP1.1標(biāo)準(zhǔn).
同時(shí),還有許多SOAP的開(kāi)發(fā)工具,以簡(jiǎn)化SOAP的開(kāi)發(fā).隨著這些開(kāi)發(fā)工具的完善,我們
甚至可以不用管具體的SOAP格式就可以開(kāi)發(fā)SOAP應(yīng)用.
下面以APACHE的SOAP包為例,舉個(gè)例子:
服務(wù)器端的Class:
package samples.soap;
public class SOAPCal {
double rate;
public SOAPCal() {
rate = 8.7;
}
public void setRate(double rate) {
this.rate = rate;
}
public Double calculate(int direction, double value) {
Double retVal;
switch(direction) {
case 0:
retVal = new Double(value * rate);
break;
case 1:
retVal = new Double(value / rate);
break;
default:
retVal = null;
}
return retVal;
}
}
客戶端Class:
package samples.soap;
import java.io.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class SOAPCalUser {
public static void main(String[] args) throws Exception {
if (args.length != 3
&& (args.length != 4 || !args[0].startsWith("-"))) {
System.err.println("Usage:");
System.err.println(" java " + SOAPCalUser.class.getName() +
" [-encodingStyleURI] SOAP-router-URL name " +
"(0: dollor to yuan | 1: yuan to dollor) value");
System.exit (1);
}
int offset = 4 - args.length;
String encodingStyleURI = args.length == 11
? args[0].substring(1)
: Constants.NS_URI_SOAP_ENC;
URL url = new URL(args[1 - offset]);
int direction = Integer.parseInt(args[2 - offset]);
double value = Double.parseDouble(args[3 - offset]);
Call call = new Call();
call.setTargetObjectURI("urn:SOAPCal");
call.setMethodName("calculate");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector();
params.add(new Parameter("direction", int.class, new
Integer(direction), null));
params.add(new Parameter("value", double.class, new Double(value),
null));
call.setParams(params);
Response resp;
try {
resp = call.invoke(url, "");
} catch (SOAPException e) {
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
// Check the response.
if (!resp.generatedFault()) {
Parameter ret = resp.getReturnValue();
Object retVal = ret.getValue();
System.out.println(retVal != null ? "\n" + retVal : "I don't
know.");
} else {
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code = " +
fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
}
和
package samples.soap;
import java.io.*;
import java.util.*;
import java.net.*;
import org.w3c.dom.*;
import org.apache.soap.util.xml.*;
import org.apache.soap.*;
import org.apache.soap.encoding.*;
import org.apache.soap.encoding.soapenc.*;
import org.apache.soap.rpc.*;
public class SOAPCalAdmin {
public static void main(String[] args) throws Exception {
if (args.length != 2
&& (args.length != 3 || !args[0].startsWith("-"))) {
System.err.println("Usage:");
System.err.println(" java " + SOAPCalAdmin.class.getName()
+ " [-encodingStyleURI] SOAP-router-URL name " +
"rate ");
System.exit (1);
}
int offset = 3 - args.length;
String encodingStyleURI = args.length == 11
? args[0].substring(1)
: Constants.NS_URI_SOAP_ENC;
URL url = new URL(args[1 - offset]);
double rate = Double.parseDouble(args[2 - offset]);
Call call = new Call();
call.setTargetObjectURI("urn:SOAPCal");
call.setMethodName("setRate");
call.setEncodingStyleURI(encodingStyleURI);
Vector params = new Vector();
params.add(new Parameter("rate", double.class, new Double(rate),
null));
call.setParams(params);
Response resp;
try {
resp = call.invoke(url, "");
} catch (SOAPException e) {
System.err.println("Caught SOAPException (" +
e.getFaultCode() + "): " +
e.getMessage());
return;
}
// Check the response.
if (!resp.generatedFault()) {
System.out.println("The rate has been changed.");
} else {
Fault fault = resp.getFault();
System.err.println("Generated fault: ");
System.out.println (" Fault Code = " +
fault.getFaultCode());
System.out.println (" Fault String = " +
fault.getFaultString());
}
}
}
發(fā)布用的XML文件dd.xml:
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:SOAPCal">
<isd:provider type="java"
scope="Application"
methods="setRate calculate">
<isd:java class="samples.soap.SOAPCal"/>
</isd:provider>
</isd:service>
這個(gè)程序的功能是設(shè)置和計(jì)算美元/人民幣的兌換價(jià)格,用
java org.apache.soap.server.ServiceManagerClient
http://sb3server:8080/soap/servlet/rpcrouter deploy dd.xml
把服務(wù)器端程序發(fā)布到TOMCAT上,然后在客戶端用:
java samples.soap.SOAPCalAdmin http://sb3server:8080/soap/servlet/rpcrouter
XX.XX
來(lái)設(shè)置匯率(1美元兌換多少人民幣), 用
java samples.soap.SOAPCalUser http://sb3server:8080/soap/servlet/rpcrouter
(1|0) XX.XX
來(lái)?yè)Q算,其中1和0代表從人民幣到美元和從美元到人民幣,下一個(gè)參數(shù)是要換算的錢數(shù).
另外,在http://www.xmethods.com/gettingstarted/apache.html
有一個(gè)簡(jiǎn)單的教程介紹怎樣用APACHE的SOAP包寫SOAP客戶端程序.講解比較詳細(xì).
注意點(diǎn):
*如果SOAP傳回來(lái)的參數(shù)是一個(gè)CLASS,這個(gè)CALSS會(huì)被序列化(Serializer)為一段XML
代碼,在客戶端接這個(gè)CLASS時(shí),仍然需要一個(gè)同名CLASS,而且那些被傳遞過(guò)來(lái)的數(shù)據(jù)的SE
T和GET方法名和參數(shù)名要相同.如果是自定義的CLASS,就要做maping聲明.聲明方法見(jiàn)APA
CHE SOAP包的samples\addressbook\DeploymentDescriptor.xml文件中isd:mappings的
寫法.
在客戶端調(diào)用時(shí)要加上
SOAPMappingRegistry smr = new SOAPMappingRegistry();
BeanSerializer beanSer = new BeanSerializer();
smr.mapTypes(/*encodingStyle*/Constants.NS_URI_SOAP_ENC,
new QName(/*Namespace URI*/"urn:xml-soap-address-demo", /*Local
Part*/"address"),
/*Class type*/Address.class, /*java2XMLClassName*/beanSer,
/*xml2JavaClassName*/beanSer);
call.setSOAPMappingRegistry(smr);
*目前不是所有的CLASS都能被序列化,如Hashtable就不行,所以最好用簡(jiǎn)單的數(shù)據(jù)類
型,如String,String,Integer,Double及其數(shù)組來(lái)傳遞變量,對(duì)復(fù)雜的參數(shù),可以直接做成
XML Document傳遞(使用Constants.NS_URI_LITERAL_XML作為EncodingStyleURI),這樣就
省得客戶端專門做個(gè)CLASS來(lái)接參數(shù),也方便跨語(yǔ)言的調(diào)用.在使用APACHE的SOAP包時(shí),XML
Document在客戶端會(huì)被轉(zhuǎn)換為XML DOM的Element class.
現(xiàn)在唯一的方法是自己寫進(jìn)行序列化的程序,不過(guò)以后也許會(huì)有標(biāo)準(zhǔn)的序列化方法.
*CLASS被序列化時(shí)CLASS中的靜態(tài)的變量是不會(huì)被加入的來(lái)的,這一點(diǎn)要注意.