JSTL - JSP Standard Tag Library

Mit Java Server Pages (JSP) existiert eine Variante, dynamische Inhalte wie z.B. Datenbankabfragen in Webseiten zu präsentieren, indem Java Code mit HTML Code gemischt werden kann. Der Ansatz von JSTL ist ähnlich, bietet aber eine einfachere Möglichkeit zur Produktion von dynamischen Inhalten über eine HTML-ähnliche Syntax.

Im folgenden Beispiel wird von 1 bis 10 gezählt; beachten Sie die erste Zeile, die einen Prefix für die JSTL Elemente definiert, damit es keine Konflikte mit HTML-Elementen geben kann.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"  %>

<c:forEach var="i" begin="1" end="10" step="1">
  <c:out value="${i}" />
  <br />
</c:forEach>

Der taglib prefix ist zwar beliebig, c für core ist aber empfehlenswert, um den Code besser lesbar und vergleichbar zu halten.

Sitzungsvariablen

Da HTTP ja keine dauernde Verbindung zwischen Client und Server vorsieht, müssen wir eine andere Möglichkeit finden, Daten zumindest für die Dauer eine Sitzung zu speichern. So wollen wir z.B. den Kunden die Möglichkeit geben, sich bei unserem System anzumelden, d.h. für die Dauer ihrer Sitzung zu identifizieren.

Wir holen uns dazu zunächst aus einem Formular Anmelden.jsp die zu speichernde Kundennummer, die der Benutzer eingibt, um sich zu identifizieren.

<h2>Anmeldung</h2>
<p> Geben Sie hier Ihre Kundennummer an:
<form action=AnmeldenSet.jsp>
<input type=text name=knr>
<input type=submit value=OK>
</form>

Im folgenden Schritt AnmeldenSet.jsp setzen wir die Sitzungsvariable knr, die wir vom Formular als param.knr bekommen. Beachten Sie scope="session"; diese Variable steht uns danach in allen anderen JSP-Seiten dieser Sitzung zur Verfügung, wenn wir später z.B. einen Auftrag anlegen wollen.

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:set var="knr" scope="session" value="${param.knr}"/>
Sie sind nun angemeldet.

Wenn die Sitzungsvariable knr einmal gesetzt ist, steht sie uns unter diesem Namen in allen JSP Seiten zur Verfügung:

... 
<c:out value="${knr}"/> 
...

Damit sich unsere Benutzer auch wieder abmelden können, sehen wir auch dafür eine Möglichkeit vor, z.B. in Abmelden.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:remove var="knr" scope="session"/>
Sie sind nun abgemeldet.

Neben den von uns gesetzten Variablen hat jede Sitzung eine Reihe weiterer Werte, u.a. auch ein 32 Zeichen langes Session ID, das die Sitzung identifiziert. Dieser Wert ist normalerweise unter der Bezeichnung pageContext.session.id verfügbar. Je nach Tomcat-Version kann es damit Probleme geben; aber mit folgendem Trick bekommen wir trotzdem das Session ID in eine Variable sid, die wir dann in anderen JSTL Elementen verwenden können, z.B. in <c:out>:

<c:set var="sid" scope="session"><%=session.getId()%></c:set>
<c:out value="${sid}"/>

Das schreiben wir am besten in die Start-Seite.

Verbindung zur Datenbank

Hier spielen drei Komponenten zusammen:

  1. Der Browser schickt einen Request in Form eines URLs
  2. Der Application Server exekutiert den JSP code und schickt HTML als Reply
  3. Die Datenbank verwaltet die Zugriffe auf die Tabelleninhalte

Damit SQL-Befehle verwendet werden können, muß zunächst eine Verbindung zur Datenbank hergestellt werden. Das geschieht am besten auf der Startseite der Applikation. Die dataSource wird als Sitzungsvariable gespeichert, d.h. sie steht uns danach in allen JSP-Seiten zur Verfügung. Alle DB-spezifischen Daten sind hier gesammelt. Im folgenden die Version für Postgresql:

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<h2>Start Page</h2>

<sql:setDataSource 
  var="db"
  scope="session"
  driver="org.postgresql.Driver"
  url="jdbc:postgresql://localhost:5432/dbuserid"
  user="dbuserid"
  password="dbpasswd"
/>

<ul> 
  <li> <a href=Anmelden.jsp>Anmelden</a>
  <li> <a href=Abmelden.jsp>Abmelden</a>
  <li> <a href=KundenErfassen.jsp>Kunden Erfassen</a>
  <li> <a href=KundenListe.jsp>Kundenliste</a>
</ul>

<p> Sie sind 
<c:choose>
  <c:when test="${not empty knr}">
    als Kunde Nummer <c:out value="${knr}"/> angemeldet.
  </c:when>
  <c:otherwise>
    nicht angemeldet.
  </c:otherwise>
</c:choose>

Für Mysql wird die data source so gesetzt:

