JSP- Java Server Pages
ã von
Horst Leitenmüller 9255833
Johannes Kepler Universität Linz
Wintersemester 2000/2001
Inhaltsverzeichnis Java Server Pages:
1.1 Was ist
eine Java Server Page ?
2.7.2 Tag
library descriptor file
5. JSP und Servlets
(Forwarding)
Eine Java Server Page bietet die Möglichkeit dynamischen Inhalt mit statischem Inhalt einer HTML Seite zu mischen. Hierbei werden die dynamischen Teile vom statischem Code durch gesonderte Tags getrennt. Die meisten dieser Tags beginnen mit <% und enden mit %>.
Java Server Pages benötigen eine JSP Engine die eine Umsetzung der JSP-Seite in ein Servlet durchführt und die Ergebnisseite als HTML (oder glw.) zurückliefert
Hier sieht man eine Apache Web-Server der die statischen HTML aufrufe direkt weiterleitet und die Dateien mit JSP oder Servlets an die Resin JSP-Servlet Engine weiterleitet. Resin übersetzt die jsp Seiten in ein Servlet und liefert den Response.
Das Servlet (sowohl von JSP oder einem normalen Servlet) wird bei der ersten Anfrage oder beim direkten Start initalisiert. Bei einem Fehler zur Übersetzungszeit wird dieser automatisch an den Client weitergeleitet, daher sollte immer das Servlet bzw. die JSP- Seite getestet werden.
Die Syntax der JSP-Seiten lässt sich in zwei unterschiedliche Ausdruckarten gliedern einmal die normale Syntax und einmal die XML Syntax.
Es gibt acht vordefinierte Variablen diese werden bei der Erzeugung des JSP- Servlets automatisch angelegt.
Ø request: ermöglicht einen Zugriff auf die Request Parameters, den Request Typ und die Request Headers.
Ø response: dient zur Rücksendung der Daten an den Client
Ø out: ist der PrintWriter um die Daten an den Client zu schicken, Größe der Buffers sind veränderbar, dieser werden mit der page directive attribute buffer verändert.
Ø session: dient um eine Verbindung als eindeutig zu definieren (HTTP ist zustandslos) , diese Variable wird immer erzeugt außer man verwendet die Page directive attribut session und dreht diese ab.
Ø application: ist die Variable für ServletContext sie beinhaltet persistente Daten und kann von allen Servlets zugegriffen werden.
Ø config: diese Variable beinhaltet das ServletConfig object für die Seite.
Ø pageContext: ist die Variable für das PageContext Object, speziell die Java Beans sollte in diesem Object abgelegt sein um einen zugriff mit der getAttribute Methode jederzeit während eines request zu gewährleisten.
Ø page: ein Platzhalter für eventuell folgende Scriptsprachen (synonym für this)
Um ein Dokument mit JSP Kommentare zu versehen ist im Gegensatz zu HTML:
Static HTML Kommentare
<!-- HTML Kommentar -->
folgende
Schreibweise zu verwenden, diese Kommentare sind bei der Übersetzung nicht mehr
sichtbar.
JSP Kommentare
<%-- JSP Kommentar --%>
Eine JSP-Expression hat folgende Form:
<%= Java Expression %>
oder in Form von XML:
<jsp:expression>
Java Expression
</jsp:expression>
Gibt die Möglichkeit Variablen direkt in den Output umzuleiten. Die Berechnung der Expression erfolgt zur Laufzeit, wenn die Seite aufgerufen wird.
Bsp.:
Current time: <%= new
java.util.Date() %>
Oder Zugriff auf die vordefinierten Variablen
<%= request.getRemoteHost()
%>
Eine JSP-Scriptlet hat folgende Form:
<% Java Code %>
oder in Form von XML:
<jsp:scriptlet>
Java Code
</jsp:scriptlet>
Gibt die Möglichkeit kompliziertere Ausdrücke auszuwerten und mit out.println an den Outstream zu übergeben. Diese Variante ermöglicht arbiträren Code einzufügen, wie zum Beispiel Anbindung an Datenbanken und andere aufwendigere Zugriffe. Alle in Java verwendbaren Konstrukte können auch hier verwendet werden.
Bsp.:
<%
String queryData =
request.getQueryString();
Out.println(„Attached GET Data: „
+ queryData);
%>
dies könnte man natürlich auch mit Expressions lösen:
Attached GET Data: <%=
request.getQueryString() %>
Eine JSP-Declaration hat folgende Form:
<%! Java Code %>
oder in Form von XML:
<jsp:declaration>
Java Code
</jsp:declaration >
Mit Declarations kann man Variablen im Bereich des Main Bodies des Servlets anlegen. Sie werden mit den beiden vorhergehenden Methoden bearbeitet (Expression, Scriptlets)
Bsp.:
<%! Private int
accessCount = 0 %>
Accesses
to page since server reboot:
<%=
++accessCount %>
Dieses
Beispiel legt eine Variable accessCount an und zählt bei jedem Zugriff auf die
Seite den Zähler nach oben. Die Variable entspricht einer static Klassenvariable.
Um eine bessere Strukturierung in eine JSP Seite zu bekommen sind directiven eingeführt worden. Diese werden in 3 Typen unterschieden:
page
inlcude
taglib
Die page directive ist dafür da die Imports der einzelnen Klassen zu kontrollieren
Die include directive ermöglicht das einfügen von Files in das Servlet zur Übersetzungszeit. Sie wird platziert am Platz wo das File eingefügt werden soll.
Die taglib directive kann benutzt werden um eigene Markup Tags zu definieren
Eine JSP directive für page hat folgende Form
<%@ directive attribute= “value“ %>
oder
<%@ directive attribute=“value“
attribute1=“value“ ......... %>
Eine page directive beinhaltet ein oder mehrere Attribute die verwendet werden können.
Ø import : gibt an welche Klassen importiert werden sollen vom generierten Servlet
Ø contentType: gibt den Content Typ des Response Headers an
Ø isThreadSafe: gibt an ob ein Servlet multiplen Zugriff gewährt oder nicht
Ø session: gibt an ob HttpSession verwendet wird oder nicht
Ø buffer: gibt die Größe des out Buffers an welcher vom JspWriter verwendet wird
Ø autoflush: gibt an ob der Buffer automatisch geschickt werden soll oder nicht
Ø extends: gibt die Superklasse für das generierte Servlet an
Ø info: mit diesem Attribut kann man eine Info eingeben über das Servlet, diese kann mit getServletInfo() abgerufen werden.
Ø errorPage: ermöglicht eine Seite mit der Bearbeitung einer Exception zu beauftragen.
Ø isErrorPage: gibt bekannt ob eine Seite als Errorpage für eine andere Seite agieren kann.
oder in Form von XML:
<jsp:directive.directiveType
attribute=“value“ />
Beispiel für die Verwendung:
Import
<%@ page import=“java.utils.* ,
mypackage.class“ %>
oder xml
<jsp:directive.page
import=“java.utils.* , mypackage.class“ />
oder contentType
<%@page
contentType=“text/plain“ % >
oder xml
<jsp:directive.page
contentType="text/plain" />
Eine include directive ermöglicht das einfügen von statischem HTML Code oder von JSP Code, hierbei können zb Navigationsleisten wiederverwendet werden usw.
Eine JSP directive für include hat folgende Form
<%@ include file="Relative
URL" %>
in dieser Form wird das Include File zum Übersetzungszeitpunkt eingebunden, sind nun Änderungen an einem eingebundenen File durchgeführt worden müssen alle Servlets aktualisiert werden die dieses File verwenden !
Eine weitere Möglickeit ist es zum Request Zeitpunkt einzubinden, dies hat dann folgende Form:
<jsp:include
page="Relative URL" flush="true" />
Bei dieser Form wird das file erst zum Zeitpunkt des Requests eingebunden jedoch darf dieses File nun keine JSP mehr enthalten sondern nur noch statischen HTML Code.
Einbinden von Clientseitigen Applet Anwendungen. Dies wird durch die folgende Form ausgeführt:
<jsp:plugin
type="applet"
code="MyApplet.class"
....
<jsp:params>
<jsp:param
name="Param1" value="value1" />
........
</jsp:params>
<jsp:fallback>
Error:
this example requires Java
</jsp:fallback>
</jsp:plugin>
Mit jsp:param kann man Parameter für das Applet angeben, das Struckt jsp:fallback fängt Fehlermeldungen ab und gibt den angegebenen Text aus.
Die Attribute für jsp:plugin sind größtenteils für Applet aber nicht alle.
Um einen eigenen Tag zu definieren muss man 3 verschiedene Komponenten definieren.
Ø tag handler class welche das tag's verhalten definiert
Ø tag library descriptor file welches die XML Elemente mit einem Namen versehen
Ø JSP file welches die taglibrary nutzt
hierbei muss das Interface javax.servlet.jsp.tagext.Tag implementiert werden, dies kann erreicht werden durch die Ableitung von TagSupport oder BodyTagSupport Klasse.
Dieser Handler wird beim erkennen des Tags ausgeführt.
Als nächste muss diese Klasse dem Server bekannt gemacht werden mit dem dazugehörigen XML Tag Namen, dies wird durch ein XML Dokument durchgeführt und sieht wie folgt aus:
<?xml
version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD
JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<taglibversion>1.0</tablibversion>
<jspversion>1.1</jspversion>
<shortname>test</shortname>
<info>......</info>
<tag>
<name>NamedesTags</name>
<tagclass>package.class</tagclass>
<info> nur ein TestTag
</info>
<bodycontent>EMPTY</bodycontent>
</tag>
</taglib>
Um nun den Tag zu verwenden muss nun das Tag Library eingebunden werden in die JSP Seite, dies erfolgt durch folgende Syntax:
<%@ taglib uri="......." prefix="......" %>
Beispiel:
<!DOCTYPE HTML
PUBLIC „-//W3C//DTD HTML 4.0 Transitional//EN“>
<HTML>
......
<%@ taglib
uri="test-taglib.tld" prefix="test" %>
<test:NamedesTags />
Oder
<test:NamedesTags>
</test:NamedesTags>
......
</HTML>
nun kann der eingebunden Tag wie oben gezeigt verwenden. Der Body ist hier nicht berücksichtigt worden, dies würde den Rahmen sprengen.
Java Beans müssen einige grundlegende Punkte erfüllen:
1) eine Bean Klasse muss einen leeren Kontstruktor besitzen
2) eine Bean Klasse sollte keine public Variablen besitzen
3) persistente Variablen sollten mit den Methoden getXXX und setXXX zugegriffen werden
Um Java Beans in einer JSP Seite zu verwenden muss diese mit folgender Syntax instanziert werden:
<jsp:useBean
id="name class="package.class" scope="page" />
Die Bean kann nun mit dem name der bei id spezifiziert worden ist zugreifen.
Um nun die Properties zu holen gibt es folgende Syntax:
<jsp:getProperty name="book"
property="title" /> oder
<%= book.getTitle() %>
Um Properties zu setzen gibt es folgende Syntax:
<jsp:setProperty name="book"
property="title" value="JSP is cool" /> oder
<% book.setTitle("JSP is
cool"); %>
Die Beans werden auf locale Variablen der _jspService Methode vom Servlet welches aus der Seite generiert wurde, zusätzlich werden die Beans jedoch auch in einem der vier verschiedenen Bereiche abhängig vom scope beim instanzieren der Bean.
Diese Bereiche sind:
Ø page: dies ist der default Bereich die Beans können mit getProperty , setProperty
Ø application: die Bean wird im Bereich ServletContext abgelegt dieser Bereich ist von allen Servlets zugreifbar mittels getServletcontext() oder durch die vordefinierte Variable application
Ø session: die Bean wird im HttpSession Objekt abgelegt, sie kann zugegriffen werden mit getValue.
Ø request: die Bean wird im ServletRequest Objekt abgelegt, sie kann zugegriffen werden mit getAttribute Methode.
Ein kleiner Buchladen der Zugriffe über mehrere Schnittstellen anbieten soll, dies bedeutet das der Zugriff über WML, HTML oder Voice stattfinden soll.
Die Zugriffe sollen von mehreren Clients ausgeführt werden und Datenbankabfragen beinhalten. Es werden für die Clients aufwendige Berechnungen durchgeführt, der Response soll für den jeweiligen Benutzer aufbreitet sein, bei einem WML Client soll nur WML zurück kommen. Es gibt unterschiedliche Seiten die als Response zurückgegeben werden können.
Ein Lösungsansatz wäre nun alles in JSP zu lösen, die Java Bean Komponenten etwas intelligenter zu machen und viel Code in die JSP Seite einbauen. Dies Widerspricht jedoch der 3tier-Technologie und ist eigentlich nicht erwünscht. Doch wie kann man nun dieses Problem lösen ?
Dieses Problem kann sehr einfach gelöst werden aufgrund eines Forward Mechanismusses ist ein weiterleiten von Request und Response an JSP Seiten oder Servlets möglich. Durch diese Weiterleitung ist eine Trennung der 3 Schichten möglich, hierbei übernimmt das Servlet die Schicht als Logik, die JSP Seiten sind die Präsentationsschicht und es gibt eine eigene Datenbankschicht.
Das Beispiel wurde nicht ganz implementiert doch aus diesem Teil ist bereits ersichtlich wie der Mechanismus funktioniert.
Um die Kombination von Servlets und JSP nutzen zu können gibt es einen Mechanismus der ein Forwarden des Requestes und des Response’s erlaubt, dieser Mechanismus wird mittels eines Request Dispatcher durchgeführt.
/**
* fowards the request to the correct Page
*/
private void gotoPage(String address,
HttpServletRequest request, HttpServletResponse
response)
throws
ServletException, IOException
{
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(address);
dispatcher.forward(request,
response);
}
Der weitergeleitete Request
verwendet die selbe Methode wie der Original Request.
Anmerkung: bei Post request's ist ein weiterleiten an HTML Dokumente nicht möglich hier muss eine Umbenennung auf .jsp stattfinden.
Ein sehr großer Vorteil von JSP ist das es nicht auf VB oder eine ASP spezifische Sprache beschränkt ist sondern die volle Vielfalt von Java nutzen kann. Dies macht den Code portable auf andere Systeme und ist nicht auf Windows-Betriebssysteme beschränkt. Dies bedeutet wenn ich eine ASP Seite geschrieben habe läuft sie nur auf einem Windows Web Server jedoch nicht auf Web-Server der auf Unix, Linux oder anderen Betriebssystemen läuft.
Nochmals die Vorteile von JSP kurz zusammengefasst:
-
Nicht
auf NT/2000 und IIS beschränkt
-
Kein
VB Script oder ASP-spezifische Sprache
Der Vorteil gegenüber PHP liegt im Bereich der bereits Vielfältig vorhandenen API’s für das Netzwerk, für Datenbankzugriffe usw.
Ein weiterer Vorteil ist, wenn man Java kann muss man nicht eine neue Sprache erlernen.
Nochmals die Vorteile von JSP kurz zusammengefasst:
-
Dynamischer
Teil in Java mit API für Netzwerk, DB
Ein großer Vorteil ist gegenüber Java Script, dass JSP absolut Server Seitig ist, dies ist auch gleichzeitig ein Nachteil wenn dynamische Informationen von der Client Umgebung benötigt werden. Ein zusätzlicher Vorteil von JSP ist die Zugreifbarkeit von Datenbanken, Server Informationen etc.
Nochmals die Vorteile von JSP kurz zusammengefasst:
-
Nur
auf Client Seite ausgeführt
-
Keine Datenbankzugriffe
Es muss eine eigene JSP-Engine installiert werden, in dieser gehören dann alle Einstellungen für die einzelnen JSP Seite angeführt.
Meiner Meinung nach ist JSP eine sehr mächtige Möglichkeit Seiten dynamisch auf der Server Seite zu erstellen. Die volle Nutzung ist jedoch erst in einer Kombination von Servlets und JSP möglich, da erst durch diese Kombination die Trennung der Präsentation von der Logik einigermaßen gelingt.
Ein großer Nachteil ist die Installation einer zusätzlichen JSP Engine wie es bei Apache jserv für die Servlets und zusätzlich Tomcat installiert werden muss. Hier ist es einfacher die Servlet/JSP Engine von Caucho zu verwenden (RESIN).
Wenn man Java programmieren kann ist die Verwendung von Servlets oder JSP sehr einfach und man kann die ganze Palette der verfügbaren Klassen verwenden, zusätzlich ist der produzierte Code Portabel auf andere Systeme und nicht auf ein System eingeschränkt.
Ø JSP Engine und Dokumentation JSP
http://www.caucho.com
Ø JSP Specification
http://www.java.sun.com/jsp
Ø Paul J. Perrone and Venkata S.R. „Krishna“ R. Chaganti
Building Java Enterprise Systems with J2EE
SAMS
ISBN 0-672-31795-8
Anmerkung:
Ø Marty Hall
Servlets and Java Server Pages
Sun microsystems
ISBN 0-13-089340-4
Anmerkung:
Gutes Grundlagenbuch mit vielen Details, sehr zu empfehlen