关于 java (apache xmlrpc) ,delphi (delphi xml-rpc),javascript(jsolait)操作xmlrpc的几点注意事项。
(lizongbo原创,转载请注明出处。)
A. java操作xmlrpc.
可以使用 apache xmlrpc http://ws.apache.org/xmlrpc/
1. org.apache.xmlrpc.XmlRpc.setDebug(true);可以打开调试模式,可以看到一些详细的xmlrpc解析处理日志。
2. 不支持值为null,支持的java类型为:Integer,Boolean,String,Double,java.util.Date(支持其子类),byte[],java.util.Vector,java.util.Hashtable
(http://ws.apache.org/xmlrpc/types.html apache xmlrpc 对java类型作了扩展,但是如果要考虑其它编程语言的调用,不建议使用扩展的类型)
B. delphi操作xmlrpc的库是delphixml-rpc:http://sourceforge.net/projects/delphixml-rpc/
(网上有人提到过codepunk,但是现在已经无法下载.http://www.codepunk.com/xmlrpc1_7_6.zip ,参考:http://www.delphibbs.com/keylife/iblog_comment.asp?xid=870)
于是选择了delphixml-rpc,实际使用中遇到以下一些问题,
1.汉字处理的问题。 delphi作客户端, java作服务端,产生
Hello, 你好 , test  汉字"不能够转换成"Hello, 你好 , test 汉字"
的问题, 解决方法如下:
xmlrpcparser
1554行,
CHR改成widechar
如下:
THEN CurContent := CurContent + widechar (StrToIntDef ('$'+Copy (Name, 3, MaxInt), 32))
ELSE CurContent := CurContent + widechar (StrToIntDef (Copy (Name, 2, MaxInt), 32));
对于sf上最新的xmlrpc包,则需要修改LibxmlPraser.pas对应地方的代码
2.空字符串(非null)的解析问题。
java 的代码: Hashtable struct = new Hashtable();
struct.put("type", new Integer(0));
struct.put ("id", "0"); //如果这样写 struct.put("id", ""); ,就会导致结构体错乱 ,取不到第一个 struct
解决办法,通过一个约定的字符串“nil”来表示空字符串。
3. 使用ssl遇到的问题:
tomcat的 ssl配置为:
<Connector port="8083"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="conf/ca/.keystore"
keystorePass="password">
</Connector>
而delphi的xmlrpc调用会出问题,因此需要修改源代码:
在XmlRpcClient.pas的第321行之后加上下面两行代码:
IdSSLIOHandlerSocket.SSLOptions.Mode := sslmUnassigned;
IdSSLIOHandlerSocket.SSLOptions.Method := sslvTLSv1;
(如果tomcat使用了apr,则ssl配置是不一样的,这种情况下的delphi调用,我们没测试过)
4.乱码导致结构体解析失败
如果结构体的string里有不可识别的字符,会导致结构体解析失败,
因此,在传输的内容为不可预见的情况下(比如用户发送的千奇百怪的短消息),
建议用byte传送(实际工作中遇到这样的情况并总结出来的。)
服务端 :struct.put ("msg", "测试短消息"); ---> struct.put ("msgbyte", "测试短消息".getBytes());
客户端delphi代码改用asBase64str方法来还原为string.
(以上均是实际工作中遇到的问题。 )
C .jsolait的xmlrpc库是javascript的操作xmlrpc的,非常简单.
多个参数的调用可以放在一个数组,也可以分别传入,同jdk1.5的可变参数(Variable Arguments)。
如果只传一个参数,而这个参数是个数组,需要这样写:
var xmlrpc=null;
try{
var xmlrpc = importModule("xmlrpc");
}catch(e){
reportException(e);
throw "importing of xmlrpc module failed.";
}
var addr = "http://lizongbo:808/lizongbo/xmlrpc";
var methods = ["lizongbo.testOneArray"];
var rslt;
var params = new Array();
params[0] = "0311112";
params[1] = "awsasaas";
params[2] = "awsasaas";
try{
var service = new xmlrpc.ServiceProxy(addr, methods);
rslt = service.lzbrpc.testOneArray([params]);//用中括号括起来,否则会被解析为三个传入参数的调用
///service.lzbrpc.testOneArray(params) 等同于service.lzbrpc.testOneArray(params[0],params[1],params[2]);
返回结果里如果只有一个值,可以直接在用rslt,如果有多个值,
比如下面这个结构体, 则可以用rslt.flag,rslt.info,rslt.struct.version来分别得到对应的值。
(符合dom)
// var str="" + rslt.flag+' xx '+rslt.info+' yy '+rslt.struct.version ;
// 或者var str="" + rslt['flag']+' xx '+rslt['info']+' yy '+rslt['struct']['version'];
//得到的结果是"1 xx 成功 yy 123.beta "
参考 : http://www.blogjava.net/mstar/archive/2005/06/07/5657.aspx
D . 调试xmlrpc,有一个非常优秀的工具:
http://torrez.net/projects/konstructor/Konstructor.exe
来自:
http://torrez.net/archives/xmlrpc_request_builder.php
缺点,只能够连接类似 http://lizongbo.com/xmlrpc的Endpoint
不支持https,也不支持除80外的其它端口
(lizongbo原创,转载请注明出处。)