2016-05-28 8 views
-2

bearbeiten: Die Java™ Tutorials sagen, dassÜbertragen eines Daten des Objekts (insbesondere Servervariablen) über RMI

der Server und der Client kommunizieren und geben Informationen zurück und her

und dass RMI

bietet Mechanismen zum Laden der Klassendefinitionen eines Objekts sowie für die Übertragung der Daten eines Objekts.

Ich hatte gehofft, dass „eine Daten für das Objekt“ eines Serverobjekts Variablen (wie Test.value in meinem Code unten) umfassen würde - aber die ersten Kommentare, die ich zeigen bekam, dass vielleicht falsch ich war. Meine ursprüngliche Frage folgt.

Ich versuche, auf ein Remoteobjekt zuzugreifen, das ich über RMI an einen Client sende. Ich kann nur auf seine Methoden zugreifen, aber nicht auf seine Instanzvariablen. Stattdessen erhalte ich die Felder der Schnittstelle. Meine Frage ist, wie kann ich, sobald ich eine Klasse auf einem Server implementiere und instanziiere, auf seine [public] Felder zugreifen, ohne Getter zu verwenden? Ich bin in der Lage, einen Stub ohne irgendwelche Fehler oder Ausnahmen zu senden, aber wie gesagt, ich kann nicht auf die Felder des Server-Objekts zugreifen, nur die Schnittstelle. Im Folgenden finden Sie eine verkürzte Version meiner Benutzeroberfläche, Implementierung, Server und 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); 
    } 
} 

P.S. In dem obigen Clientcode ist test.shortName wackelig unterstrichen und Eclipse schlägt vor, dass The static field TESTint.shortName should be accessed in a static way. Ich verstehe, dass der Client die Implementierung nicht erkennt, sondern nur die Schnittstelle - aber gibt es eine Möglichkeit, auf Testfelder zuzugreifen, nicht nur auf die Methoden? Ich habe viele Felder in meinem ursprünglichen Code und ich möchte nicht Getter für jeden einzelnen schreiben, wenn möglich.

+0

Wenn Sie viele Felder haben, können Sie sie in eine neue Klasse kapseln und eine Methode schreiben (sowohl in der Interface- als auch in der Implementierungsklasse), die eine Instanz dieser Klasse zurückgibt. Auf diese Weise können Sie durch Aufrufen einer einzelnen Remote-Methode Werte für alle Felder abrufen. –

+0

Sie benötigen weder RMI noch eine Instanz der Schnittstelle, um auf statische Endwerte einer Schnittstelle zuzugreifen. Deine Frage ergibt keinen Sinn. – EJP

+0

@EJP: Ich versuche nicht auf die endgültigen Werte einer Schnittstelle zuzugreifen. Ich versuche (oder der Client), auf Variablen auf der Serverinstanz von Test zuzugreifen. – Shahar

Antwort

1

RMI steht für Remote Method Invocation, was bedeutet, dass Sie remote eine Methode eines Objekts ausführen können. Die Implementierung der Methode befindet sich im Remote-System. Sie können niemals auf die Instanzvariablen der Implementierungsklasse zugreifen, die im Remote-System vorhanden sind, auch wenn sie öffentlich sind. Sie können nur öffentliche Methoden ausführen, die vom Interface zur Verfügung gestellt werden. Wenn Sie also auf die Variablen zugreifen möchten, müssen Sie sowohl in der Interface- als auch in der Implementierungsklasse öffentliche Getter-Methoden hinzufügen.

Verwandte Themen