Tutorial für die Arbeit mit jsps und Servlets

Autor:
Ralf Rapude

1. Einleitung
Bei diesem Tutorial wurde zur Demonstration eine Adressverwaltung auf der Basis JSP/Servlets und MySQL gewählt. Die Anwendung wurde mit Eclipse als IDE und Jakarta/Tomcat 4.1.12 als Servlet Engine entwickelt. Folgende Files können zum durcharbeiten und testen runtergeladen werden:

  1. Das komplette Tutorial mit allen Dateien gibt es hier.
  2. mysql_daten: Enthält die Datenbank für MySQL
  3. projektfiles: Die Java Quelldateien mit ihren Packages
  4. Die komplette Anwendung als Eclipse Projekt

Schwerpunkte und Zielsetzung dieses Tutorials:

  1. Ausloten der Möglichkeiten die bei der Arbeit mit JSP und Servlets geboten werden:
    Dazu gehört z.B. der Umgang und die Verarbeitung von taglibs, die Weitergabe von Parametern zwischen den einzelnen Anwendungsteilen z.B. über Session und request Attribute oder auch die Nutzung des Session Trackings über Cookies bzw. Session Id's.
  2. Durchsetzung des MVC Konzeptes:
    Obwohl es für diese kleine Anwendung eindeutig überdimensioniert ist, ist der Umgang mit diesem Design Pattern überaus interessant. Zwar gibt es z.B. das Struts-Framework, dass uns viel Arbeit abnimmt, wenn wir nach MVC-Prinzipien arbeiten wollen, doch ist es sinnvoll, dieses Pattern einmal "von Hand" nachzubilden, da erst dann deutlich wird, worum es bei diesem Muster eigentlich geht.
  3. Servlet Container:
    Servlet Container bieten eine Vielzahl von Einstellungsmöglichkeiten, um eine Web-Anwendung zu steuern und zu beeinflussen. Dazu zählt zum Beispiel das Servlet Mapping, das es ermöglicht Servlet-Urls zentral zu verwalten und so mit relativen Pfaden innerhalb von Servlets zu arbeiten oder auch das Deployment von Anwendungen über xml files, das z.B. eine Ausgabe eigener Fehlerseiten erlaubt oder eine interne Verwaltung von Usern.

top

2. Login


Dies ist das Fenster auf der Startseite der Anwendung. Der User gibt hier einen Nutzernamen und ein Passwort ein, dass in der Tabelle addresses/user der MySQL Datenbank angelegt wurde.
Beim Klick auf "Login" wird das Formular über "Post" an servlet.LoginServ weitergeleitet. Hier kommt zum ersten Mal ein Servlet Mapping zum Einsatz, damit der User zum einen in der Adresszeile des Browsers nicht die Url servlet/login.LoginServ zu sehen bekommt, sondern nur kurz "check_user" erscheint und zum anderen in den Servlets die Arbeit mit relativen Urls möglich wird.
In LoginServ wird dann ein Datenbank Connect über einen ConnectionPool angelegt (database.ConnectionPool) und Username und Passwort werden an die Hilfsklasse login.CheckUser weitergeleitet. Ist der User valide, gibt CheckUser "true" an Login.Serv zurück und fügt den Datenbankconnect über session.setAttribute() als SessionVariable ein, um den Connect auf allen weiteren Seiten verfügbar zu halten.
Als weiteres Objekt wird der Integer Wert 1 als Attribut eingefügt, um auf allen weiteren Seiten problemlos abfragen zu können, ob es sich um einen validen User mit Session id bzw. cookie handelt, oder gerade ein unberechtigter Zugriff auf die Seite erfolgt.
Sind Username und Passwort ok, wird auf data.jsp weitergeleitet, liegt ein Fehler vor, erfolgt die Umleitung auf die Seite error_login.jsp.

top

3. Darstellung der Datensätze

Die Darstellung der Daten erfolgt auf der Seite data.jsp. Im Kopf der Seite wird neben den Standardangeben wie package import usw. auch über "<jsp:useBean id = "Check" class="beans.CheckValidUser" />" eine Bean referenziert, die auf jeder zugänglichen Seite benötigt wird, denn über den Aufruf "<%Check.checkSession(session, response); %>" ist es möglich, einen unberechtigten Aufruf der Seite zu verhindern, da die Funktion checkSession() in der Klasse beans.CheckValidUser die Sessionvariablen auf ihre Richtigkeit überprüft und gegebenenfalls auf eine Fehlerseite umleitet.
Hier zahlt sich bereits das MVC - Konzept aus, da durch diese starkte Modularisierung nur wenige Codezeilen in die jsp-Seite einzufügen sind, um diese Überprüfung vorzunehmen.

