假设我有一个远程类,它有一个带有 POJO 参数的方法:
class MyRemote implements Remote {
void service(Param param) throws RemoteException;
}
客户端检索 stub 并执行以下操作:
// DerivedParam is defined by the client
// and is derived from Param
DerivedParam dparam = getDerivedParam();
myService.service(dparam);
它失败了,因为服务器不知道 DerivedParam 类(以及它可能实现的接口(interface))。
问题:是否可以通过某种方式将这些类从客户端传递到服务器以使此类调用成为可能?
最佳答案
我不是这方面的专家,但我不久前确实用过这个技巧。神奇之处在于 code mobility 的使用通过设置java.rmi.server.codebase
属性。
您可以将此属性指向共享类可能驻留的 URL 或以空格分隔的 URL 列表。例如,这可以是 FTP 服务器或 HTTP 服务器,其中驻留具有公共(public)类的 jar 文件。
一旦设置,代码库注释将包含在服务器和客户端编码的所有对象中,当任何一方找不到类时,他们会在代码库中提供的 URL 中查找它并动态加载它。
请阅读Dynamic Code Downloading with Java RMI .
假设您只向客户端提供接口(interface),并且实现将位于给定的代码库中。然后客户端请求服务器发送一个给定的对象,客户端期望收到一个实现给定接口(interface)的对象,但是实际的实现对于客户端来说是未知的,当它反序列化发送的对象的时候就得去代码了基并下载所传递的实际对象的相应实现类。
这将使客户端变得非常精简,并且您将非常轻松地更新代码库中的类,而不必更新每个客户端。
假设您有一个具有以下接口(interface)的 RMI 服务器
public interface MiddleEarth {
public List<Creature> getAllCreatures();
}
客户端将只有 MiddleEarth
和 Creature
的接口(interface),但类路径中没有任何实现。
其中 Creature
的实现是 Elf
、Man
、Dwarf
和 类型的可序列化对象霍比特人
。这些实现位于您的代码库中,但不在客户端的类路径中。
当您要求 RMI 服务器向您发送中土世界中所有生物的列表时,它将发送实现 Creature
的对象,即上面列出的任何类。
当客户端收到序列化对象时,它必须查找类文件以便反序列化它们,但这些文件并不位于本地类路径中。该流中的每个对象都标有给定的代码库,可用于查找丢失的类。因此,客户端求助于代码库来查找这些类。在那里它将找到正在使用的实际生物类。
代码库双向工作,因此这意味着如果您向服务器发送Creature
(即Ent
),它将在代码库中查找它也是如此。
这意味着,当客户端和服务器都需要发布新类型的生物时,他们所要做的就是更新代码库中的 creaturesImpl.jar
,而服务器或客户端中无需执行任何操作应用程序本身。
关于java - RMI:将非远程对象类传递到服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10798877/