xml rpc是什么



xml rpc是什么?

1.xml rpc是什么 1.1. xml rpc简介 xml rpc是使用http协议做为传输协议的rpc机制,使用xml文本的方式传输命令和数据。 一个rpc系统,必然包括2个部分:1.rpc client,用来向rpc server调用方法,并接收方法的返回数据;2.rpc server,用于响应rpc client的请求,执行方法,并回送方法执行结果。 1.2. xml rpc的可用版本 xml rpc client和xml rpc server都有很多版本的实现。一般而言,一个实现版本都会同时实现client/server。但由于都满足xml rpc规范,从理论上讲,任何一个版本的rpc client实现与任何一个版本的rpc server都能配套使用。 更进一步,由于xml rpc以xml文本的方式,使用http协议传输,所以与编程语言无关。例如:rpc client的已实现版本包括了:perl,php,python,c/c++,java,等等;rpc server的实现语言包括perl,java,等。 同一种编程语言所实现的版本也不止一个。例如java版的实现有:Marque的xmlrpc实现(http://xmlrpc.sourceforge.net/),apache的xmlrpc 实现(http://ws.apache.org/xmlrpc/)

1.3.xmlrpc的工作原理 完整的需要参考xmlrpc规范(http://www.xmlrpc.com/spec) 简单描述: rpcclient的工作原理:rpcclient根据URL找到rpcserver -> 构造命令包,调用rpcserver上的某个服务的某个方法 -> 接收到rpcserver的返回,解析响应包,拿出调用的返回结果。 rpcserver的工作原理:启动一个webserver(在使用内置的webserver的情况下) -> 注册每个能提供的服务,每个服务对应一个Handler类 ->进入服务监听状态。 1.4. xmlrpc规范 区区6页,讲的非常清楚,建议细看。http://www.xmlrpc.com/spec

2.在java中使用xml rpc的几个例子 2.0.环境准备:下载如下包并设置到CLASSPATH中 apache xmlrpc软件包(http://ws.apache.org/xmlrpc/) commons-httpclient-3.0-rc4.jar commons-codec-1.3.jar 2.1.使用apache的java xmlrpc实现版本,实现简单的加/减服务。参考附录中test.XmlRPCClient类与test.JavaServer类 2.2.使用apache的java xmlrpc实现版本,测试java的数据类型与xmlrpc数据类型的相互对应关系。参考附录中test2.XmlRPCClient类与test2.JavaServer类。 在这里简单描述一下: >xmlrpc中的Array类型,对应到java中的Vector类型 例如:在RPC Server中的某个服务方法的返回值的声明类型是String[],但在Client中接收到的将是Vector对象; 反之,如果Client传送过去的调用参数为String[],但在RPC Server中所接收到的将是Vector对象 当然,如果我们不使用String[],直接声明为Vector,也是可以的。 >xmlrpc中的struct类型,对应到java中的Hashtable类型 >其它的类型,如:String,int,double,boolean,Date等,都比较好对应。需要注意的是:在rpc Client中,如果使用到int/double/boolean这些基本类型时,需要将他们封装成一个相应的Object,例如:Integer/Double/Boolean。

2.3.使用apache的java xmlrpc实现版本,实现自定义类型的数据的传输 这个sample中,假设所传输的object都实现了XmlRPCSerializable接口。这个例子的目的是:模拟unionmon中的command对象。当假设所传输的数据是一个Object[]时,可以用这种方式传输。结合unionmon中的代码生成机制,每个vo的序列化/反序列化方法可以在代码生成过程中完成。同样地,vox的序列化/反序列化方法需要手写。 参考代码:附录中的test3.XmlRPCSerializable , test3.AccountVO , test3.XmlRPCClient , test3.JavaServer

2.4.不启动内置的WebServer,让tomcat支持rpc server。 做法:1.实现一个Servlet,并配置到tomcat中;2.让rpc client直接找这个servlet,获得服务。 注意rpc client使用的是http post方法,所以该servlet中只需要实现doPost方法。

过程:在tomcat中的web.xml增加如下配置: <servlet>      <servlet-name>SampleServiceServlet</servlet-name>      <servlet-class>test4.ServletXmlRPCServer</servlet-class> </servlet> <servlet-mapping>      <servlet-name>SampleServiceServlet</servlet-name>      <url-pattern>/SampleServiceServlet</url-pattern> </servlet-mapping>

参考类:附件中的test4.SampleService,test4.ServletXmlRPCServer,test4.XmlRPCClient

3.todolist 3.1.能否通过introspect方式,使得自定义类型的vo的序列化/反序列化工作自动完成.castor可以完成对象的xml binding,似乎可参考 3.2.soap协议比xmlrpc复杂并强大。soap不熟悉。另,soap一定与web service在一起用?能否不用web service,但使用soap做rmi的协议。

4.附录 4.1.附录1 xmlrpc所支持的数据类型(略) 4.2.附录2 xmlrpc数据类型与java语言的数据类型的映射(略) 4.3.参考资料 http://xmlrpc.sourceforge.net/   –Marque的xmlrpc实现 http://ws.apache.org/xmlrpc/ apache上xmlrpc server的实现 http://xmlrpc-c.sourceforge.net/xmlrpc-howto/xmlrpc-howto.html xmlrpc howto http://www.sentom.net/list.asp?id=80 xml-rpc之实例 http://www.xmlrpc.com/spec xmlrpc规范 4.4.相关代码 //*********************************  begin test.XmlRPCClient  ************************************// package test; import java.util.*; import org.apache.xmlrpc.*; public class XmlRPCClient {   // The location of our server.   private final static String server_url =       “http://localhost:9001“;   public static void main(String[] args) throws Exception{       XmlRpc.debug = true;       // Create an object to represent our server.       XmlRpcClient server = new XmlRpcClient(server_url);

// Build our parameter list.       Vector params = new Vector();       params.addElement(new Integer(5));       params.addElement(new Integer(3));

// Call the server, and get our result.       Hashtable result = (Hashtable) server.execute(“mysample.sumAndDifference”,           params);       int sum = ( (Integer) result.get(“sum”)).intValue();       int difference = ( (Integer) result.get(“difference”)).intValue();       System.out.println(“Sum: ” + Integer.toString(sum) +                          “, Difference: ” +                          Integer.toString(difference));   } } //*********************************   end test.XmlRPCClient   ************************************//

//**********************************  begin test.JavaServer   ************************************//
package test;

import java.util.*; import org.apache.xmlrpc.WebServer;

public class JavaServer {

public JavaServer() {   }

public Hashtable sumAndDifference(int x, int y) {     Hashtable result = new Hashtable();     result.put(“sum”, new Integer(x + y));     result.put(“difference”, new Integer(x – y));     return result;   }

public static void main(String[] args) {     try {       // Invoke me as <http://localhost:9001/RPC2>.       WebServer webserver = new WebServer(9001);       webserver.addHandler(“mysample”, new JavaServer());       webserver.start();     }     catch (Exception exception) {       System.err.println(“JavaServer: ” + exception.toString());     }   } }

//**********************************  end test.JavaServer  ************************************//

//**********************************  begin test2.XmlRPCClient  ************************************//
package test2;

import java.util.*; import org.apache.xmlrpc.*; public class XmlRPCClient {

// The location of our server.   private final static String server_url =       “http://localhost:9001“;

public static void main(String[] args) {     try {       XmlRpc.debug = true;       XmlRpcClient server = new XmlRpcClient(server_url);       // Build our parameter list.       Vector params = new Vector();       Vector arg0 = new Vector();       arg0.add(“army”);       arg0.add(“robin”);       params.addElement(arg0);       Hashtable arg1 = new Hashtable();       arg1.put(“a”,”a”);       arg1.put(“b”,”b”);       params.addElement(arg1);       Integer arg2 = new Integer(3);       params.addElement(arg2);       Double arg3 = new Double(11.33);       params.addElement(arg3);       Boolean arg4 = new Boolean(false);       params.addElement(arg4);       Date arg5 = Calendar.getInstance().getTime();       params.addElement(arg5);       // Call the server, and get our result.       Object ret = server.execute(“sample.getAllUser”,params);       Vector result = (Vector)ret;       if(result!=null){         System.out.println(“result:” + result.size() + “records”);         for(int i=0;i<result.size();i++){           System.out.println(“result ” + i + “is:” + result.get(i));         }       }     }     catch (XmlRpcException exception) {       System.err.println(“XmlRPCClient: XML-RPC Fault #” +                          Integer.toString(exception.code) + “: ” +                          exception.toString());     }     catch (Exception exception) {       exception.printStackTrace(System.err);     }   } }

//*********************** end test2.XmlRPCClient *********************************//

//*********************** begin test2.JavaServer*********************************//

package test2; import java.util.*; import org.apache.xmlrpc.WebServer; public class JavaServer {

public JavaServer () {             // Our handler is a regular Java object. It can have a             // constructor and member variables in the ordinary fashion.             // Public methods will be exposed to XML-RPC clients.         }

public Vector getAllUser (Vector arg0,Hashtable arg1,int arg2,double arg3,boolean arg4,Date arg5) {           if(arg0!=null){             System.out.println(arg0.size());           }           if(arg1!=null){             System.out.println(arg1.size());           }           System.out.println(arg2);           System.out.println(arg3);           System.out.println(arg4);           System.out.println(arg5);             Vector result = new Vector();             result.add(“bruce”);             result.add(“测试中文”);             result.add(“orbison”);             return result;         }

public static void main (String [] args) {             try {

// Invoke me as <http://localhost:9001/RPC2>.                 WebServer webserver = new WebServer(9001);

webserver.addHandler(“sample”, new JavaServer());                 webserver.start();             } catch (Exception exception) {                 System.err.println(“JavaServer: ” + exception.toString());             }         }     }

//*********************** end test2.JavaServer *********************************//

//********************* begin test3.XmlRPCSerializable ****************************// package test3; import java.util.Vector; public interface XmlRPCSerializable {   /*将本对象序列化为Vector对象*/   public Vector serialize();   /*从v中反序列化本对象*/   public void deSerialize(Vector v); }

//******************** end test3.XmlRPCSerializable **********************//

//******************** begin test3.AccountVO  *********************// package test3; import java.util.*;

public class AccountVO implements XmlRPCSerializable{   private String acctId;   private double balance;   public AccountVO() {   }

public String toString(){     return “acctId:” + acctId + “,balance:” + balance;   }   public Vector serialize(){     Vector v = new Vector();     v.add(acctId);     v.add(new Double(balance));     return v;   }


public void deSerialize(Vector v){     acctId = (String)v.get(0);     balance = ((Double)v.get(1)).doubleValue();   }

public String getAcctId() {     return acctId;   }   public void setAcctId(String acctId) {     this.acctId = acctId;   }   public double getBalance() {     return balance;   }   public void setBalance(double balance) {     this.balance = balance;   }

}

//************************ end test3.AccountVO *************************//

//************************ begin test3.XmlRPCClient*************************// package test3;

import java.util.*; import org.apache.xmlrpc.*;

public class XmlRPCClient {

// The location of our server.   private final static String server_url =       “http://localhost:9001“;

public static void main(String[] args) {     try {       XmlRpc.debug = false;       // Create an object to represent our server.       XmlRpcClient server = new XmlRpcClient(server_url);

// Build our parameter list.       Vector params = new Vector();

// Call the server, and get our result.       Vector result = (Vector) server.execute(“mysample.getAllAccountVO”,                                               params);       if (result != null) {         for (int i = 0; i < result.size(); i++) {           Vector v = (Vector) result.get(i);           AccountVO vo = new AccountVO();           vo.deSerialize(v);           System.out.println(vo);         }       }

}     catch (XmlRpcException exception) {       System.err.println(“XmlRPCClient: XML-RPC Fault #” +                          Integer.toString(exception.code) + “: ” +                          exception.toString());     }     catch (Exception exception) {       exception.printStackTrace();     }   } }

//************************ end test3.XmlRPCClient*************************//

//************************ begin test3.JavaServer*************************// package test3; import java.util.*; import org.apache.xmlrpc.WebServer; public class JavaServer {

public JavaServer () {         }

public Vector getAllAccountVO () {             Vector result = new Vector();             AccountVO vo = new AccountVO();             vo.setAcctId(“robin”);             vo.setBalance(300000.00);             result.add(vo.serialize());             vo = new AccountVO();             vo.setAcctId(“amy”);             vo.setBalance(100000.10);             result.add(vo.serialize());             return result;         }

public static void main (String [] args) {             try {

// Invoke me as <http://localhost:9001/RPC2>.                 WebServer webserver = new WebServer(9001);                 webserver.setParanoid (true);                 // deny all clients                 webserver.acceptClient (“192.168.0.*”); // allow local access                 webserver.denyClient (“192.168.0.3″); // except for this one                 webserver.setParanoid (false); // disable client filter

webserver.addHandler(“sample”, new JavaServer());                 webserver.addHandler(“mysample”,new JavaServer());                 webserver.start();             } catch (Exception exception) {                 System.err.println(“JavaServer: ” + exception.toString());             }         }     }

////////////////////////end test3.JavaServer//////////////////////////////////

//************************ end test3.JavaServer*************************//

//************************ begin test4.SampleService*************************// package test4; import java.util.*; public class SampleService {   public SampleService() {   }

public Date currentTime(){     return Calendar.getInstance().getTime();   }

} ////////////////////////end test4.SampleService//////////////////////////////////

////////////////////////begin test4.ServletXmlRPCServer////////////////////////////////// package test4;

import java.io.*; import javax.servlet.ServletException; import javax.servlet.http.*; import org.apache.xmlrpc.*;

public class ServletXmlRPCServer     extends HttpServlet {   public void doPost(HttpServletRequest request, HttpServletResponse response)    throws ServletException, IOException {     XmlRpcServer xmlrpc = new XmlRpcServer();     xmlrpc.addHandler(“sampleService”, new SampleService());     byte[] result = xmlrpc.execute(request.getInputStream());     response.setContentType(“text/xml”);     response.setContentLength(result.length);     OutputStream out = response.getOutputStream();     out.write(result);     out.flush();   }

} ////////////////////////end test4.ServletXmlRPCServer//////////////////////////////////

//*********************** end test4.ServletXmlRPCServer **************************//

//*********************** begin test4.XmlRPCClient**************************// package test4;

import java.util.*;     import org.apache.xmlrpc.*;

public class XmlRPCClient {

// The location of our server.         private final static String server_url =             “http://localhost:8080/axis/SampleServiceServlet“;

public static void main (String [] args) {             try {               XmlRpc.debug = false;                 // Create an object to represent our server.                 XmlRpcClient server = new XmlRpcClient(server_url);                 // Build our parameter list.                 Vector params = new Vector();                 // Call the server, and get our result.                 Date result = (Date) server.execute(“sampleService.currentTime”, params);                 System.out.println(result.getTime());

} catch (XmlRpcException exception) {                 System.err.println(“XmlRPCClient: XML-RPC Fault #” +                                    Integer.toString(exception.code) + “: ” +                                    exception.toString());             } catch (Exception exception) {                 System.err.println(“XmlRPCClient: ” + exception.toString());             }         }     }

//*********************** end test4.XmlRPCClient**************************//