JavaServer Pages (JSP) sind Textseiten, die bei ihrem ersten Aufruf in den Java-Code einer Servletklasse umgewandelt werden. Dieser Code wird dann einmalig compiliert und kann anschließend den Request abarbeiten. Der Container wird jede JSP mit einem festen Lifecycle abarbeiten:
Jede JSP Seite ist also die Bauanleitung für ein Servlet. Wie genau im Detail der Container aus einer JSP die fertige Servletklasse generiert ist serverspezifisch. Will man JSP Seiten debuggen, muss man die übersetzten Java-Klassen finden und ihre Struktur kennen. Der generierte Code wird übrigens in der Methode _jspService untergebracht, nicht wie bei Erben von HttpServlet in service, doGet etc.
Vor diesem Hintergrung ist die "JSP-Sprache" eigentlich die Anweisungen an den JSP-Übersetzer, wie der Java-Code des Ziel-Servlets aussehen soll. Diese Sprache kennt sechs Script-Elemente, die JSP Expression Langugage, sowie JSP Standard Actions und JSP Custom Actions:
JSP Technologie +---------------------+-------------------------------+ | | | Script Elemente Expression Language JSP Action * Plain Text +-----+-----+ +-------------+------------+ * Scriptlet | | | | | * Expression EL Standard EL Function Standard Custom JSTL * Comment * useBean * TLD * forward +---+---+ * core * Declaration * EL implicit * include | | * fmt * Directive objects * ... Tagfiles Tag * xml * JSP implicit * .-Notation * TLD(2) Handler * sql objects(1) * []-Notation * TLD * functions * reserved words * classic * simple (1) für scriptlet und expression (2) TLD nur im JAR Bundle erforderlich
JSP Script-Elemente: Plain Text
Wenn keines der nachfolgenden Script-Elemente aktiv ist, wird der Inhalt der JSP Seite einfach ausgegeben. Im Java-Code stehen dann Anweisungen wie
out.print("Template Text");Man spart sich damit endlose Kolonnen von out.print(..) Angaben im Servlet.
Scriptlet-Code wird als Java-Code direkt in _jspService eingebaut:
<% if (a == b) { %> Hello World! <% } %>Damit ist programmiertechnisch maximale Flexibilität gegeben. Gleichzeitig sind JSP Seiten in denen umfangreich Scriptlet-Code zum Einsatz kommt unwartbar. Viele Ergänzungen und Erweiterungen der JSP Spezifikation zielen deshalb darauf ab, Scriptlet-Code durch alternative, besser beherrschbare Techniken zu ersetzen. Dazu zählen in erster Linie JSP Standard Actions, Custom Actions (als Tagfiles und Tag Handler) und die JSP Expression Language.
Eine Expression ist Scriptlet-Code, der in einer out.print-Anweisung eingebettet wird. So findet sich
<%= Math.random() %>im Servlet-Code als out.println(Math.random()) wieder.
Alles zwischen den Kommentarklammern wird vom JSP-Übersetzer ignoriert, hier können Kommentare untergebracht werden die weder im übersetzten Servlet noch in der fertigen HTML Seite erscheinen.
Der Code einer Deklaration wird außerhalb der _jspService untergebracht. Damit lassen sich Klassenvariablen oder Methoden definieren und überschreiben. Ein wichtiges Anwendungsbeispiel ist das Überschreiben der jspInit oder jspDestroy Methode des Ziel-Servlets:
<%! jspInit() { // wird vor dem erstem Request einmalig gerufen ServletConfig sc = ... : } %>
Direktiven sind ergänzende Anweisungen im Ziel-Code, die nicht direkt mit der Ausgabe zusammenhängen. Mit Direktiven lassen sich beispielsweise import-Anweisungen oder das Laufzeitverhalten der JSP Servletklassen beeinflussen.
Page Directive | Bedeutung | Standard |
---|---|---|
import | Import-Statement im generierten Servlet, z.B. <%@ page import="a.b.*" %>. Die Pakete java.lang, javax.servlet, javax.servlet.jsp und javax.servlet.http werden implizit importiert. | |
isThreadSafe | true: der Container kann sicher das generierte Servlet dieser JSP Seite nebenläufig rufen, da alle Zugriffe auf gemeinsam genutzte Ressourcen ordentlich synchronisiert sind. false: der Container muss davon ausgehen, dass diese JSP Seite nicht nebenläufig gerufen werden kann. Da es keinen verlässlichen, allgemein anwendbaren und gleichzeitig skalierenden Mechanismus für diese Anforderung gibt (siehe SingleThreadModel), ist 'false' als deprected eingestuft und sollte nicht mehr verwendet werden. Mit anderen Worten: diese Direktive am besten nicht nutzen und wie gewohnt vernünftig synchronisieren. | true |
contentType | der MIME Typ des Servlets in der Form 'TYPE' oder 'TYPE;char-set=CHARSET', TYPE ist dabei ein MIME Type und CHARSET ein chracter encoding Name nach IANA, Bespiel: 'text/html;char-set=UTF-8' | für TYPE: "text/html"} |
isELIgnored | true: ignoriert EL Ausdrücke (also alles der Form ${...} und #{...}) beim Übersetzen | false |
isErrorPage | true: diese Seite dient als Errorpage und kennt das implicit object 'exception' | false |
errorPage | nicht abgefangene Exception werden auf die angegebene Seite gelenkt | |
language | die Sprache der Seite | java |
extends | Superklasse des generierten Servlets | |
session | false: die Seite hat kein implicit object 'session' vom Typ HttpSession | true |
buffer | definiert wie groß der Buffer in kb (das Suffix 'kb' ist Pflicht) im implicit object 'out' ist, bei 'none' wird direkt in den PrintWriter des ServletResponse geschrieben | 8kb |
autoFlush | false: automatisches Flush ist abgeschaltet | true |
info | Text, der von getServletInfo() geliefert wird | |
pageEncoding | das Encoding der JSP Seite (als Anweisung an den JSP-Übersetzer) | ISO-8859-1 |
deferredSyntaxAllowedAsLiteral | true: die Sequenz '#{' ist in String-Literalen erlaubt | false |
trimDirectiveWhitespaces | true: Whitespace-Text wird nicht ausgegeben | false |
<%@ include file="bar.html" %> // Der Inhalt von bar.html wird hier eingefügtStartet die URL mit '/' wird sie relativ zur Anwendung, sonst relativ zur JSP interpretiert.
<%@ taglib tagdir="/WEB-INF/tags/foo" prefix="foo" %> taglib Deklaration für Tagfiles <%@ taglib uri="some_logical_name" prefix="foo" %> taglib Deklaration für Taghandler und EL Funktionen
JSP implicit objects können in Expressions und Skriptlets jederzeit über ihren Namen angesprochen werden, es sind Klassenvariablen im Zielkontext:
Name | Interface/Klasse |
---|---|
request | javax.servlet.http.HttpServletRequest |
response | javax.servlet.http.HttpServletResponse |
session | javax.servlet.http.HttpSession |
pageContext | javax.servlet.jsp.PageContext |
application | javax.servlet.ServletContext |
config | javax.servlet.ServletConfig |
out | javax.servlet.jsp.JspWriter |
exception | java.lang.Throwable |
JSPX - XML valide JSP Dokumente
Für die Unterstützung der XML Technologie ist mit JSP2.0 für jedes Script-Element ein XML konformer Ersatz definiert:
JSP Element | XML konforme Schreibweise |
---|---|
Directives: <%@ page import=".."%> | |
Declarations: <%! int a = -1; %> | |
Scriptlets: <% boolean b = false; %> | |
plain Text: FooBar | |
Expressions: <%= person.name() %> |
JSP Standard Actions und JSP Custom Actions
Standard und Custom Actions sind JSP Anweisungen in xml Syntax. JSP Standard Actions dürfen dabei in jeder JSP verwendet werden und müssen vom JSP Übersetzer erkannt werden. JSP Custom Actions sind selber oder von Drittanbietern entwickelte JSP Anweisungen. Die Realisierung erfolgt mit Tagfiles und Tag Handler und die Deklaration der Schnittstellen in Tag Library Descriptoren (TLD). Eine Reihe von Custom Actions sind so allgemein und nützlich, dass sie als JSTL (JSP Standard Tag Library) in die Spec mit aufgenommen wurden.
Definition einer Fehlerseite 'error.jsp':
<%@ page isErrorPage="true" %> // diese Direktive macht das implizite Objekt 'error' verfügbar : Fehler...Benutzung:
<%@ page errorPage="error.jsp" %> : Division durch Null ergibt: <%= 1000/0 %>In der Errorpage ist vom Container ein zusätzliches implizites Objekt bereitgestellt:
<%@ page isErrorPage="true" %> : Fehler ${pageContext.exception.message}
<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid> true // es gibt dafür keine page directive (deprecated!) </scripting-invalid> </jsp-property-group> </jsp-config>