Inhaltsverzeichnis

Arthur Dent hatte schon lange keinen so schlechten Tag mehr wie den, an dem die Erde in die Luft flog. 🔥 Halt, Moment, Stop. Falsches Buch. 📘 Hier geht es darum, den Server in unsere Webentwicklung miteinzubeziehen.

Was passiert beim Aufruf einer Webseite?

Unsere Geschichte beginnt mit einen Browser und einem Webserver.

Und einem Anwender, der eine URL eingibt.

Daraufhin baut der Browser eine Verbindung zum Server auf.

Und sendet ihm eine Anfrage, um die Seite abzurufen. In diesem Fall eine GET-Anfrage.

Der Server antwortet mit Statuscode 200 und dem Inhalt der Seite.

Sogleich macht sich der Browser daran die Seite darzustellen.

Doch halt! Die Seite enthält ja noch Stylesheets, Skripte und Bilder.

Diese muss der Browser alle vom Server abrufen.

Und der Server antwortet fleißig mit den gesuchten Dateien.

Am Ende ist die Seite vollständig aufgebaut und die Verbindung wird getrennt.

🖼️ Nächstes Bild anzeigen

Bildnachweise: Pixabay: OpenClipart-Vectors, Pixabay: Clker-Free-Vector-Images, Pixabay: ROverhate, Pixabay: Jsprzperez

Inahlt einer HTTP-Nachricht

Verb Pfad HTTP-Version
POST /feedback/save.php HTTP/1.1 Anfragezeile
Host: www.wpvs.de
Content-Type: text/json
Accept: text/json
Connection: keep-alive
Header Fields ¹
  Leerzeile
{
    "course": "webprog",
    "year": 2017,
    "text": "Vielen Dank für diese tolle Vorlesung!"
}
Request Body ¹
HTTP-Version Statuscode Bezeichnung
HTTP/1.1 200 Ok Antwortzeile
Content-Type: text/json
Content-Length: 55
Date: Sun, 15 Oct 2017 20:18:17 GMT
Header Fields
  Leerzeile
{
    "type": "success",
    "message": "Feedback wurde gespeichert",
}
Response Body

¹ Optional

GET

  • Inhalte vom Server abrufen
  • Die Anfrage darf keinen Request Body enthalten
  • Der Server antwortet mit dem gewünschten Inhalt oder einer Fehlerseite

PUT

  • Neue Inhalte auf den Server hochladen
  • Der Inhalt der Datei muss im Request Body mitgeschickt werden
  • Der Server antwortet mit einer neuen HTML-Seite oder einer Fehlerseite

POST

  • Daten zur Verarbeitung an den Server schicken
  • Wird häufig verwendet, um vorhandene Daten auf dem Server zu aktualisieren
  • Der Server antwortet mit einer neuen HTML-Seite oder einer Fehlerseite

DELETE

  • Daten auf dem Server löschen
  • Die Anfrage darf keinen Request Body enthalten
  • Der Server antwortet mit einer neuen HTML-Seite oder einer Fehlerseite

Seltener verwendete Verben

HEAD, OPTIONS, TRACE, PATCH

1xx: Informationen

  • Zwischenmeldung, um die Verbindung aufrecht zu erhalten
  • Verhindert, dass die Verbindung durch einen Timeout vorzeitig beendet wird

2xx: Erfolgreicher Abschluss

  • Die Anfrage wurde erfolgreich bearbeitet
  • 200 OK: Alles roger! Der Response Body beinhaltet die gewünschten Daten 👌🏼
  • 202 Accepted: Die Anfrage wurde empfangen, wird aber erst später bearbeitet

3xx: Umleitung

  • Es sind weitere Aktionen vom Client notwendig
  • 300 Multiple Choice: Die Anfrage war nicht eindeutig genug
  • 301 Moved Permanently: Umleitung des Clients auf eine andere URL

