Servlet und JSP verbinden

Kleine Exkursion in die Welt von JavaServerPages und Servlets und wie man dazwischen Daten austauschen kann. Zunächst mal die einfache Seite, die JSP :

<%@ page import="java.net.IDN,misc.*,web.*,java.util.*,rsi.*,hash.*,sendmail.Sendmail,java.io.*,server.*,org.json.JSONArray,org.json.JSONObject,ordb.Pandora_server" pageEncoding="UTF-8"
%><%@ include file="cookies.jsp"
%><jsp:useBean id="daten" scope="session" class="hash.StringHash"
/>

Der JSP:useBean Tag ermöglicht u.a. sessionbasierte Objekte in einer JSP zu verarbeiten. Überall wo man den Tag angibt, ist das Objekt verfügbar. Da kann man dann ganz normal drauf zugreifen und mit arbeiten.

if ( daten.checkContent() ) out.write("Daten wurden geprüft und für OK befunden");

Wenn nun ein zweiter Teil der Anwendung in einem Servlet geschrieben wurde,  möchte man ggf. Daten zwischen beiden Teilen der Anwendung austauschen. Ein Servlet ist nichts anderes als eine Klasse, deren vordefinierte Methoden das Request- und Responseobjekt des Webaufrufes bekommen.

Ein kleines, stark vereinfachtes Beispiel:

public class HTMLDispatcher extends HttpServlet {

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws IOException {
    doRequest(req,res);
}

public void doPut(HttpServletRequest req, HttpServletResponse res)
throws IOException {
    doRequest(req,res);
}

public void doDelete(HttpServletRequest req, HttpServletResponse res)
throws IOException {
    doRequest(req,res);
}

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws IOException {
    doRequest(req,res);
}

...
}

Das Servlet kann man dann im Tomcat ( WebApplicationServer ) als Ziel für verschiedene Webaufrüfe definieren (siehe unten). In meinem Fall habe ich gesagt, daß mein Servlet für HTML Aufrüfe zuständig ist. Mein Servlet wertet dann die URL aus und macht mit dem HTML File noch einiges, bevor es ausgegeben wird.

public void doRequest(HttpServletRequest request, HttpServletResponse res)
throws IOException {

res.setContentType("text/html");
Writer out = new BufferedWriter(new OutputStreamWriter(res.getOutputStream(), "UTF-8"));

String method = request.getMethod();
String uri = request.getRequestURI();
String[] args = uri.split("/",-1); // Alles splitten, auch wenn es leer ist

StringHash daten = (StringHash) request.getSession().getAttribute("daten");
if ( daten == null ) daten = new StringHash();

Um an die Daten aus der JSP zu kommen, setze ich „request.getSession().getAttribute(„daten“)“ ein. Das geht aber nur mit Sessionobjekten so. Da die Methode getAttribute() ein klassenloses Objekt zurück gibt, muß selbst den TypeCast machen. Wenn noch keine Session aufgebaut wurde, kann es auch noch kein Bean geben, das wir uns krallen könnten. Damit die Anwendung dann nicht abschmiert, lege ich hier ein Objekt an. Natürlich kann man an der Stelle auch eine Fehlermeldung oder einen Redirect auslösen. Das ist situationsabhängig.

O== Warum überhaupt Servlet und JSP mischen ?

Servlets müssen kompiliert und der WAS Server üblicherweise neu gestartet werden, um die Änderungen anzunehmen. Wenn man JSP Seiten benutzt kümmert sich Jasper darum. Das spart im Einzelfall eine Menge Zeit und man verliert dabei auch keine Sessionobjekte, d.h. kleinere Fehler kann man direkt beheben und weitermachen. Zweifelsfrei eine zeitsparende Methode seine Webseiten zu bauen.

O== Wofür setzt man ein Servlet ein ?

Servlets können auf spezielle Webanfragen eingestellt werden, d.b. bspw. alle Files die auf .jos enden, könnten eine serialisierte Repräsentation des JavaObjekts einer Seite ausgeben, statt HTML Code. Das bekommt man mit reinen JSP Seiten nicht hin.

O== Wie aktiviert man ein Servlet ?

Im WEB-INF Verzeichnis der Anwendung liegt die web.xml Datei. In dieser Datei kann man ein Servlet ganz leicht hinzufügen:

    <servlet>
        <servlet-name>HTMLDispatcher</servlet-name>
        <servlet-class>servlet.HTMLDispatcher</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HTMLDispatcher</servlet-name>
        <url-pattern>*.html</url-pattern>
    </servlet-mapping>

Die nötigen Klassen müssen dann im dortigen classes Verzeichnis hinterlegt sein.