今天在TSS上發現了XML-RPC的帖子,就粗略的看了些資料,感覺這種輕量級的跨平臺遠程調用很有意思啊。用起來簡單,據說速度也很快(自己沒有試過

)。
下面貼一些資料:
XML-RPC 是工作在 Internet 上的遠程過程調用協議。通俗點講,就是使用 HTTP 協議交互,交互的載體是 XML 文件。XML-RPC 具體的規范說 明請參考
這里。
圖片來自XML-RPC官方網站
XML-RPC 規范定義了六種數據類型,下表是這六種數據類型與 Java 的數據類型對應表。
XML-RPC |
Java |
<i4> 或 <int> |
int |
<boolean> |
boolean |
<string> |
java.lang.String |
<double> |
double |
<dateTime.iso8601> |
java.util.Date |
<struct> |
java.util.Hashtable |
<array> |
java.util.Vector |
<base64> |
byte[ ] |
XML-RPC 規范的各種平臺都有具體實現,XML-RPC 規范的 Java 實現都有好幾種,這里我們選擇了 Apache XML-RPC。
XML-RPC 服務端實現
先定義一個簡單業務對象 MyHandler,遠程客戶端將調用該對象的方法,具體代碼如下:
package net.sentom.xmlrpc;
public class MyHandler {
public String sayHello(String str){
return "Hello," + str;
}
}
然后定義一個 Servlet 名叫 MyXmlRpcServer,遠程客戶端通過 HTTP-POST 訪問該 Servlet。
package net.sentom.xmlrpc;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.xmlrpc.XmlRpcServer;
public class MyXmlRpcServer extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
XmlRpcServer xmlrpc = new XmlRpcServer();
xmlrpc.addHandler("myHandler", new MyHandler());
byte[] result = xmlrpc.execute(request.getInputStream());
response.setContentType("text/xml");
response.setContentLength(result.length);
OutputStream out = response.getOutputStream();
out.write(result);
out.flush();
}
}
需要特別說明是:
xmlrpc.addHandler("myHandler", new MyHandler());
為了便于理解,這里可以看成普通的:
MyHandler myHandler = new MyHandler();
最后在web.xml文件中加入以下幾行:
<servlet>
<servlet-name>MyXmlRpcServer</servlet-name>
<servlet-class>net.sentom.xmlrpc.MyXmlRpcServer</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyXmlRpcServer</servlet-name>
<url-pattern>/MyXmlRpcServer</url-pattern>
</servlet-mapping>
XML-RPC 客戶端實現
客戶端相對簡單一些,先來一個 Java 客戶端實現 MyXmlRpcClient:
package net.sentom.xmlrpc;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Vector;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
public class MyXmlRpcClient {
public static void main(String[] args) {
try {
XmlRpcClient xmlrpc = new XmlRpcClient("http://localhost:8080/XMLRPC/MyXmlRpcServer");
Vector params = new Vector();
params.addElement("Tom");
String result = (String) xmlrpc.execute("myHandler.sayHello",params);
System.out.println(result);
} catch (MalformedURLException e) {
System.out.println(e.toString());
} catch (XmlRpcException e) {
System.out.println(e.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
http://localhost:8080/XMLRPC/MyXmlRpcServer 為 MyXmlRpcServer 的訪問URL。
String result = (String) xmlrpc.execute("myHandler.sayHello",params);
再來一個 Python 客戶端實現
import xmlrpclib
url = 'http://localhost:8080/XMLRPC/MyXmlRpcServer';
server = xmlrpclib.Server(url);
print server.myHandler.sayHello('Tom');
來源:http://www.sentom.net
[原創]xml-rpc入門例程及一個通用服務器
一,準備過程
遠程過程調用RPC,基于XML的傳輸方式,當然低層API,就不用我們操心了,但必須的軟件還是要有的,先給個列表清單
JDK1.4.2 不用說了
Xerces解析器 到http://xml.apache.org/上去下載吧,
XML-RPC開發包, http://ws.apache.org/xmlrpc/上可以下得到
將以上所有的jar包放到開發環境的classpath中。
二,Hello World
XML-RPC如果想跑起來,最后需要四個組件,WEB server, 服務器類,處理類,客戶類
1.WEB Server.
在我們已經下載的XML-RPC包中就有一個輕型級的WEB SERVER。
在程序中,我們只需要簡單的用以下語句就可以啟動。
//建立一個對象,傳輸一個端口
WebServer server = new WebServer(Integer.parseInt("8989"));
//啟動
server.start();
2.編寫處理類
處理類相當RMI中的遠程類,只不過在這里更輕量類,無須任何接口.
在這個類中包含一個或多個公有方法以供遠程的客戶端來調用。
public class HelloHandler {
public String sayHello(String name) {
return "Hello " + name;
}
}
3.服務器
負責調用以上代碼來啟動用服務器,同時還要將遠程對象綁定到該服務器上。
import java.io.IOException;
//引入必須的包,當然你的xml-rpc的包應該在classpath中
import org.apache.xmlrpc.WebServer;
import org.apache.xmlrpc.XmlRpc;
public class HelloServer {
/**
主方法
*/
public static void main(String[] args) {
try {
// 使用Xerces的XML解析器
XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser");
// 給出提示,并在端8989上啟動服務器
System.out.println("Starting XML-RPC Server...");
WebServer server = new WebServer(Integer.parseInt("8989"));
server.start();
// 將HelloHandler類的實例編定到WEB SERVER上,hello是該處理類的標識,在客戶端調用時要用得到
server.addHandler("hello", new HelloHandler());
System.out.println(
"Registered HelloHandler class to \"hello\"");
} catch (ClassNotFoundException e) {
System.out.println("Could not locate SAX Driver");
} catch (Exception e) {
System.out.println("Could not start server: " +
e.getMessage());
}
}
}
4.客戶端
根據“標識名.方法名“來定位遠程的處理方法。
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Vector;
//導入必須的包
import org.apache.xmlrpc.XmlRpc;
import org.apache.xmlrpc.XmlRpcClient;
import org.apache.xmlrpc.XmlRpcException;
public class HelloClient {
public static void main(String args[]) {
String yourname="liu xiaobai";
try {
// 使用 Apache Xerces SAX 解析器
XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser");
// 定位遠程服務器,http://主機地址:端口號, 8989是上文服務器啟動時用的端口
XmlRpcClient client =
new XmlRpcClient("http://localhost:8989/");
// 創建調用請求,方法的參數列表如果一個Vector對象來存儲。
Vector params = new Vector();
params.addElement(yourname);
// 發出請求,并返回結果,execute需要兩個參數,第一個參數用“標識名.方法名”,第二參數是一個 剛剛建立的向量對象
String result =
(String)client.execute("hello.sayHello", params);
System.out.println("Response from server: " + result);
} catch (ClassNotFoundException e) {
System.out.println("Could not locate SAX Driver");
} catch (MalformedURLException e) {
System.out.println(
"Incorrect URL for XML-RPC server format: " +
e.getMessage());
} catch (XmlRpcException e) {
System.out.println("XML-RPC Exception: " + e.getMessage());
} catch (IOException e) {
System.out.println("IO Exception: " + e.getMessage());
}
}
}
5,編譯以上代碼,要確保解析器,XMP-RPC開發包的jar文件在classpath中。
運行服務器
java HelloServer
運行客戶端
java HelloClient
6.一個通用的XML服務器
功能描述:通過配置文件來配置要加載的處理器
1.配置文件的名稱及位置
名字:config.properties
類文件的根目錄中,如果你類是默認包,那么就是同一個目錄;如果類的包名是com.hello,那么該文件應該與com目錄放在同一級中。
內容:
#標識名=類名
hello=javaxml2.HelloHandler
2.通用的源代碼
import java.io.*;
import org.apache.xmlrpc.*;
import java.util.Properties;
import java.util.Enumeration;
import java.util.Hashtable;
public class MyLightXMLServer
{
private WebServer server;
private int port;
private String configfile;
public MyLightXMLServer(int port,String config)
{
this.port=port;
this.configfile=config;
}
//啟動服務器
public void start() throws IOException,ClassNotFoundException,Exception
{
XmlRpc.setDriver("org.apache.xerces.parsers.SAXParser");
System.out.println("starting up xml-rpc server...");
server=new WebServer(port);
//調用注冊函數
registerHandlers(this.getHandlers());
server.start();
}
public void registerHandlers(Properties handlers) throws Exception
{
Enumeration enum=handlers.propertyNames();
while(enum.hasMoreElements())
{
String temp=(String)enum.nextElement();
String tempcls=(String)handlers.get(temp);
Class cls=Class.forName(tempcls);
server.addHandler(temp,cls.newInstance());
}
}
public Properties getHandlers()
{
try
{
Properties properties=new Properties();
properties.load(new FileInputStream(new File("config.properties")));
return properties;
}
catch(Exception e)
{
e.printStackTrace();
}
return null;
}
public static void main(String args[])
{
String port="8989";
String configfile="";
MyLightXMLServer server=new MyLightXMLServer(Integer.parseInt(port),configfile);
try
{
server.start();
}
catch(Exception e)
{e.printStackTrace();}
}
}
將MyLightXMLServer .java編譯并運行之后,該服務器會在配置文件中加載該處理器
然后可以直接執行HelloClient
java HelloClient