4xx: Client Fehler

  • Der Client hat etwas falsch gemacht; die Verarbeitung wird abgelehnt
  • 400 Bad Request: Ungültige bzw. fehlerhafte Anfrage
  • 401 Unauthorized: Keine Berechtigung für diese Aktion
  • 403 Forbidden: Die Aktion ist prinzipiell nicht erlaubt
  • 404 Not Found: Der gesuchte Inhalt wurde nicht gefunden

5xx: Server Fehler

  • Anfrage kann aufgrund eines Serverfehlers nicht bearbeitet werden
  • 500 Internal Server Error: Schwerer technischer Fehler, alles ist kaputt! 🗑️
  • 501 Not Implemented: Die Funktion ist nicht verfügbar
  • 503 Service Unavailable: Temporärer Fehler, bitte später nochmal versuchen

HTTP/0.9

Dies war die ursprüngliche von Tim Berners-Lee entwickelte HTTP-Version, wie sie 1991 veröffentlicht wurde. In dieser Version gab es nur GET-Anfragen und noch keine Header Fields. Eine Anfrage bestand daher lediglich aus einer Zeile:

GET /index.html

Die Antwort des Servers beinhalte nur den Inhalt der abgerufenen Datei, sonst nichts.

HTTP/1.0

1996 wurde HTTP/1.0 veröffentlicht. Ab hier haben die HTTP-Nachrichten den oben gezeigten Aufbau.

HTTP/1.1

Diese Version wurde 1999 veröffentlicht und brachte weitreichende Verbesserungen. Unter anderem die Möglichkeit, die Verbindung zwischen zwei Anfragen offen zu halten. Denn zuvor wurde die Verbindung nach jeder Antwort automatisch getrennt. Da aber gerade der Verbindungsaufbau bei TCP/IP sehr langsam ist, führte dies zu langen Wartezeiten, wenn mehrere Dateien vom selben Server abgerufen werden mussten.

HTTP/2

2015 wurde HTTP/2 offiziell verabschiedet. In seinen Grundzügen basiert es auf dem von Google entwickelten SPDY-Protokoll. Die Inhalte der HTTP-Nachrichten sind weitgehend gleich geblieben, jedoch werden sie nicht mehr in der oben gezeigten Textform kodiert. Stattdessen kommt ein kompaktes und in vielen Dingen eindeutiger spezifiziertes Binärformat zum Einsatz.¹

Als weitere größere Neuerung führt HTTP/2 Server Push ein, wodurch der Server beim Abruf einer HTML-Seite selbstständig weitere Dateien an den Browser schicken kann. Somit können Stylesheets, Skripte und Bilder schon an den Browser geschickt werden, bevor dieser überhaupt weiß, dass er sie benötigen wird.

Stand 2017 hat sich HTTP/2 noch nicht gegen HTTP/1 durchgesetzt. Die meisten Webseiten verwenden weiterhin HTTP/1. Man kann aber davon ausgehen, dass sich das im Laufe der Jahre ändern wird.

¹ Beispielsweise war bei HTTP/1.x nie definiert, welche Bytefolge ein Zeilenende markiert.

Zeit für eine Demonstration

Bildnachweis für das Endesymbol: Pixabay: janf93

Aufzeichnung der HTTP-Kommunikation im Browser

Bildnachweis für das Endesymbol: Pixabay: janf93

Aufgabe 1: Ein kleines HTTP-Quiz

Aufgabe 1.1: HTTP-Verben

a) Was bedeutet das HTTP-Verb POST?

  1. Vorhandene Daten vom Server abrufen
  2. Daten auf dem Server löschen (POST = Postpone)
  3. Daten zur Verarbeitung an den Server schicken

b) Was bedeutet das HTTP-Verb DELETE?

  1. Daten im Browser löschen
  2. Daten auf dem Server löschen
  3. Prüfen, ob die Daten gelöscht werden können

c) Was bedeutet das HTTP-Verb GET?

  1. Daten vom Server abrufen, zum Beispiel eine HTML-Datei
  2. Abrufen einer Dateiliste vom Server mit allen Dateien einer Webseite
  3. Übertrag einer Datei vom Browser an den Server