<sql:setDataSource 
  var="db"
  scope="session"
  driver="com.mysql.jdbc.Driver"
  url="jdbc:mysql://localhost:3306/dbuserid"
  user="dbuserid"
  password="dbpasswd"
/>

Weiter unten in der Startseite zeigen wir dann noch an, ob der Benutzer schon eingeloggt ist.

SQL Select

Nachdem die Verbindung zur Datenbank hergestellt ist, können SQL Befehle verwendet werden, um z.B. eine Liste der Kunden zu erzeugen.

Die Datei KundenListe.jsp enthält folgendes:

<%@ taglib prefix="c"   uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"  %>

<h2>Kundenliste</h2>

<sql:setDataSource 
  var="db"
  scope="session"
  driver="org.postgresql.Driver"
  url="jdbc:postgresql://localhost:5432/dbuserid"
  user="dbuserid"
  password="dbpasswd"
/>

<sql:query var="kunden" dataSource="${db}">
  select nr, name, adresse from kunde
</sql:query>

<table>
  <c:forEach var="x" items="${kunden.rows}">
    <tr> 
      <td> <c:out value="${x.nr}"/> </td>
      <td> <c:out value="${x.name}"/> </td>
      <td> <c:out value="${x.adresse}"/> </td>
    </tr>
  </c:forEach>
</table>

Formular zum Erfassen von Kunden

Zum Erfassen neuer Kunden benötigen wir zunächst ein Formular zum Eingeben von Daten. Da hier keine JSTL Funktionen notwendig sind, brauchen wir auch die taglib Zeile nicht.

Die Datei KundenErfassen.jsp enthält folgendes:

<h2>Kundendaten Erfassen</h2>

<form action=KundenInsert.jsp>
  <table>
    <tr> 
      <td> Nr: </td>
      <td> <input type="text" name="nr"> </td>
    </tr>
    <tr> 
      <td> Name: </td>
      <td> <input type="text" name="name"> </td>
    </tr>
    <tr> 
      <td> Adresse: </td>
      <td> <input type="text" name="adresse"> </td>
    </tr>
    <tr> 
      <td> </td>
      <td> <input type="submit" value="OK"> </td>
    </tr>
  </table>
</form>

SQL Insert

Nachdem die Daten im Formular eingegeben wurden, sollen sie nun in KundenInsert.jsp in die Tabelle in der Datenbank geschrieben werden:

Die Datei KundenInsert.jsp enthält folgendes:

<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

<c:catch var="msg">
  <sql:update dataSource="${db}">
    insert into kunde (nr, name, adresse) 
    values ( ${param.nr}, '${param.name}', '${param.adresse}' )
  </sql:update>
</c:catch>

<c:choose>
  <c:when test="${not empty msg}">
    <b>Fehler beim Erfassen:
    <c:out value="${msg}"/>
  </c:when>
  <c:otherwise>
    <p> Kundendaten wurden erfasst.
  </c:otherwise>
</c:choose>

  • Mit catch speichern wir eventuelle Fehlermeldungen
  • Mit choose testen wir, ob die Variable msg eine Fehlermeldung enthält, die wir dann ausgeben
  • Hier wird das zB eine schon vergebene Kundennummer sein

    Warenkorb

    Aus der Artikelliste sollen unsere Kunden Artikel in einen virtuellen Warenkorb legen können. Das soll natürlich auch ohne Registrierung oder Login funktionieren. Mit der Session-ID können wir die Inhalte der Warenkörbe unterschiedlicher Benutzer trennen. In der DB legen wir dazu eine Tabelle warenkorb mit einem char(32) Feld für die Session-ID an, sowie integer für Artikelnummer und Menge. Dann versehen wir die Artikelliste mit Links auf eine Folgeprozedur:

    ...
    <table>
      <c:forEach var="x" items="${artikel.rows}">
        <tr>
          <td> ${x.nr} </td>
          <td> ${x.bez} </td>
          <td> ${x.preis} </td>
          <td> <a href=inkorb.jsp?nr=${x.nr}>In den Warenkorb</a> </td>
        </tr>
      </c:forEach>
    </table>
    

    Die Folgeprozedur inkorb.jsp erhält die Artikelnummer als Parameter und verwendet sie in einem Insert-Statement:

    <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    
    Artikel Nr. ${param.nr} ist im Korb.
    
    <c:set var="sid" scope="session"><%=session.getId()%></c:set>
    
    <sql:update dataSource="${db}">
      insert into warenkorb (sessionid, artikel, menge)
      values ('${sid}', ${param.nr}, 1)
    </sql:update>
    

    In der Folge können wir dann

    Include

    Häufig verwendete Komponenten können mit dem include Befehl in JSP Seiten verwendet werden:

    <%@include file="other.jsp" %>
    

    Alle HTML Inhalte und JSP Befehle in other.jsp werden an dieser Stelle eingefügt und ausgeführt. Damit lassen sich einheitliche dynamische Bestandteile in der ganzen Applikation erzielen.