简体   繁体   English

通过 RMI 传输对象的数据(特别是服务器变量)

[英]Transmitting an object's data (specifically, server variables) over RMI

Edit : The Java™ Tutorials say that编辑Java™ 教程

the server and the client communicate and pass information back and forth服务器和客户端通信并来回传递信息

and that RMI和那个 RMI

provides mechanisms for loading an object's class definitions as well as for transmitting an object's data.提供加载对象的类定义以及传输对象数据的机制。

I was hoping that "an object's data" would include a server object's variables (such as Test.value in my code, below) - but the first comments I got indicate that perhaps I was wrong.我希望“一个对象的数据”将包含一个服务器对象的变量(例如下面我的代码中的Test.value ) - 但我得到的第一条评论表明我可能错了。 My original question follows.我原来的问题如下。

I am trying to access a remote object that I am sending over RMI to a client.我正在尝试访问我通过 RMI 发送给客户端的远程对象。 I am only able to access its methods, but not its instance variables - I get the interface's fields instead.我只能访问它的方法,而不能访问它的实例变量——我得到了接口的字段。 My question is, once I implement and instantiate a class on a server, how do I access its [public] fields, without using getters?我的问题是,一旦我在服务器上实现并实例化了一个类,我该如何访问它的 [public] 字段,而不使用 getter? I am able to send a stub without any errors or exceptions, but like I said, I am not able to access the server's object's fields, only the interface's.我能够发送没有任何错误或异常的存根,但就像我说的那样,我无法访问服务器对象的字段,只能访问接口的字段。 Following is an abbreviated version of my interface, implementation, server, and client.以下是我的接口、实现、服务器和客户端的缩写版本。

package test;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface TESTint extends Remote {

        double value = -22;
        String shortName = "TESTint";

        double getValue() throws RemoteException;
}
package test;

import java.rmi.RemoteException;

public class Test implements TESTint {

    public double value = -33;
    public String shortName = "TestAccount";
    public int whole = 1;

    public Test(String shortName) {
        this.shortName = shortName;
        print(shortName);
    }

    public double getValue() throws RemoteException {
        return value;
    }

    public void print(Object o) {
        System.out.println(shortName + ": " + o);
    }   
}
package test;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class RemoteTestMain {
    Test test;

    public static void main(String[] args) throws InterruptedException {
        if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
        new RemoteTestMain();
    } // main

    public RemoteTestMain() {
        test = new Test("Charlie");
        Registry registry;
        try {
            registry = LocateRegistry.createRegistry(1234);
            registry.list( ); // will throw an exception if the registry does not already exist         
            print(test.shortName); // it gets it right here
            print(test.value); // it gets it right here
            TESTint r = (TESTint) UnicastRemoteObject.exportObject(test, 0);
            registry.rebind("DCregistry", r);
            print("test bound");  
        } catch (java.rmi.RemoteException ex) {
            print("Remote Exception at Server");
            ex.printStackTrace();;
        }
    }

    public static void print(Object o) {
        System.out.println("Server: " + o);
    }
}
package test;

import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
    TESTint test;

    public static void main(String[] args) {
        try {
            new Client();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    } // main

    private void init(int account) {
        print("INITiating Account " + account);         
        try {
            Registry registry = LocateRegistry.getRegistry(1234);
            test = (TESTint) registry.lookup("DCregistry");
        } catch (Exception e) {
            System.err.println("RMI exception:");
            e.printStackTrace();
        }
        print("Short name : " + test.shortName);
        print("value: " + test.value);
        try {
            print("Value through getter is " + test.getValue());
        } catch (RemoteException e) {
            print("Could not get equity");
            e.printStackTrace();
        }
    } // init(int account)

    public Client() throws RemoteException { 
        if (System.getSecurityManager() == null) { System.setSecurityManager(new SecurityManager()); }
        init(2);
    }

    private static void print(Object o) {
        System.out.println("GUI: " + o);
    }
}

PS In the Client code above, test.shortName is wiggly-underlined and Eclipse suggests that The static field TESTint.shortName should be accessed in a static way . PS 在上面的客户端代码中, test.shortName的下划线,Eclipse 建议The static field TESTint.shortName should be accessed in a static way I understand that the Client does not recognize the implementation, only the interface - but is there a way to access test's fields, not only its methods?我知道客户端不识别实现,只识别接口 - 但是有没有办法访问测试的字段,而不仅仅是它的方法? I have many fields in my original code and I do not want to write getters for each and every one, if possible.我的原始代码中有很多字段,如果可能的话,我不想为每个字段都编写 getter。

RMI stands for Remote Method Invocation which means that you can remotely execute a method of an object. RMI代表Remote Method Invocation ,这意味着您可以远程执行对象的方法。 The implementation of the method resides in the remote system.该方法的实现驻留在远程系统中。 You can never access the instance variables of the implementation class which exists in the remote system even if they are public.您永远无法访问远程系统中存在的实现类的实例变量,即使它们是公共的。 You can only execute public methods which are exposed by the Inteface.您只能执行由接口公开的公共方法。 So if you want to access the variables, you need add public gettter methods both in the Inteface and implementation class.因此,如果要访问变量,则需要在 Inteface 和实现类中添加公共 gettter 方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM