Java RMI:如何传递POJO

问题描述:

我成功创建了RMI服务和客户端。我可以调用方法等。但是现在我想尝试以下方法:我想要一个像LinkedList这样的标准Java对象托管在服务上。 另外,我想'假装'我已经有了使用LinkedList的现有代码。我想要的是获得一个实际由服务管理的LinkedList,但我可以像访问一个普通的LinkedList一样访问本地。最重要的是,我想做一些最小化的日志记录,就像调用.add()一样,它会在服务器上写入:“添加调用”。Java RMI:如何传递POJO

这不是为了生产,只是为了帮助我理解它是如何工作的!

到目前为止,我已经尝试了很多东西。最有前途的是我创建了一个扩展LinkedList并实现Remote的类。该类试图将自身与构造注册表这样注册:

try {

UnicastRemoteObject.exportObject((Remote)this); Naming.rebind("theList", (Remote)this); } catch (Exception e) { System.out.println("fail"); System.out.println(e.getMessage()); }

我必须这样做,因为我需要延长的LinkedList,所以我不能继承UnicastRemoteObject。

输出我得到的,当我尝试运行此,在服务器端:

 
fail 
Connection refused to host: 192.168.178.27; nested exception is: 
java.net.ConnectException: Connection refused 

而且在客户端:

 
java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList 
at $Proxy0.createList(Unknown Source) 
at RemoteProgram.main(RemoteProgram.java:27) 

提前感谢!

你要做的是非常低效,不是一个好主意。基本上,您可以发送任何可以序列化的方法调用。如果你想获得良好的性能,我建议你只有一个代表你的服务的远程对象,并作为你需要的所有服务的外观(每个远程对象产生单独的文件描述符,因此通常有很多远程对象不是一个好主意)。另外,如果您经常添加和删除对象,那么每次添加或删除元素时都会发送消息,这并不合理。我建议有以下两个非常简单的方法,一个单一的远程对象:

LinkedList retrieveLinkedListByName(String); 
boolean commitNewVersionOfLinkedListByName(String,LinkedList); 

在应用程序启动时,您可以下载链接的列表,然后定期和在应用程序退出,您可以发送回链接名单。每次向链表添加或删除元素时,使用网络应该会更有效。只要LinkedList的元素是可序列化的,你就不需要做任何魔术(比如扩展远程)来发送它。

+0

嘿迈克尔,谢谢你的回应。但我只是试图理解这些概念。我指定它的方式 - 你将如何去做,以便每次改变它都被传送到服务器,尽管效率很低? – partel 2010-07-11 12:07:19

java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList 
at $Proxy0.createList(Unknown Source) 
at RemoteProgram.main(RemoteProgram.java:27) 

LinkedList是一个具体类,RMI与接口一起工作,因此您应该将其转换为客户端的List接口。

+0

...至于连接被拒绝的异常,我首先看看你正在使用的安全策略(假设没有像防火墙这样的外部问题)。 – darri 2010-07-11 11:47:11

同意其他海报,这是一个非常低效的设计。

至于你的例外情况,我不知道你怎么能在服务器中得到'连接被拒绝'并且仍然能够运行客户端。您需要发布堆栈跟踪。