私は単純な問題を抱えています。Java XMLRPC クライアントが、TCL で記述された XMLRPC サーバーと正しく通信できないようです。
(TCL XMLRPC SERVER OPEN SOURCE実装を使用)
概要: TCL/Python などの XMLRPC クライアントは、TCL XMLRPC サーバーに対してメッセージを送受信できますが、私の Java XMLRPC クライアントは機能しないようです。
Java クライアント側コード:
/*
* try's, catches, comments removed to show code-flow w/ out mess.
* host/port/target all same as whats set in Python
*/
//show imports / package used, this is using apache's xmlrpc v3.1.3
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
//... host and port are the same as whats used in working tcl/python clients. (remoteHostName / 5555)
//... method is the same as well, 'fooBar123', and args is just 1 string passed to it.
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
target = "RPC2";
String targetUrl = "http://"+host+":"+port+"/" + target;
TestNgUtil.ReportInfo("config.SetServerUrl("+targetUrl+")");
config.setServerURL(new URL(targetUrl));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
String result = null;
/*
* This Result Never Returns from TCL XMLRPC Server
*/
result = (String) client.execute(command, params);
Java に対する TCL サーバーのデバッグ エラー応答:
//(notice unlike Python example below, no proper Header, Content-Type, etc)
TCL Server Side of the Java Error
in serveOnce: addr: 10.21.69.13
in serveOnce: port: 64522
Unknown type: fooBar123</value></param></params>
bgerror failed to handle background error.
Original error:
Error in bgerror: can't read "xmlcall": no such variable**
Python の例は機能しますが、成功したリクエストを確認するために XML デバッグを出力することにも注意してください。
ただし、TCL クライアント、または単純な Python XMLRPC クライアントを使用しようとすると、機能します。Python を使用して XMLRPC リクエストを出力することもできます。
(Python クライアントから、空想的なものは何もありません)
import xmlrpclib
server_url = "http://remoteHostName:5555";
server = xmlrpclib.Server(server_url, verbose=True);
result = server.hello('hello world')
## DEBUG INFO PRINTED FROM REQUEST POST ##
send: "POST /RPC2 HTTP/1.1\r\nHost: remoteHostName:5555\r\nAccept-Encoding: gzip\r\nUser-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)\r\nContent-Type: text/xml\r\nContent-Length: 160\r\n\r\n<?xml version='1.0'?>\n<methodCall>\n<methodName>hello</methodName>\n<params>\n<param>\n<value><string>hello world</string></value>\n</param>\n</params>\n</methodCall>\n"
reply: 'HTTP/1.1 200 OK\n'
header: Content-Type: text/xml
header: Content-length: 162
body: '<?xml version="1.0"?>\n<methodResponse>\n\t<params>\n\t\t<param>\n\t\t\t<value> <string>hello(hello world) yaaaah?!</string></value>\n\t\t</param>\n\t</params>\n</methodResponse>\n'
適切な応答を戻す前の TCL サーバーのデバッグ/Python への応答:
send: "POST /RPC2 HTTP/1.1
Host: remoteHostName:5555
Accept-Encoding: gzip
User-Agent: xmlrpclib.py/1.0.1 (by www.pythonware.com)
Content-Type: text/xml
Content-Length: 156
これは、hello( arg ) の TCL XMLRPC サーバー コードです。java ではなく、tcl、python で動作します。(おそらく Java クライアントの構成の問題)
#using the TCL XMLRPC Server ( http://sourceforge.net/projects/xmlrpctcl/ )
package require xmlrpc
xmlrpc::serv 5555
proc hello { world } {
puts "IN HELLO WORLD!"
set res "hello(${world}) yaaaah?!"
return [list string $res]
}
vwait forever
これまでのところ、Java または Python を組み込みの TCL インタープリターと共に使用してこれを回避しようとしましたが、このアプリケーションが使用、ソース、および共有する必要がある TCL が大量にあるため、取得する必要があります。 TCL XMLRPC サーバーが稼働しています。
また、Web サービスの httpd を XMLRPC で使用しようとしましたが、tcl/python クライアントで動作するようにしてもあまり成功しませんでした。
すでにこれで週末全体を殺しました。
読んでくれてありがとう、そしてどんなポインタ/助けも。
解決策が見つかりました(ここに投稿)
- 問題は、データ型に含まれていない古い tcl xmlrpc サーバーの XML に要約されます。それらは暗示されているため、apache の XMLRPC クライアントが文字列の周りに暗示されているデータ型を送信するようにするには、「カスタム データ型」を実装してタグを元に戻すだけです。
コードはこちら:
import java.net.URL;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.apache.xmlrpc.common.TypeFactoryImpl;
import org.apache.xmlrpc.common.XmlRpcController;
import org.apache.xmlrpc.common.XmlRpcStreamConfig;
import org.apache.xmlrpc.serializer.StringSerializer;
import org.apache.xmlrpc.serializer.TypeSerializer;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
public class XMLRPCClient {
public static void main(String[] argv) throws Exception {
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://127.0.0.1:6800/rpc"));
XmlRpcClient client = new XmlRpcClient();
client.setConfig(config);
client.setTypeFactory(new MyTypeFactoryImpl(client));
Object[] params = new Object[] {
new String[] { "http://www.google.com" }
};
String result = (String)client.execute("aria2.addUri", params);
}
static private class MyStringSerializer extends StringSerializer {
public void write(ContentHandler pHandler, Object pObject)
throws SAXException {
// Write <string> tag explicitly
write(pHandler, STRING_TAG, pObject.toString());
}
}
static private class MyTypeFactoryImpl extends TypeFactoryImpl {
public MyTypeFactoryImpl(XmlRpcController pController) {
super(pController);
}
public TypeSerializer getSerializer(XmlRpcStreamConfig pConfig, Object pObject) throws SAXException {
if(pObject instanceof String) {
return new MyStringSerializer();
} else {
return super.getSerializer(pConfig, pObject);
}
}
}
}