Web-Programmierung in Java


Servlets

Servlets sind Java-Klassen, die in einem Server, einem Servlet Container, eingebettet sind und von ihm bei Bedarf aufgerufen werden. Dieser kann insbesondere von einem Webserver verwendet oder in ihm eingebaut sein. In diesem Falle heißen sie HTTP-Servlets.

Durch entsprechende Konfiguration wird der Web-Server veranlaßt, bei der Anfrage nach bestimmten URLs den Servlet Container aufzurufen und ihm die Bearbeitung der URL zu überlassen. Das Ergebnis der Bearbeitung wird dann vom Web-Server an den Aufrufer zurückgegeben.

Die Servlet-Klasse

HTTP-Servlets werden von der Klasse HttpServlet abgeleitet und definieren u. a. folgende Methode :

    protected void doGet (HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException;

req liefert Informationen über den Aufruf des Servlets.

resp bietet Möglichkeiten, Ausgaben zu erzeugen und damit ein Ergebnis zu liefern.

Je nach zu unterstützender HTTP-Methode können auch entsprechende Methoden doPost und doPut definiert werden.

Nach einer Änderung und Rekompilierung wird die Klasse beim nächsten Aufruf automatisch neu geladen.

Ausgaben eines Servlets

Die HttpServletResponse-Klasse bietet für die Ausgabe u. a. folgende Methoden :

    public void setContentType (String type);

setzt den MIME-Typ der Ausgabe, z. B. "text/html".

    public PrintWriter getWriter () throws IOException;

liefert ein Objekt, mit dem das Servlet Text-Ausgabe erzeugen kann. PrintWriter bietet Methoden print und println zur Ausgabe diverser Datentypen.

    public ServletOutputStream getOutputStream () throws IOException;

liefert ein Objekt, mit dem das Servlet Daten-Ausgaben erzeugen kann. Dies ist z. B. für Bilder geeignet.

    public void sendRedirect (String location) throws IOException;

veranlaßt den Browser, eine Umleitung zu einer anderen URL durchzuführen. Dies kann insbesondere in einer doPost-Methode nach dem Empfang von Formulardaten verwendet werden.

Im Fehlerfall kann folgende Methode verwendet werden :

    public void setStatus (int sc);

setzt den Status-Code der Antwort. Hierfür bietet die Klasse HttpServletResponse diverse Konstanten, z. B. SC_NOT_FOUND (=404) und SC_UNAUTHORIZED (=401)

Beispiel: TestServlet.java

Eingaben eines Servlets

Die HttpServletRequest-Klasse bietet folgende Methoden, um Informationen über den Request zu lesen :

    public Enumeration getHeaderNames ();

liefert eine Aufzählung der Namen der Request Header.

    public String getHeader (String name);

liefert den Wert eines Headers.

Beispiel: ShowHeaders.java

    public Enumeration getParameterNames ();

liefert eine Aufzählung der Namen der Request Parameter.

    public String getParameter (String name);

liefert den Wert eines Parameters.

Parameter können sowohl in der URL als auch mit der HTTP-POST-Methode über ein HTML-Formular übergeben werden.

Beispiel: ShowParms.java

Session Tracking

Session Tracking ist das Problem, einen Anwender von Seite zu Seite zu verfolgen. Dies ist nötig, um jeweils zu ihm gehörige Informationen anzuzeigen, z. B. einen Einkaufskorb.

Hierzu wird eine Session über das HttpServletRequest-Objekt erzeugt bzw. wiedergefunden :

    public HttpSession getSession ();

Über das Session-Objekt können nun beliebige Daten in Form von Objekten als Attribute mit Namen gespeichert werden :

    public void setAttribute (String name, Object value);

So gespeicherte Objekte können auch nach ihrem Namen wiedergefunden werden :

    public Object getAttribute (String name);

Das Session Tracking geschieht automatisch, sofern möglich, über Cookies. Es wird eine eindeutige Session ID erzeugt und unter einem bestimmten Namen als Cookie an den Browser gegeben, der dieses beim nächsten Zugriff wieder zurückgibt. Damit es auch ohne Cookies funktioniert, müssen die Ausgaben aller URLs in HTML, die das Session Tracking betreffen, über die Methode encodeURL des Response-Objektes gefiltert werden :

    out.print ("<FORM METHOD=POST ACTION=");
    out.print (resp.encodeURL ("elug.servlet.TestServlet"));
    out.println (">");

Dies bewirkt, daß, wenn Cookies nicht verwendet werden können, stattdessen ein entsprechender Parameter in die URL eingebaut wird. Wenn der ausgegebene Verweis später vom Browser verwendet wird, so sendet er den in ihm enthaltenen Parameter wieder zurück, was der Servlet Container dann automatisch erkennt.

Beispiel: SessCounter.java

Web Applications

Eine Web Application ist ein geschlossener Bereich innerhalb des Servlet Containers, der für ein Web-Anwendungsprogramm gedacht ist. Servlets innerhalb einer Web Application kommen nicht an Informationen von Servlets außerhalb der Web Application.

Verschiedene Web Applications können auch verschiedene Sicherheitsbeschränkungen haben.

Eine Web Application kann neben Servlets auch andere Dateien enthalten. Alle diese Dateien stehen unterhalb der URL, die die Web Application darstellt.

Beispiel :

Eine Web Application habe die URL http://localhost/elug/. Dann kann ein Servlet als http://localhost/elug/servlet/elug.servlets.TestServlet aufgerufen werden. Eine Bilddatei wäre unter http://localhost/elug/images/tomcat.gif zu finden.

Jede Web Application hat eine eigene Konfigurationsdatei.

Beispiel: WEB-INF/web.xml

Hierin können Servlets bestimmten URLs zugeordnet werden.

Aus dieser Konfigurationsdatei können auch übergreifende Context Initialization Parameters gelesen werden :

Beispiel: ShowContext.java

Threads in Servlets

Der Servlet Container erzeugt normalerweise für jede Servlet-Klasse nur eine Instanz, auch wenn es mehrfach gleichzeitig aufgerufen wird. Bei der Programmierung eines Servlets muß dies berücksichtigt werden. Ist dies nicht zu erreichen, so kann das Servlet das Interface SingleThreadModel implementieren. Dies bewirkt, daß der Servlet Container die mehrfache Ausführung eines Servlet-Objektes verhindert.


JavaServer Pages

Eine JavaServer Page ist eine Beschreibung eines Servlets. Ähnlich PHP gibt man eine HTML-Seite an, in die man über bestimmte Kennzeichen Java-Code einsetzen kann.

Beim Aufruf einer JSP wandelt ein JSP Processor die Seite in ein Servlet um, kompiliert es und ruft es anschließend auf. Für die erzeugte Klasse ist nur folgendes zu wissen nötig :

Statt der Methode doGet, doPost usw. wird nur eine einzige Methode erzeugt, die aber die gleichen Parameter hat. Diese heißen request und response. Zur Ausgabe von HTML-Code kann das Object out verwendet werden.

Angabe von Java-Code

Java-Code wird in <% %> eingeschlossen. Ein solcher Code wird unverändert in die erzeugte Service-Methode des Servlets übernommen. Darin stehen alle Möglichkeiten des Servlets zur Verfügung.

Ausdrücke zur Ausgabe von Werten können in <%= %> eingeschlossen werden.

    <TABLE>
    <%
      for (int i = 0; i < count; i++)
        {
    %>
          <TR>
            <TD><CODE><%= i %></CODE>
            <TD><CODE><%= myValue (i) %></CODE>
          </TR>
    <%
        }
    %>
    </TABLE>

Deklarationen

Um zusätzliche Angaben außerhalb der Methode machen zu können, kann man sie in <%! %> einschließen. Auf diese Weise können Feldvariablen deklariert oder Methoden definiert werden.

    <%!
      private static int count = 10;
      private int myValue (int x)
      {
        return (x * 2 + 1);
      }
    %>

Zusätzlich gibt es noch die Möglichkeit, über eine geeignete Syntax übergreifende Angaben zu machen. Dies gilt insbesondere für Import-Anweisungen :

    <%@ page import="java.sql.*" %>

Beispiel: testjsp.jsp
Beispiel: showhdrs.jsp

Include Files

Es können an jeder Stelle Include Files aufgerufen werden :

    <%@ include file="jspincl.jsp" %>

Sessions

Sessions stehen in JSP als Variable session zur Verfügung. Die Verwendung erfolgt genau wie in Servlets.

Beispiel: sesscount.jsp

Sonstiges

Auch Kommentare (JSP und HTML) sind möglich :

    <%-- Dies ist ein JSP-Kommentar --%>
    <!-- Dies ist ein HTML-Kommentar -->

JSPs können über besondere Tags mit JavaBeans und Tag Libraries zusammenarbeiten.

JavaBeans sind Objekte von Java-Klassen, deren Methoden eine bestimmte Namenskonvention einhalten. Sie können als Vermittler zwischen der Oberfläche und der Programmlogik verwendet werden.

Tag Libraries sind Sammlungen von Java-Klassen, die über besondere selbstdefinierte Tags der Form <Prefix:TagName> (auch mit Attributen) aufgerufen werden. Der Sinn liegt auch hier hauptsächlich in der Trennung zwischen Oberfläche und Programmlogik.

Die JSP Engine ist als Servlet implementiert. Entsprechend wird JSP über die Servlet Engine konfiguriert.


Cocoon

Cocoon bietet die Möglichkeit, Webseiten in XML zu erstellen.

Die XML-Datei wird über die angegebene URL lokalisiert, mittels eines XML-Parsers in einen Objekt-Baum, ein Document Object Model (DOM), umgewandelt, dann ggf. bearbeitet und schließlich über ein Formatting Object in ein Dokument-Format umgewandelt. Dieses wird dann an den Aufrufer zurückgegeben.

Die Bearbeitungs- und Formatierungs-Schritte werden in der XML-Datei durch Processing Instructions festgelegt.

HTML-Seiten in XML

Auf diese Weise kann man zunächst ein HTML-Dokument in XML-Syntax erstellen und direkt zur Ansicht bringen. Über eine entsprechende Processing Instruction wird die Umwandlung der XML-Datei nach HTML veranlaßt :

    <?cocoon-format type="text/html"?>

Beispiel: testhtml.xml

XSLT

Um die darzustellenden Daten von der Art der Darstellung zu trennen, gibt es Style Sheets. Diese werden in der eXtensible Stylesheet Language (XSL) erstellt. Diese wiederum verwendet die XML-Syntax.

Ein Style Sheet ist eine Beschreibung, wie der eXtensible Style Sheet Transformator (XSLT)ein XML-Dokument in ein anderes umwandeln soll.

Im aufgerufenen XML-Dokument kann man sich dadurch auf die Angabe der eigentlichen Informationen beschränken. Im Style Sheet wird dann beschrieben, wie die Informationen als HTML-Dokument dargestellt werden sollen.

Die Auswahl des Style Sheets erfolgt durch eine Processing Instruction :

    <?cocoon-process type="xslt"?>
    <?xml-stylesheet href="URL" type="text/xsl"?>

Im Style Sheet ist es möglich, zusätzliche Processing Instructions zu erzeugen, die die weitere Bearbeitung steuern.

Beispiel: testxml.xml testxml.dtd testxml.xsl
Beispiel: testdata.xml data.dtd data.xsl

Java und XML

Um Java-Programmcode in eine XML-Datei einzubauen, gibt es eXtensible Server Pages (XSP). Auch diese verwenden die XML-Syntax.

Die Behandlung einer XML-Datei als XSP wird durch eine Processing Instruction angegeben :

    <?cocoon-process type="xsp"?>

XSPs werden ähnlich JSPs mit Hilfe eines XSP Processors in eine Java-Klasse umgewandelt, jedoch nicht in ein Servlet, sondern in einen Content Producer. Dies ist eine Klasse, die eine Methode definiert, die beim Aufruf ein DOM erzeugt.

Diese Klasse wird dann kompiliert und anschließend die Producer-Methode aufgerufen. Danach werden wie bei statischen XML-Dateien die übrigen Processing Instructions bearbeitet.

Java-Code wird innerhalb eines Logic-Elementes gesetzt :

    <xsp:logic>
        JavaProgramCode
    </xsp:logic>

Im Java-Code lassen sich die von den JSPs bekannten Variablen request, response und session verwenden.

Ausgaben lassen sich mit dem Expression-Element durchführen :

    <xsp:expr>Expression</xsp:expr>

Globale Deklarationen, z. B. Import-Anweisungen werden in ein Structure-Element gesetzt :

    <xsp:structure>
        <xsp:include>JavaClass</xsp:include>
    </xsp:structure>

Beispiel: showdata.xml data.dtd data.xsl
Beispiel: sesscount.xml sesscount.dtd sesscount.xsl

Auch Style Sheets lassen sich als XSP formulieren.

Ein Style Sheet kann auch eine XSP erzeugen.

Cocoon bietet eine Statusseite Cocoon.xml, auf der man die Konfiguration prüfen kann.

Sonstiges

Außer für HTML gibt es auch Formatting Objects zur Erstellung von Text-Dokumenten und PDF-Dokumenten.

Cocoon ist als Servlet implementiert. Entsprechend wird Cocoon über die Servlet Engine konfiguriert.


Schlußbemerkung

Servlets, JSPs und Cocoon lassen sich auch in beliebiger Kombination verwenden. So kann man je nach Bedarf die Vorteile der verschiedenen Techniken nutzen.


Thomas Conze <thomas.conze@gmx.net>