Praktikum aus Softwareentwicklung 2 Java Servlets Praktikum aus Softwareentwicklung 2 Java Praktikum – SS 2010 – [email protected] 1 Praktikum aus Softwareentwicklung 2 Java Servlets • • Architektur – Merkmale, Servlet-Methoden, Lebenszyklus, … Sessions – Session Tracking API, Cookies, … Java Praktikum – SS 2010 – [email protected] 2 Praktikum aus Softwareentwicklung 2 Servlets Motivation ● ● Web-Browser als Benutzerschnittstelle für Anwendungen ● Standardisiert ● Keine Installation der Anwendung notwendig Web-Server implementiert Anwendungslogik ● Dynamische Generierung der Benutzerschnittstelle (CGI, SSI, Servlets, JSP, PHP etc.) – ● Darstellung: HTML für GUI - http://de.selfhtml.org/index.htm HTTP als Kommunikationsprotokoll zwischen Server und Benutzerschnittstelle (Browser) Java Praktikum – SS 2010 – [email protected] 3 Praktikum aus Softwareentwicklung 2 Servlets Architektur Server Client ServletRequest HTTP Request Servlet 1 Servlet 2 HTTP Response Snoopy.html: <HTML><BODY><P>Some text</P> Servlet n ServletResponse <FORM METHOD="GET“ ACTION="http://somehost.com:80/servlets/SnoopServlet"> <INPUT TYPE="submit" NAME="sendFile" VALUE="Run the servlet"> </FORM> Dynamische Generierung ... Java Praktikum – SS 2010 – [email protected] 4 Praktikum aus Softwareentwicklung 2 Servlets Merkmale • Standardisiertes HTTP Server Interface ● Servlets implementieren dieses Interface • Servlets werden in einem "Container" ausgeführt ● Die Servlet-Engine, ist zugleich HTTP-Server • Zur Implementierung einer Client/Server Anwendung basierend auf HTTP Session Tracking API zur Simulation von Sessions in HTTP • Java Praktikum – SS 2010 – [email protected] 5 Praktikum aus Softwareentwicklung 2 Servlets Entstehung • ~1995 CGI (Common Gateway Interface) ● ● ● • • • • Mechanismus zur Erweiterung der Funktionalität des Web Schleche Performanz > FastCGI Keine Interaktion mit Webserver, weil eigener Prozess (z.B. kann ein CGI-Prozess nicht in die Logdatei des Servers schreiben) 1996 stellt Netscape sogenannte "Server-side Applets" vor 1996 präsentiert W3C "resources" ● server-seitige Java Module 1997 Servlet - standardisierte Technologie ~1999 Erweiterungen: ● SSI - Server Side Includes (Netscape, heute AOL) ● ASP - Active Server Pages (Microsoft) ● JSP - Java Server Pages (Sun Microsystems) Java Praktikum – SS 2010 – [email protected] 6 Praktikum aus Softwareentwicklung 2 Servlets HTTP Request/Response Interface • HTTP ist definiert in RFC-2068 (www.ietf.org/rfc.html) • Browser (User-Agent) sendet Request 1. Zeile mit Requestmethode, z.B. GET oder POST, und URL-Pfad GET: Download von einer URL; ohne Body; Request-Parameter als Teil des URL sind möglich, z.B. /login?user=xxx POST: wie GET, aber Parameter sind im Request-Body kodiert • Weiters PUT, DELETE, HEAD, OPTIONS, TRACE Es folgen Header-Zeilen optional einen Request-Body (enthält z.B. Formulardaten) Server antwortet mit Response Statuszeile Header-Zeilen, z.B.: Content-Type, Cookies, etc. optional ein Response-Body, z.B. HTML, GIF, etc. Java Praktikum – SS 2010 – [email protected] 7 Praktikum aus Softwareentwicklung 2 Servlets Klassen Java Praktikum – SS 2010 – [email protected] 8 Praktikum aus Softwareentwicklung 2 Servlets Webapplication - <name>.war • Web Archive (WAR) als Standard – Das Executable einer Web Applikationen als ZIP – Installation und Ausführung auf Servlet Containern beliebiger Hersteller. – Definiert die Verzeichnisstruktur und das Verhalten einer Webapplikation • Deployment Descriptor: web.xml • Verzeichnisstruktur – /> *.html... – /META-INF/> Manifest – /WEB-INF/> web.xml – .../classes/> class Files – .../lib/> Libraries (JARs) Java Praktikum – SS 2010 – [email protected] 9 Praktikum aus Softwareentwicklung 2 Servlets HTTP Servlet Methoden import javax.servlet.*; import javax.servlet.http.*; public class SnoopServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {} public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {} public void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {} public void doDelete(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {} public void init(ServletConfig config) throws ServletException {} public void destroy() {} } Java Praktikum – SS 2010 – [email protected] 10 Praktikum aus Softwareentwicklung 2 Servlets Lebenszyklus • Methoden, die zur Steuerung überschrieben werden können, werden ausschließlich vom Servlet Container aufgerufen: void init(…); ... void doXXX(…); ... void destroy(); • Lebenszyklus: – Aufruf von init() nach dem Laden des Servlets – doXXX() bei Anfragen von Clients – Beim Beenden wird destroy() aufgerufen Java Praktikum – SS 2010 – [email protected] 11 Praktikum aus Softwareentwicklung 2 Servlets Deployment Deskriptor: web.xml • Spezifikation der Servlets, Initialisierungsparameter und URLs (optional) <web-app> <servlet> <servlet-name>login</servlet-name> <servlet-class>LoginServlet</servlet-class> <init-param> <param-name>foo</param-name> <param-value>bar</param-value> </init-param> Servlet-URL: </servlet> http://localhost:8080/test/login ... <servlet-mapping> <servlet-name>login</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> ... <session-config> <session-timeout>30</session-timeout> </session-config> </web-app> Java Praktikum – SS 2010 – [email protected] 12 Praktikum aus Softwareentwicklung 2 Servlets Initialisierung • Methode init() – – • Wird vor dem ersten doXXX()-Aufruf ausgeführt throws UnavailableException, falls das Servlet nicht benutzbar ist Parameter für bestimmtes Servlet: getInitParameter("forwardURL"); <servlet> … <init-param> <param-name>forwardURL</param-name> <param-value>/main</param-value> </init-param> … • Parameter für Applikation, also für alle Servlets: getServletContext().getInitParameter("name"); <web-app> … <context-param> <param-name>name</param-name> <param-value>a_val</param-value> </context-param> … Java Praktikum – SS 2010 – [email protected] 13 Praktikum aus Softwareentwicklung 2 Servlets HttpServletRequest • • Zugriff auf Header- bzw. Body-Daten des HTTP Request HTTP-Parameter (Transparent GET oder POST) – – – – • • Session ID: getRequestedSessionId() - Session Tracking Weitere Header-Daten – • String param = request.getParameter(name); String[] params = request.getParameterValues(name); Enumeration p = request.getParameterNames(); String q = request.getQueryString(); (für HTTP GET) z.B.: getRemoteHost(), getRemoteUser(), getLocale(),... Body-Daten (POST) – – – Parameter mit getParameter() Header-Daten getContentType() und getContentLength() getReader() für Textdaten bzw. getInputStream() für Binärdaten Java Praktikum – SS 2010 – [email protected] 14 Praktikum aus Softwareentwicklung 2 Servlets HttpServletResponse • • Header – response.setContentType( "text/html; charset=ISO-8859-1"); – Weitere Methoden: setContentLength(len), addCookie(cookie), ... – Auch request.getSession() kann implizit Header-Daten (Cookie) erzeugen Body erst nach den Header-Daten schreiben – PrintStream out=response.getWriter() für Textdaten • – Zeichencodierung entsprechend dem bei setContentType angegebenen charset response.getOutputStream() für Binärdaten Java Praktikum – SS 2010 – [email protected] 15 Praktikum aus Softwareentwicklung 2 Servlets Generieren von HTML • Das Generieren von HTML kann durch einfache println Anweisungen erfolgen. Z.B. out=response.getWriter(); out.println("<HTML><HEAD><TITLE>Hello World</TITLE>"); ... – • Online HTML-Tutorial: http://selfhtml.teamone.de/html/ Einen Weg zur Trennung von HTML und Java-Code stellt die Verwendung von Templates bzw. Server Side IncludeMechanismen dar, z.B. JSP (Java Server Pages) <HTML><HEAD><TITLE>Hello World</TITLE></HEAD> <BODY><TABLE> <% Iterator i=all.iterator(); while(i.hasNext()) { %> <TR><TD> ... Java Praktikum – SS 2010 – [email protected] 16 Praktikum aus Softwareentwicklung 2 Servlets Beispiel „doGet()“ public void doGetPostRequest (HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { PrintWriter out; res.setContentType("text/html"); out = res.getWriter(); out.println("<html><head><title>Snoop Servlet</title></head>"); out.println("<body bgcolor=\"#FFFFFF\">"); out.println("<h1>Requested URL:</h1>"); out.println (getRequestURL ().toString ()); log(req.getRequestURL().toString ()); Enumeration e = req.getHeaderNames(); while (e.hasMoreElements()) { String name = (String)e.nextElement(); out.println(" " + name + ": " + req.getHeader(name)); } … e = req.getParameterNames(); … out.close(); } Java Praktikum – SS 2010 – [email protected] 17 Praktikum aus Softwareentwicklung 2 Servlets Fehler, Logging • Rückgabe von Fehlermeldungen an den Client durch die Methode sendError, z.B. public void doGet (HttpServletRequest req, HttpServletResponse res) throws … … res.sendError(HttpServletResponse.SC_FORBIDDEN); • Logging – – Andwendungs-Logs mit Log4J oder Java Logging API… Eintrag im Logfile des Servlet Containers … catch(Exception e) { log("oops", e); Java Praktikum – SS 2010 – [email protected] 18 Praktikum aus Softwareentwicklung 2 Servlets Interaktion via Browser • Kontrollfluss: Links – • HTML-Output eines Servlet enthält Links auf andere Servlets: out.println("<A HREF=/MoreServlet>Weiter</A>"); Datenfluss: Request-Parameter – – – HTTP-Request enthält Daten, die als Request-Parameter an das Ziel-Servlet übermittelt werden Als Teil der URL, z.B.: out.printf( "<A HREF=\"/UserDetailServlet?userId=%s\">%s</A>%n", user.getId(), user.getName()); Felder in einem Formular, z.B.: out.printf( "<FORM ACTION=\"/DeleteUserServlet\" METHOD=GET>"+ "<INPUT TYPE=HIDDEN NAME=userId VALUE=%s>"+ "<INPUT TYPE=SUBMIT VALUE=\"Delete!\"></FORM>%n", user.getId()); Java Praktikum – SS 2010 – [email protected] 19 Praktikum aus Softwareentwicklung 2 Servlets Interaktion am Server • Kontrollfluss: Weitergabe eines Requests mittels RequestDispatcher, z.B.: RequestDispatcher d = req.getRequestDispatcher("ServletZwei"); • – Delegation eines Request von ServletEins and ServletZwei d.forward(request, response); es dürfen noch keine Response-Daten gesendet worden sein. – Einbindung von ServletZwei in ServletEins d.include(request, response); die Ausgabe der URL wird in den Response eingefügt. Datenafluss: – – request.setAttribute(name, object) und object = request.getAttribute(name) Servlet.getServletContext().setAttribute(name, object) object = Servlet.getServletContext().getAttribute(name) Java Praktikum – SS 2010 – [email protected] 20 Praktikum aus Softwareentwicklung 2 Servlets Beispiel: forward() und include() public class PresentationServlet extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String item = req.getParameter("item"); if(item == null) { req.setAttibute("exception", new Exception("Item not found")); getServletContext() .getRequestDispatcher("/servlet/ErrorServlet") .forward(req, res); } else { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print("<HTML><HEAD><TITLE>Item " + item + "</TITLE>"+ "</HEAD><BODY>Item " + item + ":<P>"); getServletContext() .getRequestDispatcher("/servlet/ItemServlet?item="+item) .include(req, res); out.print("</BODY></HTML>"); } } } Java Praktikum – SS 2010 – [email protected] 21 Praktikum aus Softwareentwicklung 2 Java Servlets • • Architektur – Merkmale, Servlet-Methoden, Lebenszyklus, … Sessions – Session Tracking API, Cookies, … Java Praktikum – SS 2010 – [email protected] 22 Praktikum aus Softwareentwicklung 2 Servlets Multithreading / Kontext • • Zugriffe auf den Server von mehreren Clients gleichzeitig – Ein Thread pro Client – Synchronisierung beim Zugriff auf gemeinsam verwendete Objekte, z.B. static-Variablen Servlet Variablen sind nicht im Client Kontext – – – Nur ein Servlet Objekt für alle Clients in der Servlet-Engine Aber: jeder Client hat sein 'eigenes' Request, Response, Session Objekt Daher: Instanzvariablen im Servlet vermeiden, sondern Objekte zu Session oder Request Speichern: session.setAttribute("com.uni.MyParamBean",paramBean); session.getAttribute("com.uni.MyParamBean"); Java Praktikum – SS 2010 – [email protected] 23 Praktikum aus Softwareentwicklung 2 Servlets Session Tracking Problem: Zustandslosigkeit von HTTP (state-less) – es gibt keine "Sessions", d.h., jeder Request wird individuell und unabhängig von den anderen betrachtet – Client Kontext in Anwendungen notwendig • ● Verschiedene Varianten um Zustandsinformation einem Request (Client) zuzuordnen: – (1) Versteckte Felder in Formularen – (3) Zustandsinformation in Link kodieren – (4) HTTP Cookies – (5) Java Servlet Session Tracking API Java Praktikum – SS 2010 – [email protected] 24 Praktikum aus Softwareentwicklung 2 Servlets Session Tracking API (1/2) • • Ab Java Servlets 2.0 Unterstützung hängt vom verwendeten Server , z.B. – – – • • Jeder Benutzer eines Servers hat genau ein Session Objekt: HttpSession session = request.getSession(); if (session.isNew())… – – • werden Cookies verwendet, oder URL Kodierung (falls Cookies nicht verfügbar sind) URL-Kodierung mittels response.encodeURL(url); false: ein neues Session-Objekt mit Session ID wird erzeugt und im Servlet Container gespeichert, Session ID wird im Response mitgeschickt true: falls mit dem Request eine gültige Session ID mitgeschickt wurde Session IDs als Cookies – Alternativ kann die Session ID in URLs als Parameter kodiert werden Java Praktikum – SS 2010 – [email protected] 25 Praktikum aus Softwareentwicklung 2 Servlets Session Tracking API (2/2) • Im Session-Objekt können sessionspezifische Daten gespeichert werden, z.B. Benutzername, temporäre Daten, etc. – – – – • session.setAttribute(String name, Object value); Object session.getAttribute(String name); session.removeAttribute(String name); Enumeration session.getAttributeNames(); Eine Session hat eine begrenzte Gültigkeitsdauer – Explizite Invalidierung, z.B. beim Logout, mit session.invalidate() – Automatisch nach einer bestimmten Zeit, Default ist 30 min.: session.setMaxInactiveInterval(int seconds) – Benachrichtigung über das Ende einer Session durch Implementierung von HttpSessionBindingListener Java Praktikum – SS 2010 – [email protected] 26 Praktikum aus Softwareentwicklung 2 Servlets Session Beispiel • Verwenden von Sessions … HttpSession session = req.getSession(true); … out.println( "<LI>Creation time <b>"+new Date(session.getCreationTime())+"</B>"); out.println("<LI>Session ID <b>"+session.getId()+"</B>"); out.println("<LI>Session is new <b>"+session.isNew()+"</B>"); … session.setAttribute("aKey", "aValue"); … Enumeration attrs = session.getAttributeNames(); … an=attrs.nextElement().toString(); out.println( "<LI>Name <b>"+an+"</b>, value <b>"+session.getAttribute(an)+"</B>"); … Java Praktikum – SS 2010 – [email protected] 27 Praktikum aus Softwareentwicklung 2 Servlets Arten von "Servlet-Variablen" Art der Variable Attribute eines ServletContext Sichtbarkeit Lebensdauer Alle Servlets im ServletContext Bis zum Ende der WebApplikation Servlets im ServletContext, die Requests der Session behandeln Bis zum Ablauf der Session Instanzvariablen eines Servlet Methoden des Servlet Servlet.init() bis Servlet.destroy() Attribute eines ServletRequest Servlets, die den Request behandeln Bis zum Ende der Request-Behandlung Attribute einer Session Java Praktikum – SS 2010 – [email protected] 28 Praktikum aus Softwareentwicklung 2 Servlets Versionen, Doku • • Sun Spezifikationen mit Apache Tomcat – Java Servlets 2.2 + Tomcat 3.3 – Java Servlets 2.3 + Tomcat 4 und 5.5 – Java Servlets 2.4,2.5 + Tomcat 6 – Java Servlets 3.0 (Draft – April 2010) Doku – Servlet API – – http://java.sun.com/products/servlet/ Tomcat 6 – http://tomcat.apache.org/tomcat-6.0-doc/index.html Java Praktikum – SS 2010 – [email protected] 29 Praktikum aus Softwareentwicklung 2 Ende der 4. Übung Java Praktikum – SS 2010 – [email protected] 30