 |
上一主题
呵呵总结了![url=http://blog.csdn.net/catstiger/archive/2005/10/27/517980.aspx]经验和总结[/url]
|
|
下一主题
各位,前辈大哥,大姐.
问一下,如何实现一个事务机制.功能像数据库的事务.
具体描述如下.
我们要开发的是一个向多个系统操作的平台,当向一个系统操作成功时,向另一个系统操作失败后,如何编程使用每..
|
|
|
|
|
|
|
|
0.为什么整理xml rpc,并share 希望互通有无,实际上这些东西并不复杂,但大家的时间都有限。希望能共享。
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//////////////////////////////////
////////////////////////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//////////////////////////////////
////////////////////////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//////////////////////////////////
|
|
|
|
|
|
Re: xmlrpc walk through
|
2005年10月20日 11:50
|
|
|
经常有人问: 客户端不使用浏览器如何办? 客户端可否使用Delphi或VB客户端? 客户端能否不采取从服务器拉的方式,而是由服务器推信息过来? 多层结构的C/S架构如何实现?
本文提出XML RPC这样解决方案,非常不错,本文是学习和理解XML RPC很好的教程,从代码和原理都适合亲自动手实验。 不过在J2EE中,Apache Axis等都已经整合了XML RPC,不必自己再另写Server端代码。
从XML RPC可以了解一下SOAP或者Web服务,都是一条路线发展过来的。
我设计的Jdon框架中也有RPC,不过是基于Object的,类似RMI,但是是Http协议,如果都是java,转换成XML浪费性能。
XML RPC的web服务将在SOA架构中大显身手,我想XML RPC和Web services以及SOAP都会在以后推出的SOA服务器中处于底层位置,可能无需我们来开发。
|
|
|
|
|
|
Re: xmlrpc walk through
|
2005年10月20日 12:27
|
|
|
apache的web service开源与xml rpc相关项目:
http://ws.apache.org/
在XML世界,有两种方式实现RPC,一个是XML RPC;一个是SOAP。 XML-RPC 是一种比SOAP 更早的、简单的轻量级Web 服务技术。XML-RPC是 XML Web服务的鼻祖,大多数语言都有了标准的或已经可用的 XML-RPC 实现。
XML-RPC 要求不高,只是提出一个请求和处理信息的简单有效途径, SOAP突破了XML-RPC限制,在XML-RPC上对XML信息格式更加优化和定制,这样开发者能够对发送的XML进一步规定细化,所以SOAP更适合Service服务这样相互调用(SOA)架构:
http://weblog.masukomi.org/writings/xml-rpc_vs_soap.htm
XML-RPC是一个用XML消息执行RPC的简单协议,服务请求使用XML来编码,并通过HTTP POST发送,XML响应被嵌入HTTP响应主体。
SOAP是在计算机之间交换信息的基于XML的协议,主要侧重于通HTTP传输RPC。它利用了XML的命名空间和XML模式(XML Schema)。
XML-RPC是启动web服务最容易的方法,在很多方面比SOAP更简单易用,但不同于SOAP的是,XML-RPC没有相应的服务Service描述语法,这妨碍了XML-RPC服务Service的自动调用。
|
|
|
|
|
|
Re: xmlrpc walk through
|
2005年10月23日 15:35
|
|
|
一个比较好专门进行远程调用的开源框架:Crispy(10月23日在Sourceforge Framework排行中领先Jdon Framework前两名,排名第8,在看排名时发现的) XML-RPC是远程调用的一种方式,WebService是使用JAX-RPC,现在存在各种各样不同的远程调用,还有:RMI,EJB的JNDI调用,我们要为每个远程服务写不同的调用代码,非常麻烦,无论Jdon框架/Spring/HiveMind等,都是试图通过下面形式解决服务调用: MyService myService = (MyService)XXXX.getService(); 目前版本在支持远程服务调用这方面,还没有CriSpy那样专业和全面,它基本支持SOA所支持大部分远程服务,CriSpy的远程服务调用形式非常类似上述调用,例如它的Web服务调用语句:
Properties prop = new Properties(); prop.put(Property.REMOTE_URL_AND_PORT, "http://localhost:9080/axis/services"); prop.put(Property.EXECUTOR_CLASS, JaxRpcExecutor.class.getName());
ServiceManager manager = new ServiceManager(prop); Calculator calc = (Calculator) manager.createService(Calculator.class); System.out.println("1 + 2 = " + calc.add(1, 2));
XML-RPC调用如下:
Properties prop = new Properties(); prop.put(Property.REMOTE_URL_AND_PORT, "http://localhost:9090"); prop.put(Property.EXECUTOR_CLASS, XmlRpcExecutor.class.getName());
ServiceManager manager = new ServiceManager(prop); Calculator calc = (Calculator) manager.createService(Calculator.class); System.out.println("1 + 2 = " + calc.add(1, 2));
看看两种不同形式的调用,客户端代码几乎一致。
CriSpy还可应用在ESB,或者是JBI的客户端,胖客户端和服务器的通讯等。
Jdon框架也支持胖客户端和服务器,但只限于Java客户端,没有拓展到XML。
所幸的是CriSpy可以被嵌入Spring HiveMind, Jdon,CriSpy下一步打算是使用Pico来管理它的组件,我看和Jdon整合真是不错,还有liao的OBI,是一个组件集群框架,也可以和Jdon框架整合,使的Jdon框架的POJO组件可以有集群计算能力,那不是另外一个轻量EJB吗?
CriSpy网址: http://sourceforge.net/projects/crispy/
|
|
|
|
热点TAG:
AOP
cache
缓存
DDD
EJB
集群
设计模式
Hibernate
IOC
JiveJdon
OO
RBAC
Seam
Spring
Struts
anti spam
|