Beispiel: JSP-Grundlagen (IBM WebSphere)
Inhalt:
Beispiel 1: JSP-Grundlagen
Beispiel 2: Controller-Servlet
Beispiel 3: Tag Libraries
Beispiel 4: Custom Tag Libraries
Diverse JSP-Beispiele. Alle diese Beispiele arbeiten völlig ohne EJB-Zugriff.
Eigentlich hätte ich hier gerne, analog zu den JBoss-Beispielen, ein "Dynamic Web Project" verwendet,
allerdings gab das beim Deploy auf den Server eine Fehlermeldung. Scheinbar mag der großmächtige
WebSphere nur Enterprise Applications. Also ein Enterprise Application Project mit
einem Webmodul erstellen.
Beispiel 1: JSP-Grundlagen
Dieses Beispiel enthält drei JSP-seiten ("index.jsp", "input.jsp" und "errorpage.jsp") und die Klassen
de.fhw.swtvertiefung.knauf.jsp1.Historie
und de.fhw.swtvertiefung.knauf.jsp1.Seitenlaengen
.
Es führt die gleiche Logik aus wie das Beispiel der Stateful Session Bean:
Es errechnet Oberfläche und Volumen eines Quaders.
Hier gibt es das Projekt als Projektaustausch: JSP1Export.zip.
Das Beispiel soll folgende Grundelemente einer JSP zeigen:
- Verwenden des Session-Contexts zum Speichern der bisherigen Berechnungen.
- "jsp:useBean"-Tag für das Erzeugen einer Bean im Session-Context, die bei weiteren
Requests wiederverwendet wird.
- "jsp:useBean"-Tag für das Erzeugen einer Java-Klasse im Page Context und automatisches Befüllen aus Request-Parametern.
- Einbinden einer externen Seite mit jsp:include.
- Bei Fehlern an den Eingaben wird automatisch die Errorpage aufgerufen.
Die Anwendung findet sich unter dieser URL: http://localhost:9080/JSP1Web/index.jsp.
Beispiel 2: Controller-Servlet
In diesem Beispiel wird ein großer Teil der Anwendungslogik in ein Servlet ausgelagert.
Beim Absenden des Formulars ist nicht die JSP-Seite das Ziel, sondern ein Servlet. Dieses
wertet die Request-Parameter aus, erzeugt die Bean mit den aktuellen Request-Werten, berechnet
Volumen und Oberfläche.
Anschließend wird der Request an "index.jsp" weitergeleitet, diese Seite gibt die errechneten
Werte aus.
Hier gibt es das Projekt als Projektaustausch: JSP2Export.zip.
Das Beispiel zeigt dieses:
- Trennung von Anwendungslogik und Anzeigelogik
- Verwaltung der Session über Servlet.
- Weiterleiten des Requests vom Servlet an die JSP.
- Speichern von Objekten im Request, so dass weitere Serverkomponenten sie nutzen können.
- Fehlerbehandlung: im Servlet ausgelöste Exception an Errorpage weitergeben.
Die Anwendung findet sich unter dieser URL: http://localhost:9080/JSP2Web/index.jsp.
Beim Anlegen des Servlets sind diese Einstellungen vorzunehmen:
Schritt 1: Servlet-Name angeben, das Default-URL-Mapping wird entfernt und ersetzt durch
/servlet/GeometricModelServlet
.
Schritt 2: Package de.fhw.swtvertiefung.knauf.jsp2
angeben.
WebSphere-Besonderheit: Das Weiterleiten an eine JSP aus dem Servlet heraus konnte ich nicht
direkt verwirklichen (es gab die Fehlermeldung "Servlet index.jsp nicht gefunden").
Workaround: in Web Deployment Descriptor jede JSP als Servlet deklarieren (mit
gleichem Namen wie die JSP-Seite).
Das sieht dann so aus:
<servlet>
<display-name>index.jsp</display-name>
<servlet-name>index.jsp</servlet-name>
<jsp-file>/index.jsp</jsp-file>
</servlet>
<servlet>
<display-name>input.jsp</display-name>
<servlet-name>input.jsp</servlet-name>
<jsp-file>/input.jsp</jsp-file>
</servlet>
<servlet>
<display-name>errorpage.jsp</display-name>
<servlet-name>errorpage.jsp</servlet-name>
<jsp-file>/errorpage.jsp</jsp-file>
</servlet>
Man kann diese Information auch beim Anlegen einer JSP im letzten Schritt angeben,
allerdings muss man anschließend den "Servlet Name" korrigieren, da ein angehängtes ".jsp"
vom Assistenten verschluckt wird.
Das Ergebnis des Ganzen sieht dann so aus:
Beispiel 3: Tag Libraries
In diesem Beispiel wird Beispiel 2 weitergeführt: auf der JSP-Seite "index.jsp" soll
kein Stück Javacode mehr zu sehen sein. Stattdessen soll alle dynamische Formatierung von
TagLibs erledigt werden.
Das Beispiel verwendet folgende Taglibraries:
-jakarta-taglibs-request-1.0.1 (Arbeiten mit dem Request, z.B. Ausgabe von Attributen im Request)
-jakarta-taglibs-standard-1.1.2 (Implementation des Java-Standard-Taglib-Standards).
Hier gibt es das Projekt als Projektaustausch: JSP3Export.zip.
Nach dem Anlegen der Enterprise Application und des Dynamic Web Projects müssen die zu verwendenden
Tag-Libraries importiert werden.
Dazu müssen die Dateien "taglibs-request.jar" aus dem Paket "jakarta-taglibs-request-1.0.1" und
"jstl.jar" sowie "standard.jar" aus "jakarta-taglibs-standard-1.1.2" in das Verzeichnis "WebContent\WEB-INF\lib" des
Projekts eingefügt werden.
Die Taglibrary-Deklarationen (Dateien mit der Endung "tld") müssen in das Unterverzeichnis "WebContent\WEB-INF\tags"
(hier kann auch ein beliebiges anderes Verzeichnis gewählt werden) eingefügt werden. Hier sind das
"c.tld" aus "standard.jar" und "taglib.tld" aus "taglibs-request.jar".
Anschließend "Refresh" im Projekt wählen.
Jetzt den Deployment Deskriptor des Webprojekts öffnen. Auf der Karteikarte "Variables" können
wir die Taglibrary-Referenzen editieren. Wir fügen die beiden Taglibs zu (als Location wird
jeweils der relative Pfad zur tld-Datei angegeben):
Für die Java Standard Tag Library geben wir dieses ein:
URL: http://jakarta.apache.org/taglibs/request-1.0
Location: /WEB-INF/tags/taglib.tld
Für die Request-Taglib:
URL: http://java.sun.com/jstl/core
Location: /WEB-INF/tags/c.tld
Das Ergebnis sieht so aus:
In "web.xml" sieht das genauso aus wie im JBoss-Beispiel:
<jsp-config>
<taglib>
<taglib-uri>http://jakarta.apache.org/taglibs/request-1.0</taglib-uri>
<taglib-location>/WEB-INF/tags/taglib.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>http://java.sun.com/jstl/core</taglib-uri>
<taglib-location>//WEB-INF/tags/c.tld</taglib-location>
</taglib>
</jsp-config>
Hier werden symbolische Namen für die Taglibs in "WEB-INF\lib" deklariert, unter diesen URI (Unified Resource
Identifier) werden sie später auf den JSP-Seiten angesprochen.
In "index.jsp" werden die Taglibs so eingebunden:
<%@ taglib uri="http://jakarta.apache.org/taglibs/request-1.0" prefix="req" %>
<%@ taglib uri="http://java.sun.com/jstl/core" prefix="c" %>
Jetzt können die Tags aus den TagLibraries als "jsp" bzw. "c" verwendet werden.
Natürlich müssen, genau wie im letzten Beispiel, die JSP-Seiten als Servlets deklariert werden, damit
ein Weiterleiten aus einem Servlet heraus möglich ist.
Die Anwendung findet sich unter dieser URL: http://localhost:9080/JSP3Web/index.jsp.
Beispiel 4: Custom Tag Libraries
In diesem Beispiel werden die TagLibraries aus Beispiel 3 ersetzt durch handgeschriebene Taglibraries.
Hier gibt es das Projekt als Projektaustausch: JSP4Export.zip.
Jetzt werden die TagLibraries angelegt. Sie landen im Package de.fhw.swtvertiefung.knauf.jsp4.tags
.
Die Definition der Tags erfolgt in der Datei "WebContent\WEB-INF\tags\jsp4.tld".
Der Rahmen dieser TagLibrary-Deklaration sieht so aus (gemäß JSP-2.0-Spezifikation, die TagLibs aus dem letzten
Beispiel wurden erstellt gemäß JSP-Spezifikation 1.1, dort wurde eine DTD verwendet und einige Tags hießen leicht anders):
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<short-name>jsp4</short-name>
<uri>http://www.informatik.fh-wiesbaden.de/~knauf/jsp4</uri>
...
</taglib>
Hier vergebe ich einen Kurznamen der TagLib und eine URI, wobei beide Werte frei vergebbar sind und nur als Vorschläge
dienen, auf der JSP-Seite können sie beliebig überschrieben werden.
Folgende Tags werden verwendet:
IfExistsRequestAttributeTag
: Prüft ob im Request ein Attribut mit einem bestimmten Namen steckt.
Der Name des Attributs wird auf der JSP-Seite per Attribut gesetzt.
Ist dieses Attribut im Request vorhanden wird der JSP-Inhalt ausgeführt. Die Tag-Klasse ist von
javax.servlet.jsp.tagext.BodyTagSupport
abgeleitet da das Tag JSP-Inhalt haben kann.
Wichtige Methoden sind setRequestAttribute
(hier wird das Attribut "requestAttribute" aus der
JSP-Seite heraus gesetzt) und doStartTag
(hier wird gesteuert ob der Inhalt des Tags ausgeführt wird).
In "jsp4.tld" sieht das so aus:
<tag>
<name>ifExistsRequestAttribute</name>
<tag-class>de.fhw.swtvertiefung.knauf.jsp4.tags.IfExistsRequestAttributeTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>requestAttribute</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
Wichtig ist hier die Angabe dass das Tag JSP-Inhalt haben kann (Tag body-content
).
PrintRequestAttributeTag
: Gibt ein Request-Attribut mit einem konfigurierbaren Namen aus. Die Klasse
ist von javax.servlet.jsp.tagext.SimpleTagSupport
abgeleitet, da das Tag keinen Inhalt hat.
Wichtige Methoden sind setRequestAttribute
(hier wird das Attribut "requestAttribute" aus der
JSP-Seite heraus gesetzt) und doTag
(hier wird die Logik des Tags ausgeführt).
In "jsp4.tld" sieht das so aus:
<tag>
<name>printRequestAttribute</name>
<tag-class>de.fhw.swtvertiefung.knauf.jsp4.tags.PrintRequestAttributeTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>requestAttribute</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
Wichtig ist hier die Angabe dass das Tag keinen Inhalt hat.
LoopOverHistorieTag
: Holt aus dem Session-Context ein Attribut mit einem bestimmten Namen vom Typ
de.fhw.swtvertiefung.knauf.jsp4.Historie
und läuft per java.util.Iterator
über die
Elemente der Collection. Das aktuelle Element wird unter einem konfigurierbaren Namen in den PageContext gesteckt.
Der Name des Session-Context-Attributs in dem die Historie steckt wird auf der JSP-Seite per Attribut gesetzt.
Ist dieses Attribut im Request vorhanden wird der JSP-Inhalt für jedes Item ausgeführt. Die Tag-Klasse ist von
javax.servlet.jsp.tagext.BodyTagSupport
abgeleitet da das Tag JSP-Inhalt haben kann.
Wichtige Methoden sind setRequestAttribute
(hier wird das Attribut "requestAttribute" aus der
JSP-Seite heraus gesetzt), doStartTag
(hier wird der Iterator initialisiert und erstmalig der Inhalt des Tags ausgeführt wird)
und doAfterBody
(hier wird nach jedem Schleifendurchlauf geprüft ob ein weiterer Durchlauf nötig ist und
falls ja wird das aktuelle Item in den PageContext geklebt).
In "jsp4.tld" sieht das so aus:
<tag>
<name>loopOverHistorie</name>
<tag-class>de.fhw.swtvertiefung.knauf.jsp4.tags.LoopOverHistorieTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>sessionContextAttribute</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>item</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
Wichtig ist hier die Angabe dass das Tag JSP-Inhalt haben kann.
PrintPageContextSeitenlaengeTag
: Ausgabe einer der Properties "a", "b" oder "c" einer Instanz
von de.fhw.swtvertiefung.knauf.jsp4.Seitenlaengen
. Die Klasse
ist von javax.servlet.jsp.tagext.SimpleTagSupport
abgeleitet, da das Tag keinen Inhalt hat.
Wichtige Methoden sind setPageContextAttribute
(hier wird das Attribut "pageContextAttribute" aus der
JSP-Seite heraus gesetzt), setSeitenlaengeValue
(auszugebende Property von Seitenlaengen
)
und doTag
(hier wird die Logik des Tags ausgeführt).
In "jsp4.tld" sieht das so aus:
<tag>
<name>printPageContextSeitenlaenge</name>
<tag-class>de.fhw.swtvertiefung.knauf.jsp4.tags.PrintPageContextSeitenlaengeTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>pageContextAttribute</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>seitenlaengeValue</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
Wichtig ist hier die Angabe dass das Tag keinen Inhalt hat.
Abschließend muss die Taglib in "WebContent\WEB-INF\web.xml" eingetragen werden. Dies geschieht über das
Element "jsp-config" (geht natürlich auch über die GUI):
<jsp-config>
<taglib>
<taglib-uri>http://www.informatik.fh-wiesbaden.de/~knauf/jsp4</taglib-uri>
<taglib-location>/WEB-INF/tags/jsp4.tld</taglib-location>
</taglib>
</jsp-config>
Die Taglib-URI unter der wir die TagLib später in den JSPs ansprechen ist hier identisch mit der in der
TLD-Datei vorgegebenen, dies ist aber nicht verpflichtend.
In "index.jsp" wird die TagLib so eingebunden:
<%@ taglib uri="http://www.informatik.fh-wiesbaden.de/~knauf/jsp4" prefix="jsp4" %>
Jetzt zeigt uns Eclipse auch brav die verfügbaren Tags an:
Natürlich müssen, genau wie in den letzten beiden Beispielen, die JSP-Seiten als Servlets deklariert werden,
damit ein Weiterleiten aus einem Servlet heraus möglich ist.
Die Anwendung findet sich unter dieser URL: http://localhost:9080/JSP4Web/index.jsp.
Version 1.2.0.1, Stand 12.12.2006
Historie:
1.0.0.0 (30.11.2005): Erstellt
1.1.0.0 (06.12.2005): JSP3-Beispiel
1.2.0.0 (09.01.2006): Beispiel 4 zugefügt. Servlet-Klasse aus Beispiel 3 ersetzt da die vorherige noch Fragmente der JBoss-Version
enthielt.
1.2.0.1 (12.12.2006): Unsauber maskiertes XML in Beispiel 3 ("jsp-config") korrigiert.