Remote- und Server-Programmierung Dr. Wolfgang Süß Thorsten Schlachter
Remote Method Invocation (RMI) Servlets WebServices 2
Remote Method Invocation (RMI) Das Remote Method Invocation (RMI)-Framework existiert in Java bereits seit JDK 1.1. RMI ermöglicht eine transparente Kommunikation von Java- Anwendungen auf verschiedenen virtuellen Maschinen und auf anderen Rechnern. Notwendig: Stellvertreter (Stub) auf lokaler JVM Anwendung (Skeleton) auf entfernter JVM Stub (Client) Aufruf Parameter Skeleton (Server) Lokale JVM Rückgabe Entfernte JVM 3
Entfernter Aufruf im Detail (Prinzip) Aufruf Stub Serialisierung warten Deserialisierung Stub Deserialisierung Skeleton Ausführung Skeleton Serialisierung Weiterer Ablauf Lokale JVM Entfernte JVM 4
RMI-Aufrufe über die JVM-Registry Damit eine Java-Anwendung von einer anderen VM angesprochen werden kann, muss sie sich bei der lokalen Registry registrieren. manuell über Anwendung rmiregistry Über den Java-Code Wenn über RMI auch Klassen geladen werden sollen, muss man sich um einen passenden SecurityManager kümmern. Hinweis: Vor Java 1.5 musste man über einen speziellen Java-RMI-Compiler die Stubs und Skeletons erzeugen. Das machen neuere Java- Compiler automatisch und transparent für den Programmierer. 5
Server-Interface Erweitert das Interface java.rmi.remote Muss alle Remote-Methoden deklarieren Jede Methode muss java.rmi.remoteexception werfen. Bei Implementierung dieses Interface ist dies nicht nötig, da der Aufruf ja auf Client-Seite fehlschlägt. Beispiel: import java.rmi.remote; import java.rmi.remoteexception; public interface ServerInterface extends Remote { } public void method() throws RemoteException; 6
Server-Klasse (1) Implementiert Service-Interface Erweitert die Klasse UnicastRemoteObject UnicastRemoteObject kann eine RemoteException werfen (muss also deklariert werden!) import java.rmi.naming; import java.rmi.remoteexception; import java.net.malformedurlexception; import java.rmi.registry.locateregistry; import java.rmi.registry.registry; import java.rmi.server.unicastremoteobject; public class Server extends UnicastRemoteObject implements ServerInterface { Server() throws RemoteException { super(); } 7
Server-Klasse (2) } public static void main(string[] args) { try { LocateRegistry.createRegistry( Registry.REGISTRY_PORT); } catch (RemoteException ex) { System.out.println(ex.getMessage()); } try { Naming.rebind("Server", new Server()); } catch (MalformedURLException ex) { System.out.println(ex.getMessage()); } catch (RemoteException ex) { System.out.println(ex.getMessage()); } }... // method() implementieren! 8
Client-Klasse Im Client holt man sich eine Remote-Referenz eines Servers und kann auf dieser die Methoden des Server-Interfaces aufrufen:... try { String url = "//127.0.0.1/Server"; ServerInterface server = (ServerInterface) Naming.lookup(url); server.method(); } catch (Exception ex) {... }... URL: //<Server-Name>/<Registrierter Name> 9
Parameter und Rückgabewerte (Serialisierung( Serialisierung) Objekte müssen über RMI verschickt werden. Hierzu müssen das Objekte serialisiert ( Byte-Strom ) werden. Byte-Strom wird jeweils auf einer Seite eingepackt, auf der anderen Seite wieder ausgepackt. Viele Java-Basisklassen (String, Collection-Framework, etc.) sind in dieser Art serialisierbar. Andere Objekte (bzw. deren Klassen) müssen das Interface java.io.serializable implementieren. 10
Besonderheiten von Remote-Aufrufen Referenzen auf dasselbe Objekt liefern beim Remote-Aufruf unterschiedliche Objekte (sie werden ja zwei mal serialisiert!) Operator == liefert false Auch für Objekte, die Remote implementieren wird bei jeder Übertragung ein neues Stub-Objekt generiert. Operator == liefert false Verwendung von equals statt == funktioniert, muss allerdings ggf. Abfragen über das Netzwerk machen (Performanz). 11
Java-Servlets Idee: Java-Programme erweitern die Fähigkeiten von Servern Request/Response-Protokoll Unabhängig vom Serverprotokoll, aber meist mit Webservern (HTTP) verwendet 12
Servlets: : Funktionsweise request request WebApp1 response response WebApp2 WebApp3 Browser Webserver Webcontainer Servlets werden nicht direkt vom Webserver aufgerufen Objektorientierte CGIs : Java-Klassen statt Skript oder Programmes Bestandteil einer Webapplikation, verwaltet vom Webcontainer 13
Webcontainer (1) Stellt die Laufzeitumgebung für Webapplikationen (Servlets) zur Verfügung Kann an Webserver angebunden sein (z.b. als Modul in Apache) Kann auf einer anderen Maschine laufen als Webserver (Lastverteilung, Sicherheit/Redundanz) Kann als eine Art eigenständiger Server angesehen werden Erhält die Daten eines Requests vom Webserver Führt anhand der URL und der Konfiguration ein Mapping durch: Welche Webapplikation? Welche Ressource der Applikation wurde angefordert? Falls Servlet: Entsprechende Servletinstanz suchen oder erzeugen Servlet aufrufen Das Servlet erhält Request und Response 14
Webcontainer (2) Web-Applikation 1 Web-Applikation 2 Servlets Servlets Servlets JSPs Servlets Servlets Servlets JSPs Java-Klassen, JAR-Archive Java-Klassen, JAR-Archive Statische Inhalte (HTML, PDFs, Grafiken,...) Statische Inhalte (HTML, PDFs, Grafiken,...) Deployment-Descriptor web.xml Deployment-Descriptor web.xml 15
Web-Applikation: Struktur Wird in der Regel in einem war - Archiv ausgeliefert war ist wie jar - mit besonderer Struktur: Enthält ein öffentliches Wurzelverzeichnis, dessen Inhalte (z.b. HTML-Seiten) alle angezeigt werden können Ausnahme: privates Verzeichnis WEB-INF Deployment-Descriptor web.xml Verzeichnis classes mit den Servlets und benötigten Klassen Und ein lib - Verzeichnis für z.b. zusätzliche jar-files 16
web.xml (Ausschnitt) <web-app>... Servlet-Beschreibung <servlet> <servlet-name>hallowelt</servlet-name> <servlet-class>ba.srv.hallowelt</servlet-class> <init-param> <param-name>wer</param-name> <param-value>die Welt</param-value> </init-param> </servlet> Servlet-Mapping <servlet-mapping> <servlet-name>hallowelt</servlet-name> <url-pattern>/hallo</url-pattern> </servlet-mapping> </web-app> 17
Servlet: : Struktur InputStream ServletInputStream interface RequestDispatcher interface ServletContext interface ServletRequest interface Servlet init(servletconfig) service(servletrequest, ServletResponse) destroy() interface ServletConfig interface ServletResponse OutputStream ServletOutputStream abstract GenericServlet 18 Package javax.servlet
HttpServlet: : Struktur abstract GenericServlet interface HttpServletRequest HttpServlet init(servletconfig) destroy() doget() dopost() doput() interface HttpServletResponse 19
Lebenszyklus Servlet und ServletContainer ServletContainer Threadpool erzeugen Thread1 Thread2 HTTP Request Servletinstanz erzeugen init() Request Thread zuordnen service() Servlet X Initialisierung Service... HTTP Response Antwort Shutdown Threadpool beenden destroy() cleanup Servlet beenden / garbage collection Container beendet sich 20
Servlet-Lebenszyklus init() einmaliger Aufruf bei Servlet-Erzeugung guter Ort um init-parameter (z.b. web.xml) einzulesen, Ressourcen wie Datenbankverbindungen zu erzeugen service() hier wird die eigentliche Arbeit getan destroy() zum Aufräumen (z.b. DB-Verbindungen schließen) 21
HttpServlet Beispiel (1) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class SomeServlet extends HttpServlet { } public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { // request: eingehenden HTTP-Header und // Formulardaten lesen // response: HTTP-Antwort response // z.b. Cookies setzen PrintWriter out = response.getwriter(); // out: Inhalt an Browser sckicken } 22
HttpServlet Beispiel (2) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class HelloWorld extends HttpServlet { } public void doget(httpservletrequest request, HttpServletResponse response) throws ServletException, IOException { PrintWriter out = response.getwriter(); out.println("hello World"); } 23