# applet servlet kommunikation



## rohn (5. Okt 2004)

tachchen
ich schreibe gerade an einer art onlinegame indem ein applet auf einem server eine socketverbindung herstellen soll von dem es aber nicht geladen wird und ein datenaustausch via objektserialisierung stattfindet.
Prinzipiell weiß ich das man das Applet dazu signieren muß aber habe einiges probiert und aus verzweiflung aufgegeben,selbst mit `Jarkive`)
Ich habe nun ein Servlet erstellt, welches über Http Request einen ObjektInputStream vom Applet entgegennimmt und seinerseits eine socketvervindung öffnet(bzw öffnen soll).
Auf dem Server soll dann die Verarbeitung der Daten erfolgen und das Resultat über die Socketverbindung an das Servlet zurückgesendet werden und das Servlet schickt dann über Http Response einen ObjecktOutputstream an den client zurück der das Applet geladen hat. So, denke ich, müßte es doch funzen oder?
Leider habe ich das Problem das ich eine "StreamCorruptedException" bekomme wenn ich den Http InputStream einlese weil die Headerinfo noch dranhängt denk ich mal.
Wie kann ich denn den Header von meinem eigentlichen relevanten Code trennen?  
Bin sehr dankbar für eventuelle Lösungsansätze...


----------



## semi (5. Okt 2004)

Schicke die serialisierten Objekte als "octet-stream".
z.B.

Applet-seitig

```
URLConnection con = url.openConnection();
con.setDoInput(true);
con.setDoOutput(true);
con.setDefaultUseCaches(false);
con.setUseCaches(false);
con.setRequestProperty("Content-Type", "application/octet-stream");

ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(con.getOutputStream()));
out.writeObject(request);
out.flush();
out.close();

ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(con.getInputStream()));
Object response = in.readObject();
in.close();
```

Servlet-seitig

```
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(request.getInputStream()));
Object request = in.readObject();
in.close();
...
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(response.getOutputStream()));
response.setStatus(HttpServletResponse.SC_OK);
response.setContentType("application/octet-stream");
out.writeObject(response);
out.flush();
// Nicht schliessen!!!
```

Gruß,
Michael


----------



## semi (5. Okt 2004)

Übrigens, das ganze lässt sich so automatisieren, dass man
mit Remote-Objekten so arbeiten kann als ob sie lokal (beim Applet)
wären.

Das folgende Beispiel sollte Dich auf paar Idee bringen

```
interface Hello {
  void hello(String s);
}

class ServiceLocator {
  public static Object createService(Class type, URL url) {
    return Proxy.newProxyInstance( type.getClassLoader(), new Class[] { type }, new HTTPInvocationHandler(url));
  }

  static class HTTPInvocationHandler implements InvocationHandler {
    private URL url;

    public HTTPInvocationHandler(URL url) {
      this.url = url;
    }

    public Object invoke(Object proxy, Method method, Object[] args) {
      System.out.println("invoke: " + method.toString());
      // Hier über HTTP den Aufruf weiterleiten und das Ergebnis
      // dann zurückgeben
      // Die Information über die serverseitig auszuführende Instanz/Methode
      // kannst Du in einem serialisierbaren Info-Objekt an das Servlet übergeben.
      // Als Antwort kriegst Du dann auch ein solches Objekt mit Rückgabedaten, 
      // Exceptions etc. zurück

      // 'null' nur hier in dem Test!!! Sonst Daten vom Serveraufruf
      return null;
    }
  }
}

public class DynamicProxy {
  public static void main(String[] args) {
    // Hier neben Interface auch die URL des Servlets übergeben. Im Beispiel ist es 'null'
    Hello f = (Hello)ServiceLocator.createService(Hello.class, null);
    f.hello("Hallo"); // Das würde über's HTTP gehen oder von mir aus auch HTTPS, je nach Implementierung
  }
}
```
Serverseitig brauchst Du zu jedem bekannten Interface eine Implementierung
 (im Beispiel HelloImpl implements Hello) und irgendeine Dispatcherklasse, die eine Instanz einer 
solchen Implementierung erstellt und die entsprechende Methode, mit den gegebenen Parametern 
aufruft und das Ergebnis dann wieder gepackt zurück zum Applet übergibt.

Einmal korrekt implementiert, dann brauchst Du jeweils nur das Interface und die Implementierung
zu schreiben. Die Implementierung muss Applet-seitig nicht bekannt sein.

Gruß,
Michael


----------

