Java RMI:如何传递 POJO
我成功创建了 RMI 服务和客户端。我可以调用方法等等。但现在我想尝试以下操作:我希望在服务上托管一个标准 Java 对象(例如 LinkedList)。 另外,我想“假装”我已经有了使用 LinkedList 的现有代码。我想要的是获得一个实际上由服务管理的 LinkedList,但我可以在本地访问它,就像它是普通的 LinkedList 一样。最重要的是,我想做一些最小的日志记录,例如如果调用 .add() ,它会在服务器上写入:“添加调用”。
这不是为了生产,只是为了帮助我理解它是如何工作的!
到目前为止我已经尝试了很多事情。最有前途的是我创建了一个扩展 LinkedList 并实现 Remote 的类。该类尝试在构造函数中向注册表注册自身,如下所示:
尝试{
UnicastRemoteObject.exportObject((Remote)this); Naming.rebind("theList", (Remote)this); } 捕获(异常e){ System.out.println("失败"); 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)
提前致谢!
I successfully created an RMI service and client. I can call methods and so on. But now I wanted to try the following: I wanted a standard Java object like a LinkedList to be hosted on the service.
Also, I wanted to 'pretend' I already had existing code that uses a LinkedList. What I want is to get a LinkedList that is actually managed by the service, but that I can access locally just like it was a normal LinkedList. On top of that I want to do some minimal logging, like if .add() is called it writes on the server: "Add called".
This is not meant for production, just to help me understand how it works!
So far I've tried a lot of things. The most promising is that I have created a class that extends LinkedList and implements Remote. This class tries to register itself with the Registry in the constructor like this:
try {
UnicastRemoteObject.exportObject((Remote)this);
Naming.rebind("theList", (Remote)this);
}
catch (Exception e) {
System.out.println("fail");
System.out.println(e.getMessage());
}
I have to do this because I need to extend LinkedList, thus I cannot extend UnicastRemoteObject.
The output I get when I try to run this, on the server side:
fail Connection refused to host: 192.168.178.27; nested exception is: java.net.ConnectException: Connection refused
And on the client side:
java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList at $Proxy0.createList(Unknown Source) at RemoteProgram.main(RemoteProgram.java:27)
Thanks in advance!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
同意其他海报的观点,这是一个非常低效的设计。
至于您的例外情况,我不知道如何在服务器中获得“连接被拒绝”并且仍然能够运行客户端。您需要发布堆栈跟踪。
Agree with the other posters, this is a very inefficient design.
As for your exceptions, I don't see know how you can get a 'connection refused' in the server and still be able to run the client. You would need to post the stack trace.
LinkedList 是一个具体类,RMI 使用接口,因此您应该在客户端强制转换为 List 接口。
LinkedList is a concrete class, RMI works with interfaces so you should be casting to the List interface on the client side.
你想做的事情效率很低,而且不是一个好主意。基本上,您可以在可以序列化的方法调用中发送任何内容。如果您想要良好的性能,我建议您只使用一个远程对象来代表您的服务并充当您需要的所有服务的外观(每个远程对象都会产生单独的文件描述符,因此通常拥有大量远程对象这不是一个好主意)。此外,如果您经常添加和删除对象,那么每次添加或删除元素时都发送一条消息并不明智。我建议使用以下两个非常简单的方法使用单个远程对象:
在应用程序启动时,您可以下载链表,然后定期和在应用程序退出时,您可以发回链表。这应该比每次向链接列表添加或删除元素时使用网络更有效。只要 LinkedList 的元素是可序列化的,您就不需要执行任何魔法(例如扩展远程)来发送它。
What you are trying to do is very inefficient and not a very good idea. Basically you can send anything in a method invocation that you can serialize. If you want good performance, I would suggest that you only have one remote object that represents your service and acts as a facade for all the services that you need (each remote object results in separate file descriptor, so having lots of remote objects is typically not a good idea). Additionally, if you are frequently adding and removing objects, then sending a message every time you add or remove an element is not really sensible. I would suggest having a single remote object with the following two very simple methods:
On application startup, you can download the linked list, and then at regular intervals and at application exit, you can send back the linked list. That should be more efficient then using the network every time you add or remove an element to your linked list. As long as the elements of your LinkedList are serializable, you don't need to do any magic (like extending remote) for it be sent.