Protokoll Stunde 13

Werbung
Praktikum aus Softwareentwicklung 2, Stunde 13
Lehrziele/Inhalt
1. JSP Custom Tags
2. Applets
JSP Custom Tags
EL und die JSTL ersetzen Scriptlets in weiten Teilen von Web-Anwendungen, manchmal braucht man
aber Funktionen die in der JSTL fehlen. Da wir auf Scriptlets verzichten wollen, um die JSP-Seiten
sauber zu halten brauchen wir eine Lösung eigenen Code in Tags zu packen. In JSP können wir dazu
Custom Tags implementieren. Seit JSP 2.0 (zeitgleich mit Servlet API 2.4 und J2EE 1.4) gibt es mit
Simple Tags und Tag Files bequeme Möglichkeiten eigene Tags zu erzeugen. Vor JSP 2.0 war es
komplexer eigene Tags zu implementieren. Sollte es notwendig sein die alte API zu verwenden findet
man dazu Dokumentation wenn man nach JSP classic Tags sucht.
Tag Files
Tag Files sind die einfachste Art eigene Tags zu erstellen. Mit Tag Files kann man Teile einer JSP-Seite
auslagern, zB: Header oder Footer die auf allen Seiten einer Webanwendung gleich sind. Tag Files
können Parametriert werden, zB: der Titel der Web-Seite im Header. Größere Text-/Html-Blöcke
können als Tag-Body übergeben werden.
Installiert werden Tag Files indem man sie im Verzeichnis WEB-INF/tags/ (oder einem
Unterverzeichnis davon) ablegt, um sie zu nutzen muss man eine taglib-Direktive in die JSP-Seite
einfügen. Über die taglib-Direktive muss angegeben werden welcher Präfix verwendet werden soll
und wo die Tags abgelegt sind.
In Abbildung 31 ist eine JSP-Seite zu sehen die Tag Files nutzt. In der taglib-Direktive ist angegeben,
dass die Tags mit dem Präfix psw2tf angesprochen werden, und dass die Tags direkt im Verzeichnis
WEB-INF/tags liegen. Das Beispiel nutzt die Tags header, footer und disclaimer. Mit dem Tag header
wird der HTML-Seiten-Header eingebunden, er benötigt den Parameter title, dieser wird als Titel der
Webseite ausgegeben. Parameter in einem Tag File werden mit der Direktive attribute bekannt
gemacht. Die Implementierung ist in Abbildung 32 gegeben. Weiter nutzt die Seite den Tag footer der
die Webseite abschließt (siehe Abbildung 33), er ist parameterlos. Und den Tag disclaimer (siehe
Abbildung 34) der den übergebenen Body als Parameter verwendet und als Disclaimer-Text ausgibt.
Will man Tag Files in mehreren Anwendungen verwenden lohnt es sich diese in eine JAR-Datei zu
verpacken. Tag Files in JAR-Dateien müssen im Verzeichnis META-INF/tags/ (oder einem
Unterverzeichnis davon) liegen und eine Beschreibung der Tags muss als Tag Library Descriptor
vorliegen. Der Aufbau dieser Beschreibungen ist im Abschnitt Simple Tags beschrieben.
© Markus Löberbauer 2010
Seite 57
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="psw2tf" tagdir="/WEB-INF/tags/" %>
<psw2tf:header title="Hello Page"/>
<h1>Hello PSW2 Students!</h1>
<p>
Welcome to the shiny world of JSP programming.
In this course you will learn everything
you'll ever need!
Hello PSW2 Students!
</p>
<psw2tf:disclaimer>
to the shiny world of JSP programming. In
Everything written on this page may be Welcome
this course you will learn everything you'll ever
exaggerated, or just plain wrong.
need!
</psw2tf:disclaimer>
<psw2tf:footer />
Disclaimer
Abbildung 31) JSP Seite mit Custom Tags aus Tag Files
Everything written on this page may be exaggerated,
or just plain wrong.
<%@tag description="standard header tag for our web application"
pageEncoding="UTF-8"%>
<%@attribute name="title" required="true"
description="title of the page" rtexprvalue="true"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${title}</title>
</head>
<body>
Abbildung 32) Beispiel Tag mit Parameter (Seiten-Header)
<%@tag description="standard footer for our web application"
pageEncoding="UTF-8"%>
</body>
</html>
Abbildung 33) Beispiel Tag File ohne Parameter (Seiten-Footer)
<%@tag description="web site disclaimer" pageEncoding="UTF-8"%>
<p>
Disclaimer<br>
<em>
<jsp:doBody />
</em>
</p>
Abbildung 34) Beispiel Tag File das den Body des Tags nutzt (Disclaimer).
Simple Tags
Tag Files vermeiden Code-Verdopplung in JSP-Seiten, aber wenn man Programmlogik braucht sind
Tag Files zu wenig. Dann kommen Custom Tags ins Spiel. Die einfachste Möglichkeit Custom Tags zu
programmieren sind Simple Tags. Jeder Simple Tag muss das Interface SimpleTag implementieren, in
der Praxis leitet man dafür von der Klasse SimpleTagSupport ab. Die Klassen um Tags zu
implementieren liegen im Paket javax.servlet.jsp.tagext. Damit der Web-Container die Tags findet
muss man eine Tag Library Description (TLD) schreiben.
© Markus Löberbauer 2010
Seite 58
Abbildung 35 zeigt eine JSP-Seite die Studenten, mit Hilfe des Custom Tags StudentFilter, anzeigt. Mit
der Direktive taglib wird die Tag-Library in die Seite eingebunden. Abbildung 36 zeigt den Tag
StudentFilterTag.
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="psw2tag"
uri="http://ssw.jku.at/Teaching/Lectures/PSW2/2010/" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>Students</title></head>
<body>
<h1>Active Students</h1>
<ol>
<psw2tag:StudentFilter activeOnly="true"
students="${students}"
var="student">
<li>${student.name}</li>
</psw2tag:StudentFilter>
</ol>
<h1>All Students</h1>
<ol>
<psw2tag:StudentFilter students="${students}">
<li>${var.name}</li>
</psw2tag:StudentFilter>
</ol>
</body>
</html>
Active Students
1.
2.
Susi Brain
Max Power
All Students
1.
2.
3.
4.
Susi Brain
Jack Smart
Max Power
Anna Cool
Abbildung 35) Beispiel-JSP-Seite mit Simple Tags
public class StudentFilterTag extends SimpleTagSupport {
private String controlVariable = "var";
private boolean activeOnly;
private Iterable<Student> students;
@Override
public void doTag() throws JspException, IOException {
JspFragment body = getJspBody();
if (body == null) { return; }
JspContext context = getJspContext();
for (final Student student : students) {
if (activeOnly && !student.isActive()) { continue; }
context.setAttribute(controlVariable, student);
body.invoke(null);
}
}
public void setStudents(Iterable<Student> students) {
this.students = students;
}
public void setActiveOnly(boolean activeOnly) {
this.activeOnly = activeOnly;
}
public void setVar(String controlVariable) {
this.controlVariable = controlVariable;
}
}
Abbildung 36) Beispiel Simple Tag; Liefert die Studenten der Reihe nach, gefiltert nach Aktivität
© Markus Löberbauer 2010
Seite 59
Simple Tags erben von SimpleTagSupport und überschreiben die Methode doTag, diese wird zum
Rendern des Tags aufgerufen. Der Lebenszyklus eines Tags ist wie folgt:
Der Web-Container lädt bei der ersten Verwendung eines Tags die Tag-Klasse und dann …
1.
2.
3.
4.
5.
6.
7.
erzeugt ein Objekt des gewünschten Tags über den Default-Konstruktor
setzt den Jsp-Context über setJSPContext
setzt den Eltern-Tag, falls der Tag in einem anderen Tag geschachtelt ist
setzt alle Attribute über die Setter-Methoden
setzt den Body über setJSPBody, falls der Tag einen Body hat
ruft die Methode doTag auf
verwirft das Tag-Objekt
Aus dem Lebenszyklus sehen wir, eine Tag-Klasse benötigt einen parameterlosen Default-Konstruktor
und ein Tag-Objekt wird nur einmal benutzt, d.h. man kann sich darauf verlassen, dass die Attribute
die richtigen Werte haben; und manuelle Bereinigung des inneren Zustands unnötig ist.
<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd">
<short-name>psw2tag</short-name>
<tlib-version>1.0</tlib-version>
<uri>http://ssw.jku.at/Teaching/Lectures/PSW2/2010/</uri>
<tag>
<name>StudentFilter</name>
<tag-class>
at.jku.ssw.psw2.jsptutorial.tag.StudentFilterTag
</tag-class>
<body-content>scriptless</body-content>
<attribute>
<name>students</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.util.Iterable</type>
</attribute>
<attribute>
<name>activeOnly</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>var</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>control variable</description>
</attribute>
</tag>
</taglib>
Abbildung 37) Tag Library Descriptor für den Beispiel-Tag StudentFilterTag
© Markus Löberbauer 2010
Seite 60
Abbildung 37 zeigt den TLD für unseren StudentFilter, darin ist festgelegt welche Klasse für den Tag
verwendet werden soll und welche Attribute der Tag hat. Ein TLD hat einen eindeutigen Namen (uri),
eine Kurzbezeichnung (short-name), eine Version (tlib-version) und optionale Daten wie zB: eine
Beschreibung (description) und ein Icon (icon). In einer TLD können beliebig viele Tags (tag) und Tag
Files (tag-file) beschrieben werden.
Abbildung 38 zeigt die Datenklasse Student für das Beispiel. Ein Student hat einen Namen und einen
Status ob er aktiv ist. Abbildung 39 zeigt das Servlet mit der Anbindung an die Geschäftslogik und
dem Aufruf der Seite showStudents.jsp.
package at.jku.ssw.psw2.jsptutorial.model;
public class Student {
private final String name;
private final boolean active;
public Student (final String name, final boolean active) {
this.name = name;
this.active = active;
}
public String getName() {
return name;
}
public boolean isActive() {
return active;
}
}
Abbildung 38) Beispiel-Datenklasse: Student
public class ShowStudentsServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("students", getStudents());
RequestDispatcher rd = request.getRequestDispatcher(
"/WEB-INF/jsp/showStudents.jsp");
rd.forward(request, response);
}
private Iterable<Student> getStudents() {
// read students, e.g. from a database
// ...
return students;
}
}
Abbildung 39) Beispiel-Servlet: Liest Studenten und leitet an die Beispiel-JSP-Seite weiter
© Markus Löberbauer 2010
Seite 61
Applets
Mit Applets hat Sun die Möglichkeit geschaffen Java Programme in Webseiten einzubetten. Applets
können mit AWT oder mit Swing entwickelt werden, dazu muss man eine Klasse von
java.applet.Applet bzw. javax.swing.JApplet ableiten.
Damit Applets auf dem lokalen Rechner keinen Schaden anrichten können werden sie in einer
sicheren Umgebung (Sandbox) ausgeführt. Dadurch wird verhindert, dass: Applets auf das lokale
Dateisystem zugreifen, Netzwerkverbindungen aufbauen, gefährliche System-Aufrufe ausführen (zB:
System.exit), die Zwischenablage auslesen oder sicherheitskritische System-Properties abfragen.
Benötigt man Zugriff auf diese sicherheitskritischen Dinge muss man sein Applet signieren, dann fragt
Java den Benutzer ob er dem Applet die Zugriffe erlaubt.
Der Lebenszyklus von Applets besteht aus vier Methodenaufrufen:
1. init, wird aufgerufen sobald das Applet geladen wird, hier kann zB: die GUI aufgebaut,
Threads gestartet oder Ressourcen geladen werden
2. start, wird jedes Mal aufgerufen wenn das Applet angezeigt wird, zeigt ein Applet eine
Animation, kann diese hier gestartet werden
3. stop, der Browser ruft diese Methode wenn das Applet nicht mehr angezeigt wird, hier kann
die Animation wieder gestoppt werden
4. destroy, hier können Ressourcen freigegeben werden
Wir beschäftigen uns hier mit der Swing-Version von Applets, und wie Swing allgemein sind auch
JApplets nicht threadsicher. Das heißt, Änderungen an der GUI müssen im GUI-Thread erfolgen.
Abbildung 40 zeigt eine JSP-Seite mit einem Applet, im Tag applet wird festgelegt wie groß das Applet
sein soll, wo die Jar-Datei liegt und wie die Applet-Klasse heißt. Im Body des Applet-Tags können
Parameter angegeben werden, in unserem Fall wird der Parameter name auf Alex gesetzt. Außerdem
ist im Body ein Text hinterlegt der angezeigt werden soll falls der Browser nicht mit Applets umgehen
kann. Die Zugehörige Applet-Klasse ist in Abbildung 41 gegeben.
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Applet Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<applet width="200" height="150"
code="at.jku.ssw.psw2.applet.TestApplet"
codebase="<c:url value="/"/>"
archive="TestApplet.jar">
<param name="name" value="Alex"/>
Please enable Applets in your browser.
</applet>
</body>
</html>
Abbildung 40) Beispiel JSP-Seite mit Applet
© Markus Löberbauer 2010
Seite 62
package at.jku.ssw.psw2.applet;
public class TestApplet extends JApplet {
private String name;
private JLabel label;
@Override public void init() {
name = getParameter("name");
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
label = new JLabel("Name: " + name);
getContentPane().add(label, BorderLayout.CENTER);
}
});
} catch (Exception ex) {
Logger.getLogger(TestApplet.class.getName())
.log(Level.SEVERE, null, ex);
}
// allocate resources here
}
@Override public void start() {
// start animations here
}
@Override public void stop() {
// stop animations here
}
@Override public void destroy() {
// cleanup resources here
}
}
Abbildung 41) Beispiel Applet, zeigt den Wert des Parameters "name" in einem Label an
© Markus Löberbauer 2010
Seite 63
Herunterladen