Aufgabe 1.2: Statuscodes

a) Was bedeutet der Statuscode 401 Unauthorized?

  1. Die gesuchten Daten wurden nicht gefunden
  2. Die gewünschte Funktion wurde nicht ausprogrammiert
  3. Der Anwender ist für die gewünschte Funktion nicht berechtigt

b) Was bedeutet der Statuscode 503 Service Unavailble?

  1. Es ist ein temporärer Fehler aufgetreten, bitte später nochmal versuchen
  2. Es ist ein schwerwiegender Fehler aufgetreten
  3. Die gesuchte Information wurde nicht gefunden

c) Welcher Statuscode signalisiert, dass die Seite nicht gefunden wurde?

  1. 200
  2. 301
  3. 404

d) Welcher Statuscode wird geschickt, wenn alles okay ist?

  1. 100
  2. 200
  3. 300

Lösung: Aufgabe 1.1: 3, 2, 1; Aufgabe 1.2: 3, 1, 3, 2

Serverseitige Webentwicklung mit Java

Statische Dateien vs. Javacode

1. Der Webserver empfängt eine HTTP-Anfrage.
2. Da sich die Anfrage auf eine einfache Datei bezieht, sucht der Server die Datei im Dateisystem.
3. Kann der Server die Datei finden, schickt er als Antwort den Statuscode 200 sowie den Inhalt der Datei.
1. Der Webserver empfängt eine HTTP-Anfrage.
2. Dieses mal bezieht sich die Anfrage auf ein Servlet oder eine Java Server Page.
3. Der Server führt das Servlet bzw. die Java Server Page aus, um eine Antwort zu generieren.

Webcontainer vs. eingebetter Webserver

Die klassische Form der Webentwicklung in Java. Ein ein Java geschriebener Webserver (der sogenannte Webcontainer bzw. Applikationsserver) beherbergt eine beliebige Anzahl an Webanwendungen. Die Webanwendungen müssen hierfür als Webarchive verpackt und im Server deployed werden (Deployment = Die Webanwendung mit dem Server zusammenbringen).

Historisch bedingt sind Webcontainer große, schwergewichtige Applikationsserver, die viele Ressourcen benötigen und je nach Einsatzgebiet umfangreich konfiguriert werden wollen. Aber es ist wie mit jedem Schlachtschiff: 🚢 Einmal in Dienst gestellt verrichtet es viele Jahre lang seine Arbeit.

Bekannte Applikationsserver sind: Tomcat, Jetty, GlassFish, Wildfly.

Moderne Alternative zu herkömmlichen Webcontainern: Bring Your Own Webserver. Bei der Webanwendung handelt es sich um ein gewöhnliches Javaprogramm mit einem integrierten Webserver. Dieser Ansatz kommt vor allem bei Microservices und 12-Faktor-Apps zum Einsatz.

Natürlich musst du nicht gleich einen eigenen Webserver programmieren. Hierfür gibt es fertige Bibliotheken, die du in deine Anwendung einbauen kannst. Im Vergleich zu einer herkömmlichen Webanwendung ist sie dadurch viel einfacher in Betrieb zu nehmen und verbraucht in der Regel auch weniger Ressourcen. 🛥️

Bekannte HTTP-Server-Bibliotheken sind: Die Klasse HttpServer, NanoHTTPD, Undertow, Spark, Jetty.

Unsere erste Java Server Page

<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>JSP-Beispiel</title> </head> <body> <form method="post"> Name: <input name="dein_name"/> Alter: <input name="dein_alter"/> <input type="hidden" name="aktion" value="zeigen"/> <input type="submit" value="Los!"/> </form> <!-- Alles zwischen <% und %> ist Javacode --> <% if (request.getMethod().equals("POST")) { %> <h2>Bisherige Eingabe</h2> <b>Name: </b> <%= request.getParameter("dein_name") %> <br/> <b>Alter:</b> <%= request.getParameter("dein_alter") %> <br/> <% } %> </body> </html>

Der HTML-Code aus Sicht des Browsers:

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>JSP-Beispiel</title> </head> <body> <form method="post"> Name: <input name="dein_name"/> Alter: <input name="dein_alter"/> <input type="hidden" name="aktion" value="zeigen"/> <input type="submit" value="Los!"/> </form> </body> </html>

Der neue HTML-Code aus Sicht des Browsers:

<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>JSP-Beispiel</title> </head> <body> <form method="post"> Name: <input name="dein_name"/> Alter: <input name="dein_alter"/> <input type="hidden" name="aktion" value="zeigen"/> <input type="submit" value="Los!"/> </form> <h2>Bisherige Eingabe</h2> <b>Name: </b> Richard Löwneherz <br/> <b>Alter:</b> 27 <br/> </body> </html>

Wir steigen auf Netbeans um

Bildnachweis für das Endesymbol: Pixabay: janf93

Aufgabe 2: Dein erstes Netbeans-Projekt

  1. Starte Netbeans und lege ein neues Java-Webprojekt an.
  2. Lösche die standardmäßig erzeugte index.html-Datei und ersetze sie durch eine Datei namens index.jsp.
  3. Kopiere den Quellcode aus Folie 7 in die JSP-Datei und lasse sie laufen.
  4. Wenn alles soweit klappt, erweitere das Formular um die zwei Felder Telefonnummer und Hobby.
  5. Ändere den Javacode danach so ab, dass keine leeren Felder in der Bestätigungsseite angezeigt werden.
Quellcode in Netbeans
Darstellung im Browser
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>JSP-Beispiel</title> </head> <body> <form method="post"> Name: <input name="dein_name"/> Alter: <input name="dein_alter"/> <br /> Telefon: <input name="dein_telefon"/> Hobby: <input name="dein_hobby"/> <input type="submit" value="Los!"/> </form> <!-- Alles zwischen <% und %> ist Javacode --> <% if (request.getMethod().equals("POST")) { %> <h2>Bisherige Eingabe</h2> <% if (!request.getParameter("dein_name").equals("")) { %> <b>Name: </b> <%= request.getParameter("dein_name") %> <br/> <% } %> <% if (!request.getParameter("dein_alter").equals("")) { %> <b>Alter:</b> <%= request.getParameter("dein_alter") %> <br/> <% } %> <% if (!request.getParameter("dein_telefon").equals("")) { %> <b>Telefon:</b> <%= request.getParameter("dein_telefon") %> <br/> <% } %> <% if (!request.getParameter("dein_hobby").equals("")) { %> <b>Hobby:</b> <%= request.getParameter("dein_hobby") %> <br/> <% } %> <% } %> </body> </html>

Mehrere Seiten aus einem Guss

Mehrere HTML-Seiten derselben Webanwendung nutzen dasselbe Layout. Alle Seiten sollen sich dabei dasselbe HTML-Grundgerüst teilen. Doppelter Quellcode soll möglichst vermieden werden.

Hierfür wird das HTML-Grundgerüst der Seite in eine eigene Datei ausgelagert. In vielen Webframeworks wird diese Datei ein Template (deutsch „Vorlage”) genannt. Anstelle des echten Inhalts beinhaltet das Template überall Platzhalter, wo später etwas eingefügt werden soll.

<%@tag pageEncoding="UTF-8"%> <!-- Definition der Platzhalter, die unten verwendet werden. --> <!-- fragment="true" bedeutet, dass ein ganzes Stück HTML-Code eingefügt wird. --> <!-- Andernfalls wird nur ein kurzer Textausschnitt ohne HTML-Code übernommen. --> <%@attribute name="title"%> <%@attribute name="body" fragment="true" %> <%@attribute name="footer" fragment="true" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <!-- Platzhalter für den Titel --> <title>${title}</title> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body> <nav> <!-- Nochmal der Platzhalter für den Titel --> <h1>${title}</h1> <ul> <li> <a href="index.jsp">Startseite</a> </li> <li> <a href="firmenportrait.jsp">Firmenportrait</a> </li> … </ul> </nav> <main> <!-- Platzhalter für den Body-Inhalt --> <jsp:invoke fragment="body"/> </main> <footer> <ul> … </ul> <!-- Platzhalter für den Footer-Inhalt --> <jsp:invoke fragment="footer"/> </footer> </body> </html>

