【问题标题】:RMI: are fields of remote object serialized and sent to client?RMI:远程对象的字段是否序列化并发送到客户端?
【发布时间】:2016-12-14 12:42:03
【问题描述】:

我有以下代码:

public class Foo implements SomeRemote {
  private String verySecretString;
  public void doSomething(){...}
}

据我了解, foo 将以某种方式被序列化并从 RMI 服务器发送到 RMI 客户端。那么,客户端可以访问verySecretString吗?

【问题讨论】:

  • 序列化通常不会进行深拷贝 - 您是否测试过发送的内容?
  • @DavidT.Macknet 序列化确实总是做深拷贝,但这里没有序列化。
  • 很有趣,但在其他语言中并非如此,仅对公共表示进行序列化。我认为必须进行一些序列化才能将其发送出去,但是,嘿,不是我的语言,真的。
  • @DavidT.Macknet Java 序列化传输整个对象图。请参阅对象序列化规范。

标签: java security rmi


【解决方案1】:

这不是它的工作原理,您应该公开一个远程接口而不是一个类,然后在客户端级别操作该接口,这样客户端不知道实现细节。

所以在这里你应该有类似的东西:

public interface MyService extends Remote {
    void doSomething() throws RemoteException;
}

这只是您在客户端级别所知道的。在服务器级别,您将拥有您的实现Foo,类似于:

public class Foo implements MyService {
    private String verySecretString;
    public void doSomething(){...}
}

响应更新:

如果您不想序列化字段值,只需将关键字 transient 添加到其声明中,如下所示:

private transient String verySecretString;

【讨论】:

    【解决方案2】:

    据我了解,foo 会以某种方式被序列化并从 RMI 服务器发送到 RMI 客户端。

    没有。如果Foo 是一个导出的远程对象,它将不会被发送到任何地方。它的 stub 将被发送。

    那么,客户端无论如何都可以访问verySecretString吗?

    没有。

    【讨论】:

    • 听起来不像是深拷贝,那么。 ;)
    • @DavidT.Macknet 这是一种代理模式。与深拷贝或浅拷贝或任何类型的拷贝无关。它是由 RMI 完成的,而不是由序列化完成的。
    • 我是否理解正确 - 客户端将无法访问 Foo 的实例,客户端将有权访问实现 SomeRemote 接口的存根?
    • @Pavel_K 我已经回答过了。你只是要我重复一遍。
    猜你喜欢
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多