Desweiteren wird auf dieser Seite ein selbstdefinierter Tag genutzt, der alle Zeilen der Ausgabetabelle über "<datatld:adrtable />" generiert. Dazu war es notwendig, zunächst eine xml Datei zu referenzieren. Dies geschieht über diesen Tag: "<%@ taglib uri = "datataglib.tld" prefix = "datatld" %>". Hier wird auf die xml Datei datataglib.tld verwiesen, die wiederum für das Auffinden der richtigen Klasse, nämlich "AddressTable" im package "tglibs" zuständig ist. Auch diese tld wird auf eine andere Url gemappt, damit bei einer Änderung der package Struktur oder ähnlichem nur an einer zentralen Stelle der Pfad geändert werden muß (in der web.xml). Dies wird dann sinnvoll, wenn mehrere Dateien auf diesen selbstdefinierten Tag zugreifen, da jetzt nicht mehr in jeder Datei einzeln der Pfad angepasst werden muß.

Zu jedem Datensat existiert ausserdem ein Link zum bearbeiten, bzw. löschen eines Datensatzes. In die Url der Links wird dabei nicht nur auf die Ziel Url verwiesen, sondern es wird auch automatisch über "encodeUrl()" die Session Id angehängt, wenn der User keine Cookies erlaubt. Zur Identifikation des Datensatzes befindet sich ausserdem die Id der einzelnen Records im Link, um so auf den folgenden Seiten die richtigen Datensätze anzuzeigen. Die id ist in diesem Fall natürlich "Primary Key" der einzelnen records.

Die eigentliche Darstellung der Daten, bzw. das auslesen aus der Datenbank erfolgt hier und auf allen anderen Seiten über die Nutzung des Datenbankconnects, der auf der Einstiegsseite über session.setAttribute() als Objekt eingefügt wurde.

top

3. Editieren und Löschen von Datensätzen

Beim editieren und löschen der Datensätze zahlt sich das MVC Konzept stark aus, denn beide Seiten nutzen die gleichen Klassen zum Auslesen und zur Darstellung des Datensatzes.
Zum Auslesen der Daten aus der Datenbank über die durchgeschliffene id ist das Servlet servlets.CollectPerson und zur Darstellung beans.ShowPerson zuständig. Hierzu wird ein Objekt "person" vom Typ ShowPerson initialisiert und über Getter und Setter Methoden werden alle notwendigen Variablen gesetzt. Da dieses Objekt jedoch nicht sessionweit zur Verfügung stehen muss, wird es nicht über session.setAttribute() gesetzt, sondern über request.getAttribute().
Gleichzeitig wird auf den Seiten zur Darstellung (delete.jsp und edit.jsp) der scope bei der Referenzierung der Bean auf "request" gesetzt. Dies ermöglicht die Darstellung des Datensatzes, ohne das Objekt "person" explizit als Attribut auszulesen.

Auf welche der beiden Seiten nach dem Auslesen der Daten weitergeleitet wird, hängt davon ab, welcher "action" Parameter in der Url mitgeschliffen wurde. Klickt der User in data.jsp auf "bearbeiten", wird der Parameter edit an die Url gehängt, klickt der User auf "löschen", wird delete ergänzt. CollectPerson entscheidet je nach diesem Parameter und erledigt die Weiterleitung in diesem Fall nicht über einen response.redirect(), sondern über forwarding durch einen RequestDispatcher, da auf der Ausgabeseite der request für die Darstellung der Bean benötigt wird, damit der scope bei der Referenzierung der Bean entsprechend gesetzt werden kann.

Klickt der User nach Änderung der Daten auf speichern, wird wieder über ein Servlet Mapping an das Servlet servlets.EditUser weitergeleitet. Hier wird wieder das Session Attribut "dbconnect" benötigt und der Datensatz wird geändert. Ist die Änderung erfolgreich verlaufen, wird auf die Seite erfolgedit.jsp weitergeleitet.

Klickt der User auf "löschen", sofern er sich auf delete.jsp befindet, wird an servlets.DeleteOk weitergeleitet. Nach Ausführen des Querys ist der Datensatz aus der Datenbank gelöscht und ebenso wie beim editieren wird der User dann auf eine Erfolgsseite weitergeleitet, die eine erfolgreiche Bearbeitung der Datenbank bestätigt. Hier befindet sich jetzt ein Link der zurück auf die data.jsp zur Anzeige der Datensätze führt.

Ausserdem bieten beide Seiten die Möglichkeit, die Aktion über entsprechende Links abzubrechen.

top

4. Logout

Beim Klick auf "logout" auf der Seite data.jsp erfolgt eine Weiterleitung aus servlets.LogoutServ. Hier werden die Session Variablen gelöscht. Ausserdem wird der Datenbankconnect an den ConnectionPool zurückgegeben, um ihn anderen Nutzern zugänglich zu machen. Sind diese Vorgänge erledigt, wird das erfolgreiche Logout angezeigt und die Option für ein erneutes Login geboten.

top