Der tatsächliche Inhalt, der in das Template eingefügt wird, kommt aus einer anderen Datei. Es handelt sich dabei um die eigentliche HTML/JSP-Datei, die der Anwender gerade abrufen will. 🔄 Sie beinhaltet einen Verweis auf das zu verwendende Template, so dass der Server weiß, dass er erst beide Dateien „übereinanderlegen” muss, um die fertige Seite zu erzeugen. 📄📑

<!-- Verweis auf das Verzeichnis, in dem unser Template liegt --> <%@taglib prefix="template" tagdir="/WEB-INF/tags/templates" %> <%@page contentType="text/html" pageEncoding="UTF-8"%> <!-- Aufruf des Templates mit dem Namen „base.tag“ --> <template:base> <!-- Inhalt für die Titel-Platzhalter --> <jsp:attribute name="title">Startseite</jsp:attribute> <!-- Inhalt für den Body-Platzhalter --> <jsp:attribute name="body"> <h1>Ihr perfekter Feierabend!</h1> <img src="feierabend.jpg" alt="" /> <p> Kommen Sie nach einem anstrengenden Arbeitstag nach Hause und lassen Sie sich von unseren Premiumbieren verwöhnen. Es gibt nichts besseres, um den Tag ausklingen zu lassen … </p> </jsp:attribute> <!-- Inhalt für den Footer-Platzhalter --> <jsp:attribute name="footer"> © 2017 Liquid Spirit Webdesign Ltd. <br /> Im Land wo Hopfen und Malz fließt </jsp:attribute> </template:base>

Was einmal geht, geht auch zweimal. 💕 Das HTML-Template kann natürlich für beliebig viele Seiten verwendet werden, die dadurch alle ein einheitliches Layout bekommen.

<%@taglib prefix="template" tagdir="/WEB-INF/tags/templates" %> <%@page contentType="text/html" pageEncoding="UTF-8"%> <template:base> <jsp:attribute name="title">Firmenportrait</jsp:attribute> <jsp:attribute name="body"> <h2>Alles begann als kleines Familienunternehmen</h2> <p> „Wir sollten aufhören, weniger zu trinken”. Dies war stets das Motto von Julius Sinner, bevor er 1873 seine erste kleine Brauerei gründete. Dabei hatte er nur ein äußerst bescheidenes Startkapital und der Erfolg war keinesfalls gewiss … </p> </jsp:attribute> <jsp:attribute name="footer"> © 2017 Liquid Spirit Webdesign Ltd. <br /> Im Land wo Hopfen und Malz fließt </jsp:attribute> </template:base>

Aufgabe 3: Hallo Welt mal drei

Kopiere die folgenden Java Server Pages in eine neues Java-Webprojekt und schaue, ob du es zum Laufen bekommst. Anschließend versuche, so viel HTML-Code wie möglich in ein gemeinsames Template auszulagern. Das Template sollte dabei den Dateinamen base.tag haben und im Verzeichnis WEB-INF/tags/templates liegen.

index.jsp

ehrenamt.jsp

santa.jsp

