4. Servlets – Ein kleiner Einstieg • Erinnerung: HTTP und HTML • Idee von Web‐Servern und Containern • Erstellung einfacher Servlets (zunächst software‐technisch übelst unstrukturiert) Literatur: • B. Basham, K. Sierra, B. Bates, Head First Servlets and JSP™, Second Edition, O’Reilly, Sebastopol (USA), 2008 • Sun, Java™ Servlet Specification Version 2.5 MR6 • Sun: http://java.sun.com/developer/onlineTraining/Servlets/ Fundamentals/servlets.html#usingJavaWebServer Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 147 Kurze Java‐Historie • Erfolgsfaktoren von Java – Portabilität – Wesentlich einfachere Syntax/Semantik als C++ – Frei verfügbar – Oberflächenentwicklung als Teil der Kernsprache (erst AWT, dann Swing) – Mit Applets erste einfach anzuwendende Technik, Programme im Browser laufen zu lassen • Heute – Applets spielen relativ geringe Rolle – Java die Allgemeinsprache – Java auch in Servern genutzt Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 148 Erinnerung: Internet‐Anwendungen • URL (Uniform Resource Locator) – Adressierung von Maschinen, Dateien und Programmen • URI (Uniform Resource Identifier) – Indirekte Adressierung, Server kennt evtl. physikalischen Pfad‐ und Dateinamen – Auch alleine als eindeutiger Identifikator (ohne konkrete Information dahinter nutzbar) • HTTP (Hypertext Transfer Protocol) – Kommunikation zwischen Client und Server (Request und Response) – GET : Parameter bei Anfrage an URL gehängt (sichtbar) – POST: Parameter im separaten Block (Body) unsichtbar Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 149 Konzept eines Seitenaufrufs HTTP-Request Web-Server Client HTTP-Response mit HTML-Datei im Body Server • HTML (Hypertext Markup Language) – Auszeichnungssprache mit festgelegten tags zum Aufbau der Ausgabe • Ebene 3/4 typisch TCP/IP, Session Ebene 5: HHTP, Darstellungsebene 6: HTML, Programmebene 7: JVM Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 150 HTTP‐Ablauf • Client: Request – get, post, head, put, ... URL HTTP1.x – Header Info: Accept, Cookie, ... – Body: Post‐Parameter • Server: Response – Statusmeldung: HTTP1.x 200 OK, oder 404 Error – Header Info: Content‐type, set‐cookie, ... – Body: Dokument • Verbindungsabbau • Protokoll ist zustandslos/gedächtnislos; Client wird bei erneutem Request ohne Trick nicht als Bekannter erkannt Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 151 HTTP‐Server selber schreiben public class Main { public static void main(String[] args) throws UnknownHostException, IOException { ServerSocket socket = new ServerSocket(80); Socket conn = socket.accept(); BufferedReader in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) System.out.println(line); conn.close(); } } GET /meinwww:80 HTTP/1.1 Host: localhost User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker … 152 Web‐Server mit Container nutzen • Servlet: Wortkreation aus den Begriffen „Server“ und „Applet“, (serverseitiges Applet) • Web‐Server leitet HTTP‐ Request an Servlet weiter • Servlet kann Antwort (HTML‐Code) berechnen • Servlet kann Anfrage‐ Informationen und Serverumgebung nutzen • Servlet kann mit anderen Servlets kommunizieren Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker Container 153 Erstes Servlet (1/2) import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ErstesMal extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } Komponentenbasierte Software‐ Prof. Dr. Entwicklung Stephan Kleuker 154 Erstes Servlet (2/2) } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { out.println("<html> <head>"); out.println("<title>Servlet ErstesMal</title>"); out.println("</head><body>"); out.println("<h1>Pfad:<br>" + request.getContextPath() + "</h1>"); out.println("</body></html>"); } finally { out.close(); } } Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 155 Typische Projektstruktur (Entwicklung) • Zentrale Konfigurationsdatei web.xml (Deployment Descriptor) • Ergänzt um Serverspezifika sun‐web.xml <servlet> <servlet-name>ErstesMal</servlet-name> <servlet-class>servlets.ErstesMal </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>ErstesMal</servlet-name> <url-pattern>/ErstesMal</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 156 Erstes komplettes Beispiel (1/4) <html> <head> <title>Bewertung</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> </head> <body> <form name="auswertungsform" action="Auswertung" method="POST"> Verteilte ID eingeben: <input type="text" name="idFeld" value="" size="20" /><br> <input type="checkbox" name="urteil" value="ausgezeichnet" checked="checked" /> ausgezeichnet <br> <input type="checkbox" name="urteil" value="faszinierend" checked="checked" /> faszinierend <br> <input type="checkbox" name="urteil" value="solala" /> solala <br> <input type="submit" value="Abschicken" name="abschicken"/> </form> </body> </html> Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 157 Erstes komplettes Beispiel (2/4) Web‐Seite und Projektaufbau Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 158 Erstes komplettes Beispiel (3/4) public class Auswertung extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String id = request.getParameter("idFeld"); String [] werte = request.getParameterValues("urteil"); try { out.println("<html> <head>"); out.println("<title>Bewertungsergebnisse</title>"); out.println("</head> <body>"); out.println("<h3>Auswertung mit ID: "+id+ "</h3><ul>"); if(werte!=null) for(int i=0;i<werte.length;i++) out.println("<li>"+werte[i]+"</li>"); out.println("</ul></body></html>"); } finally { out.close(); } } ... Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 159 Erstes komplettes Beispiel (4/4) In web.xml <welcome-file-list> <welcome-file>bewertung.html</welcome-file> </welcome-file-list> Ausgabe Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 160 Deployment (Ausblick) • Standard definiert u. a. : – web.xml in WEB‐INF – Programmierte Klassen in Ordner classes • war = Web‐Archive (installierbar durch Drag und Drop) • In Netbeans empfiehlt sich Blick in Ordner build oder dist Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 161 Ablauf bei Servlet‐Nutzung (1/2) Web-Server GET … Client GET Web Server Steuerung … erzeugt Servlet Steuerung (Container) erzeugt :Request :Response liest erzeugt Servlet Thread Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker Servlet (in Java) 162 Ablauf bei Servlet‐Nutzung (2/2) HTTP … Web-Server <HTML> <HTML> … Web Server Steuerung … Servlet Steuerung (Container) Client liest <HTML> … :Response schreibt <HTML> … Servlet Thread Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 163 Aufgaben des Containers • Kommunikation zwischen Servlet und Web‐Server • Container steuert Erzeugung und Löschung von Servlets • Container ermöglicht Mehrfachnutzung; neue Threads für benötigte Servlets – Hinweis: Container garantiert keine Threadsicherheit; gemeinsam genutzte Objekte muss Entwickler synchronisieren • Container‐Verhalten über XML‐Deployment‐Descriptor konfigurierbar • Container erlaubt Zusammenarbeit von Techniken (‐> JSP) Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 164 Zwischenfazit • Servlets erlauben mit Hilfe eines Web‐Servers und zugehöriger Container die Erzeugung dynamischer HTML‐ Seiten • Servlet‐Konfiguration über einen Deployment‐Descriptor • Servlets können klassische und selbst erstellte Java‐Klassen nutzen • Container stellt Objekte zur Aufgabenlösung zur Verfügung (einige mehr, als bis jetzt gezeigt) • Alles in Servlets zu packen, ist schlechte Idee – Keine Trennung der Oberfläche und der Geschäftslogik – println ist fehlerträchtig in Entwicklung – Web‐Designer können kein Java Komponentenbasierte Software‐ Entwicklung Prof. Dr. Stephan Kleuker 165