Ein Servlet ist ein Java-Programm, das serverseitig läuft und typischerweise HTML Code generiert, der an den Browser als Antwort auf einen Request zurückgeschickt wird. Daneben kann es auch andere Operationen geben, wie z.B. Datenbank- und Dateizugriffe.
Das Servlet ist keine eigenständige Applikation (hat keine main() Methode), sondern kann nur innerhalb eines Containers laufen. Als Container werden verschiedene Server verwendet, u.a. das jserv Modul des Apache-Webservers, sowie Tomcat (am Schulungsraumserver, Version 5.0.14, Nov 2003).
Gegenüber der klassischen CGI-Lösung sind kürzere Antwortzeiten möglich, weil nicht bei jedem Request serverseitig ein neuer Prozeß gestartet werden muß. Aufwendige Operationen können einmalig ablaufen (z.B. beim ersten Request an eine bestimmte Applikation) und dann für weitere Requests zur Verfügung stehen, z.B. der Verbindungsaufbau zu einer Datenbank. Mit Session Attributes können serverseitig Werte gespeichert werden und damit auf einfache Art Warenkörbe und ähnliches implementiert werden.
Auf dem Schulungsraumserver balrog.wu-wien.ac.at ist Tomcat installiert. Tomcat Web Applikationen bestehen aus HTML Seiten und Java Servlets. Dabei ist folgende Verzeichnis-Struktur ubd Konfiguration zu beachten ($HOME steht für das home directory, z.B. /home/j8325200):
*.html in $HOME/webapp
*.class in $HOME/webapp/WEB-INF/classes
*.java in $HOME/webapp/src
web.xml in $HOME/webapp/WEB-INF. Wird vom Skipt web-xml erzeugt, das
Sie immer starten, wenn Sie ein neues Servlet geschrieben haben.
URL auf HTML: z.B. http://balrog.wu-wien.ac.at:8080/j8325200/index.html
URL auf Servlets: z.B.
http://balrog.wu-wien.ac.at:8080/j8325200/servlet/Hello
Hilfreich: ein Makefile im src/ Verzeichnis. Nach jeder Änderung der .java Dateien wird mit dem Befehl 'make' neu kompiliert und die .class Datei ins WEB-INF/classes Verzeichnis gestellt.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*;Die Servlet Klasse gehört zu HttpServlet und enthält die doGet und/oder die doPost Methode.
public class Hello extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse res) {Ausgaben gehen über den PrintWriter aus dem Resultat.
res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("....");
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Hello extends HttpServlet { protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HTML><HEAD><TITLE>Hello!</TITLE>"+ "</HEAD><BODY>Hello, its j8325200!</BODY></HTML>"); out.close(); } }
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; public class Select extends HttpServlet { PrintWriter out; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); out = res.getWriter(); klist(); } void klist () { String url = "jdbc:oracle:thin:@balrog:1521:aidb2"; String userName = "j8325200"; String password = "..."; try { DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); Connection conn = DriverManager.getConnection (url, userName, password); Statement stmt = conn.createStatement (); ResultSet rset = stmt.executeQuery ("select NR, NAME from KUNDE"); out.print("<HTML><BODY><TABLE>"); while (rset.next ()) { out.println ("<TR><TD>" + rset.getString("NR") + "<TD>" + rset.getString("NAME")); } } catch (SQLException e) { out.print("Caught SQLException!"); } out.print("</TABLE></BODY></HTML>"); out.close(); } }
Zum Daten erfassen verwenden wir HTML-Formulare, deren action Parameter auf das Insert-Servlet zeigt. Dort können wir dann mit req.getParameter() bestimmte Parameter aus dem HTML-Formular abfragen.
Die HTML-Formulare (z.B. Insert.html) kommen ins webapp/ Verzeichnis am balrog-Rechner, d.h. die gesamte Applikation wird mit dem Tomcat-Server betrieben. Auch die Startseite Ihres Online-Shops sollte dort sein. Der URL dorthin lautet z.B. http://balrog.wu-wien.ac.at:8080/jMatNr/Shop.html
Im Servlet verwenden Sie statt doGet die doPost() Methode, damit die Daten nicht über den URL mitgegeben werden.
public class Insert extends HttpServlet { PrintWriter out; public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String nr = req.getParameter("NR"); String name = req.getParameter("NAME"); String adresse = req.getParameter("ADRESSE"); ...
und so weiter wie gehabt. Hier steht dann das SQL-Insert, das natürlich wieder mit Hilfe von Exceptions auf Fehler Rücksicht nehmen muß.
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; public class Insert extends HttpServlet { PrintWriter out; public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String nr = req.getParameter("NR"); String name = req.getParameter("NAME"); String adresse = req.getParameter("ADRESSE"); res.setContentType("text/html"); out = res.getWriter(); String url = "jdbc:oracle:thin:@balrog:1521:aidb2"; String userName = "j8325200"; String password = "j8325200"; try { DriverManager.registerDriver(new oracle.jdbc.OracleDriver()); Connection conn = DriverManager.getConnection (url, userName, password); Statement stmt = conn.createStatement(); ResultSet rset = stmt.executeQuery( "insert into KUNDE (nr, name, adresse)" + " values(" + nr + ", \'" + name + "\', \'" + adresse + "\')"); out.print("OK."); } catch (SQLException e) { out.print("FEHLER!! SQLException: " + e.getMessage()); } out.close(); } }
Mit Java Servlets können serverseitig Werte gespeichert werden, die mit einer Browser-Sitzung verbunden sind. Diese session attributes sind nützlich, um Dinge wie Login-Information oder Warenkörbe auf einfache Art zu implementieren.
Jede Session hat ein ID:
HttpSession session = req.getSession(true); String id = session.getId(); out.print("session id = " + id);
Ein Attribut kann gesetzt werden:
try { session.setAttribute("s", "Mozilla"); out.print("setting session Attribute s = " + "Mozilla"); } catch (Exception e) { out.print("Error setting session Attribute!"); }
Und abgefragt werden:
try { String s = session.getAttribute("s").toString(); out.print("getting session attribute s = " + s); } catch (Exception e) { out.print("Error getting session attribute!"); }
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Session extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session; res.setContentType("text/html"); res.setHeader("pragma", "no-cache"); PrintWriter out = res.getWriter(); session = req.getSession(true); String id = session.getId(); out.print("session id = " + id); try { session.setAttribute("s", "Mozilla"); out.print(", setting session Attribute s = " + "Mozilla"); } catch (Exception e) { out.print("Error setting session Attribute!"); } out.close(); } }
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Session2 extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session; res.setContentType("text/html"); res.setHeader("pragma", "no-cache"); PrintWriter out = res.getWriter(); session = req.getSession(true); String id = session.getId(); out.print("session id = " + id); try { String s = session.getAttribute("s").toString(); out.print(", getting session attribute s = " + s); } catch (Exception e) { out.print("Error getting session attribute!"); } out.close(); } }
HTML Formular:
<form action=/.../servlet/FileUp method=POST ENCTYPE="multipart/form-data"> ... <input type=file name=...>
Servlet FileUp.java:
import javax.servlet.*; import javax.servlet.http.*; import org.apache.commons.fileupload.*; import java.io.*; import java.util.*; public class FileUp extends HttpServlet { PrintWriter out = null; public void doPost(HttpServletRequest req, HttpServletResponse res) { res.setContentType("text/html"); String file = req.getParameter("file"); try { out = res.getWriter(); DiskFileUpload fu = new DiskFileUpload(); List fileItems = fu.parseRequest(req); Iterator i = fileItems.iterator(); String content = ((FileItem)i.next()).getString(); out.println("File Upload: " + content); } catch (Exception e) { out.println("Error: " + e); } } }
Zum Kompilieren:
export CLASSPATH=$CLASSPATH:/usr/local/tomcat-5.0.18/server/lib/commons-fileupload-1.0.jar
(am besten in ~/.bash_profile)
Siehe auch: jakarta.apache.org
Nun haben wir alle technischen Hilfsmittel, um eine einfache Warenwirtschaft entsprechend dem Modell am Schluß des Kapitels ER-Modell zu implementieren. Die Stammdatenpflege für Artikel und Kunden sowie die Auftragsverwaltung sollen über das Web möglich sein. Achten Sie bei der Umsetzung auf:
Zusatzaufgaben: