
下面貼一些資料:
XML-RPC 是工作在 Internet 上的遠(yuǎn)程過程調(diào)用協(xié)議。通俗點(diǎn)講,就是使用 HTTP 協(xié)議交互,交互的載體是 XML 文件。XML-RPC 具體的規(guī)范說 明請(qǐng)參考這里。
圖片來自XML-RPC官方網(wǎng)站
XML-RPC 規(guī)范定義了六種數(shù)據(jù)類型,下表是這六種數(shù)據(jù)類型與 Java 的數(shù)據(jù)類型對(duì)應(yīng)表。
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 規(guī)范的各種平臺(tái)都有具體實(shí)現(xiàn),XML-RPC 規(guī)范的 Java 實(shí)現(xiàn)都有好幾種,這里我們選擇了 Apache XML-RPC。
XML-RPC 服務(wù)端實(shí)現(xiàn)
先定義一個(gè)簡(jiǎn)單業(yè)務(wù)對(duì)象 MyHandler,遠(yuǎn)程客戶端將調(diào)用該對(duì)象的方法,具體代碼如下:package net.sentom.xmlrpc; public class MyHandler { public String sayHello(String str){ return "Hello," + str; } }
然后定義一個(gè) Servlet 名叫 MyXmlRpcServer,遠(yuǎn)程客戶端通過 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 客戶端實(shí)現(xiàn)
客戶端相對(duì)簡(jiǎn)單一些,先來一個(gè) Java 客戶端實(shí)現(xiàn) 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);
再來一個(gè) Python 客戶端實(shí)現(xiàn)
import xmlrpclib url = 'http://localhost:8080/XMLRPC/MyXmlRpcServer'; server = xmlrpclib.Server(url); print server.myHandler.sayHello('Tom'); 來源:http://www.sentom.net
[原創(chuàng)]xml-rpc入門例程及一個(gè)通用服務(wù)器
一,準(zhǔn)備過程遠(yuǎn)程過程調(diào)用RPC,基于XML的傳輸方式,當(dāng)然低層API,就不用我們操心了,但必須的軟件還是要有的,先給個(gè)列表清單
JDK1.4.2 不用說了
Xerces解析器 到http://xml.apache.org/上去下載吧,
XML-RPC開發(fā)包, http://ws.apache.org/xmlrpc/上可以下得到將以上所有的jar包放到開發(fā)環(huán)境的classpath中。
二,Hello World
XML-RPC如果想跑起來,最后需要四個(gè)組件,WEB server, 服務(wù)器類,處理類,客戶類
1.WEB Server.
在我們已經(jīng)下載的XML-RPC包中就有一個(gè)輕型級(jí)的WEB SERVER。
在程序中,我們只需要簡(jiǎn)單的用以下語句就可以啟動(dòng)。
//建立一個(gè)對(duì)象,傳輸一個(gè)端口
WebServer server = new WebServer(Integer.parseInt("8989"));
//啟動(dòng)
server.start();2.編寫處理類
處理類相當(dāng)RMI中的遠(yuǎn)程類,只不過在這里更輕量類,無須任何接口.
在這個(gè)類中包含一個(gè)或多個(gè)公有方法以供遠(yuǎn)程的客戶端來調(diào)用。
public class HelloHandler {
public String sayHello(String name) {
return "Hello " + name;
}
}
3.服務(wù)器負(fù)責(zé)調(diào)用以上代碼來啟動(dòng)用服務(wù)器,同時(shí)還要將遠(yuǎn)程對(duì)象綁定到該服務(wù)器上。
import java.io.IOException;
//引入必須的包,當(dāng)然你的xml-rpc的包應(yīng)該在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上啟動(dòng)服務(wù)器
System.out.println("Starting XML-RPC Server...");
WebServer server = new WebServer(Integer.parseInt("8989"));
server.start();
// 將HelloHandler類的實(shí)例編定到WEB SERVER上,hello是該處理類的標(biāo)識(shí),在客戶端調(diào)用時(shí)要用得到
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.客戶端
根據(jù)“標(biāo)識(shí)名.方法名“來定位遠(yuǎn)程的處理方法。import java.io.IOException;
import java.net.MalformedURLException;
import java.util.Vector;//導(dǎo)入必須的包
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");
// 定位遠(yuǎn)程服務(wù)器,http://主機(jī)地址:端口號(hào), 8989是上文服務(wù)器啟動(dòng)時(shí)用的端口
XmlRpcClient client =
new XmlRpcClient("http://localhost:8989/");
// 創(chuàng)建調(diào)用請(qǐng)求,方法的參數(shù)列表如果一個(gè)Vector對(duì)象來存儲(chǔ)。
Vector params = new Vector();
params.addElement(yourname);
// 發(fā)出請(qǐng)求,并返回結(jié)果,execute需要兩個(gè)參數(shù),第一個(gè)參數(shù)用“標(biāo)識(shí)名.方法名”,第二參數(shù)是一個(gè) 剛剛建立的向量對(duì)象
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開發(fā)包的jar文件在classpath中。
運(yùn)行服務(wù)器
java HelloServer
運(yùn)行客戶端
java HelloClient
6.一個(gè)通用的XML服務(wù)器
功能描述:通過配置文件來配置要加載的處理器
1.配置文件的名稱及位置
名字:config.properties
類文件的根目錄中,如果你類是默認(rèn)包,那么就是同一個(gè)目錄;如果類的包名是com.hello,那么該文件應(yīng)該與com目錄放在同一級(jí)中。
內(nèi)容:
#標(biāo)識(shí)名=類名
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;
}
//啟動(dòng)服務(wù)器
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);
//調(diào)用注冊(cè)函數(shù)
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編譯并運(yùn)行之后,該服務(wù)器會(huì)在配置文件中加載該處理器
然后可以直接執(zhí)行HelloClientjava HelloClient