Web services in 21 Minuten Wir haben ... K1 Proxy Proxy RMI K2 Probleme RMI ist Java-spezifisch CORBA nicht, aber komplex komplexe Programmierung Kommunikation durch Firewalls RMI z.B. Port 1099 (normal zu) konkurrierende Standards Idee Browser Webserver ServletEngine Servlet Servlet Servlet Servlet Browser schickt Anfrage (mit Parametern) an Servlet und kriegt generierte Antwort; wenn Browser = Client (-Programm) Engine = ORB Servlet = Server (Objekt) HTTP= Funktionsparameter Parameter dann RPC ! Schwierigkeiten Parameter nicht typisiert Ergebnis nicht strukturiert Statuscode + irgendwas (z.B. Text) keine (standardisierte) Fehlerbehandlung Lösung. Anfrage + Antwort als XML XML-RPC SOAP Einschub: REST Representational State Transfer Architecture HTTP Client Webserver Resourcen Darstellung der Resource, z.B. HTML-Darstellung eines Datensatzes in DB (nicht (!) der Datensatz selbst) Darstellungen der Resourcen (üblicherweise XML) werden bewegt/manipuliert (verschiedene HTTP-Methoden !) Beispiel: GET /warenkorb/4711 HTTP-Methoden GET: Darstellung der Resource lesen POST: Resource ändern PUT: Resource erzeugen DELETE: Resource löschen HEAD: Metadaten lesen Idee: Server hat Resourcen, die über URI identifiziert werden. Funktion durch HTTP-Methode. Interaktion ist stateless (Skalierbarkeit !) Objekte als Resourcen [http://www.oio.de/public/xml/rest-webservices.htm] Beispiel: google calendar mit API CalendarService myService = new CalendarService("tillh-webcal-1"); myService.setUserCredentials("[email protected]", "geheim"); new EventFeed().declareExtensions(myService.getExtensionProfile()); EventFeed myFeed = myService.getFeed(feedUrl, EventFeed.class); EventEntry calEntry = null; if (myFeed.getEntries().size() > 0) { for (int n = 0; n < myFeed.getEntries().size(); n++) { calEntry = (EventEntry) myFeed.getEntries().get(n); System.out.println("calEntry.getTitle().getPlainText()); } } } SOAP Frage: <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ns1:getBestand xmlns:ns1="http://www.tillh.de/"> <ArtikelNr xsi:type="xsd:string">4711</testParam> </ns1:getBestand> </SOAP-ENV:Body> </SOAP-ENV:Envelope> und Antwort <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <SOAP-ENV:Body> <ns1:getBestandResponse xmlns:ns1="http://www.tillh.de/"> <result xsi:type="xsd:int">127</result> </ns1:echoStringResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope> wie ? unabhängig von Plattform Programmiersprache Transport-Protokoll (HTTP, SMTP, ...) trotzdem mühsam (von Hand) zu programmieren verschiedene Tools für Client und Server hier: apache axis Server public class StoreService { public int getBestand(String ProductID) { Bestand b = new Bestand(); // rechnen ... return 42; } } als “.jws” Datei im axis webapps-Verzeichnis speichern “Now for step 2... hm, wait a minute. You're done! “ [axis User guide: http://ws.apache.org/axis/java/user-guide.html] Client mal einfacher: require 'soap/rpc/driver' proxy = SOAP::RPC::Driver.new( "http://localhost:8080/axis/StoreService.jws", "http://localhost:8080/axis/StoreService.jws") proxy.add_method('getBestand', 'ID') puts "verfuegbar: #{proxy.getBestand("2")}" (ruby) Client contd. mal komplizierter: public class getBestand { public static void main(String[] args) throws Exception { try { String ProductID = "2"; URL endpoint = new URL("http://localhost:8080/axis/StoreService.jws"); Service s = new Service(); Call c = (Call) s.createCall(); c.setTargetEndpointAddress(endpoint); c.setOperationName("getBestand"); Object[] params = new Object[] {ProductID}; Integer bestand = (Integer) c.invoke(params); System.out.println("Bestand fuer Produkt " + ProductID + ": " + bestand); } catch (Exception e) { e.printStackTrace(); } } } (Java) oder ... warum nicht wie bei RMI ? Proxy-Objekte könnten automatisch erzeugt werden können sie auch axis kann zu Web-Service (automatisch) WSDL (Web Service Description Language) generieren (?WSDL an URL anhängen) mit Proxy mit java org.apache.axis.wsdl.WSDL2Java -p store StoreService.wsdl public class getBestand { public static void main(String args[]) { String ProductID = "2"; StoreServiceServiceLocator loc = new StoreServiceServiceLocator(); try { StoreService_PortType service = loc.getStoreService(); System.out.println(service.getBestand(ProductID)); } catch (Exception e) { e.printStackTrace(); } } } später mehr (SOA), jetzt ab zur Kasse ......