<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Startseite</title> <style> html, body { height: 100%; } html { font-family: sans-serif; font-size: 12pt; } h1 { color: crimson; } @media (min-width: 50em) { html { background-image: url(https://unsplash.it/1024/768/?image=1073); background-repeat: no-repeat; background-position: center center; background-size: cover; box-sizing: border-box; padding-top: 2em; padding-bottom: 2em; } main { width: 40em; margin: 0 auto; background: white; border: 1px solid #E5E5E5; box-shadow: 1px 1px 2px #BFBFBF; padding: 1em; } } </style> </head> <body> <main> <h1>Startseite</h1> <ul> <li> <a href="ehrenamt.jsp">Nur kein Ehrenamt</a> </li> <li> <a href="santa.jsp">Is Santa Claus A Sysadmin?</a> </li> </ul> </main> </body> </html>
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Nur kein Ehrenamt</title> <style> html, body { height: 100%; } html { font-family: sans-serif; font-size: 12pt; } h1 { color: crimson; } @media (min-width: 50em) { html { background-image: url(https://unsplash.it/1024/768/?image=1073); background-repeat: no-repeat; background-position: center center; background-size: cover; box-sizing: border-box; padding-top: 2em; padding-bottom: 2em; } main { width: 40em; margin: 0 auto; background: white; border: 1px solid #E5E5E5; box-shadow: 1px 1px 2px #BFBFBF; padding: 1em; } } </style> </head> <body> <main> <h1>Nur kein Ehrenamt</h1> Willst Du froh und glücklich leben, <br /> laß kein Ehrenamt dir geben! <br /> Willst du nicht zu früh ins Grab <br /> lehne jedes Amt gleich ab! <br /> <br /> Wieviel Mühen, Sorgen, Plagen <br /> wieviel Ärger mußt Du tragen; <br /> gibst viel Geld aus, opferst Zeit - <br /> und der Lohn? Undankbarkeit! <br /> <br /> Ohne Amt lebst Du so friedlich <br /> und so ruhig und so gemütlich, <br /> Du sparst Kraft und Geld und Zeit, <br /> wirst geachtet weit und breit. <br /> <br /> So ein Amt bringt niemals Ehre, <br /> denn der Klatschsucht scharfe Schere <br /> schneidet boshaft Dir, schnipp-schnapp, <br /> Deine Ehre vielfach ab. <br /> <br /> Willst du froh und glücklich leben, <br /> laß kein Ehrenamt dir geben! <br /> Willst du nicht zu früh ins Grab <br /> lehne jedes Amt gleich ab! <br /> <br /> Selbst Dein Ruf geht Dir verloren, <br /> wirst beschmutzt vor Tür und Toren, <br /> und es macht ihn oberfaul <br /> jedes ungewaschne Maul! <br /> <br /> Drum, so rat ich Dir im Treuen: <br /> willst Du Weib (Mann) und Kind erfreuen, <br /> soll Dein Kopf Dir nicht mehr brummen, <br /> laß das Amt doch and'ren Dummen. <br /> </main> </body> </html>
<%@page contentType="text/html" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Is Santa Claus A Sysadmin?</title> <style> html, body { height: 100%; } html { font-family: sans-serif; font-size: 12pt; } h1 { color: crimson; } @media (min-width: 50em) { html { background-image: url(https://unsplash.it/1024/768/?image=1073); background-repeat: no-repeat; background-position: center center; background-size: cover; box-sizing: border-box; padding-top: 2em; padding-bottom: 2em; } main { width: 40em; margin: 0 auto; background: white; border: 1px solid #E5E5E5; box-shadow: 1px 1px 2px #BFBFBF; padding: 1em; } } </style> </head> <body> <main> <h1>Is Santa Claus A Sysadmin?</h1> <ol> <li> Santa is bearded, corpulent, and dresses funny. </li> <li> When you ask Santa for something, the odds of receiving what you wanted are infinitesimal. </li> <li> Santa seldom answers your mail. </li> <li> Santa doesn't care about your deadlines. </li> <li> Your parents ascribed supernatural powers to Santa, but did all the work themselves. </li> <li> Nobody knows who Santa has to answer to for his actions. </li> <li> Santa laughes entirely too much. </li> <li> Santa thinks nothing of breaking into your $HOME. </li> <li> Only a lunatic says bad things about Santa in his presence </li> </ol> </main> </body> </html>

WEB-INF/tags/templates/base.tag

<%@tag pageEncoding="UTF-8"%> <%@attribute name="title"%> <%@attribute name="body" fragment="true" %> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>${title}</title> <style> html, body { height: 100%; } html { font-family: sans-serif; font-size: 12pt; } h1 { color: crimson; } @media (min-width: 50em) { html { background-image: url(https://unsplash.it/1024/768/?image=1073); background-repeat: no-repeat; background-position: center center; background-size: cover; box-sizing: border-box; padding-top: 2em; padding-bottom: 2em; } main { width: 40em; margin: 0 auto; background: white; border: 1px solid #E5E5E5; box-shadow: 1px 1px 2px #BFBFBF; padding: 1em; } } </style> </head> <body> <main> <h1>${title}</h1> <jsp:invoke fragment="body"/> </main> </body> </html>

index.jsp

<%@taglib prefix="template" tagdir="/WEB-INF/tags/templates" %> <%@page contentType="text/html" pageEncoding="UTF-8"%> <template:base> <jsp:attribute name="title">Startseite</jsp:attribute> <jsp:attribute name="body"> <ul> <li> <a href="ehrenamt.jsp">Nur kein Ehrenamt</a> </li> <li> <a href="santa.jsp">Is Santa Claus A Sysadmin?</a> </li> </ul> </jsp:attribute> </template:base>

ehrenamt.jsp

<%@taglib prefix="template" tagdir="/WEB-INF/tags/templates" %> <%@page contentType="text/html" pageEncoding="UTF-8"%> <template:base> <jsp:attribute name="title">Nur kein Ehrenamt</jsp:attribute> <jsp:attribute name="body"> Willst Du froh und glücklich leben, <br /> laß kein Ehrenamt dir geben! <br /> Willst du nicht zu früh ins Grab <br /> lehne jedes Amt gleich ab! <br /> <br /> Wieviel Mühen, Sorgen, Plagen <br /> wieviel Ärger mußt Du tragen; <br /> gibst viel Geld aus, opferst Zeit - <br /> und der Lohn? Undankbarkeit! <br /> <br /> Ohne Amt lebst Du so friedlich <br /> und so ruhig und so gemütlich, <br /> Du sparst Kraft und Geld und Zeit, <br /> wirst geachtet weit und breit. <br /> <br /> So ein Amt bringt niemals Ehre, <br /> denn der Klatschsucht scharfe Schere <br /> schneidet boshaft Dir, schnipp-schnapp, <br /> Deine Ehre vielfach ab. <br /> <br /> Willst du froh und glücklich leben, <br /> laß kein Ehrenamt dir geben! <br /> Willst du nicht zu früh ins Grab <br /> lehne jedes Amt gleich ab! <br /> <br /> Selbst Dein Ruf geht Dir verloren, <br /> wirst beschmutzt vor Tür und Toren, <br /> und es macht ihn oberfaul <br /> jedes ungewaschne Maul! <br /> <br /> Drum, so rat ich Dir im Treuen: <br /> willst Du Weib (Mann) und Kind erfreuen, <br /> soll Dein Kopf Dir nicht mehr brummen, <br /> laß das Amt doch and'ren Dummen. <br /> </jsp:attribute> </template:base>

santa.jsp

<%@taglib prefix="template" tagdir="/WEB-INF/tags/templates" %> <%@page contentType="text/html" pageEncoding="UTF-8"%> <template:base> <jsp:attribute name="title">Is Santa Claus A Sysadmin?</jsp:attribute> <jsp:attribute name="body"> <ol> <li> Santa is bearded, corpulent, and dresses funny. </li> <li> When you ask Santa for something, the odds of receiving what you wanted are infinitesimal. </li> <li> Santa seldom answers your mail. </li> <li> Santa doesn't care about your deadlines. </li> <li> Your parents ascribed supernatural powers to Santa, but did all the work themselves. </li> <li> Nobody knows who Santa has to answer to for his actions. </li> <li> Santa laughes entirely too much. </li> <li> Santa thinks nothing of breaking into your $HOME. </li> <li> Only a lunatic says bad things about Santa in his presence </li> </ol> </jsp:attribute> </template:base>

Rechtshinweise

Creative Commons Namensnennung 4.0 International

§