Servlets mit JSP nutzen
In diesem Abschnitt lernen wir verschiedene Möglichkeiten kennen, JSP und Servlets zusammen in einem Request zu verwenden. Das bietet sich an, wenn Sie komplizierten Java-Code lieber in einem Servlet erledigen wollen, aufwendiges HTML zur Präsentation der berechteten Daten aber besser in einer JSP ausführen.
Redirect
Die einfachste Methode, aus einem Servlet eine JSP aufzurufen, ist dem Browser einen Redirect zu senden. Über einen 302 Header wird der Browser angewiesen, die angeforderte Ressource unter einer anderen URL anzufordern.
Code: /code2html/jspkurs/bsp/kap3/Redirect_1.java.html
response.sendRedirect( request.getContextPath()+"/bsp/kap3/redirect_1.jsp?date=" + date);
Wir haben dies schon öfter so gemacht, allerdings hat das Verfahren hier Nachteile:
- Wir erzeugen zusätzlichen Traffic, da der Browser eine neue Seite anfordern muss.
- Wir müssen Daten, die aus dem Servlet kommen und in der JSP angezeigt werden sollen, wieder umständlich über URL-Parameter oder gar die Session weiterleiten.
Forward
Statt den Browser anzuweisen, eine neue URL anzufordern, können wir den Request auch intern auf dem Server auf eine andere Ressource weiterleiten. Wir nutzen dazu den javax.servlet.RequestDispatcher.
Code: /code2html/jspkurs/bsp/kap3/Redirect_2.java.html
// RequestDispatcher aus dem Request holen und
// gewünschte Seite übergeben
RequestDispatcher requestDispatcher =
request.getRequestDispatcher(
"/bsp/kap3/redirect_2.jsp");
// Alles, was wir brauchen als Attribut in den Request packen
request.setAttribute("date", date);
// an die JSP forwarden.
requestDispatcher.forward(request, response);
Den Request-Dispatcher besorgen wir und aus dem Request, indem wir ihm mitteilen, auf welche Seite wir weiterleiten wollen. Bitte beachten Sie, dass der Kontextpfad ("/jspkurs") hier nicht anzugeben ist. Anschließend rufen wir die forward - Methode des Request-Dispatcher auf, wobei wir Referenzen auf die Request und Response Objekte übergeben müssen.
Jetzt ist es auch ziemlich einfach, der JSP Werte zu übergeben. Wir nutzen dazu das request Objekt, dem wir Attribute zuweisen können.
In der JSP können wir das Attribut dann einfach wieder auslesen:
/bsp/kap3/redirect_2.jsp
<%=request.getAttribute("date") %>
Da sich das Attribut auf dem Request Scope befindet, wird es gelöscht, wenn der Request abgearbeitet ist, und wir belasten den Speicher nicht unnötig.
Im Unterschied zum Redirekt oben bekommt der Browser vom Forward nichts mit. Der Forward wird intern auf dem Server abgearbeitet, und erst nachdem sämtliche Forwards erledigt sind, wird das Produkt unter der angeforderten URL and den Client ausgegeben. Dies kann leider einige ernste Folgen haben, wenn wir wie in diesem Fall unterschiedliche Pfade für Servlet und JSP verwenden. Unser Servlet ist unter /jspkurs/redirect2 zu erreichen, die JSP liegt aber faktisch in /jspkurs/bsp/kap3/redirect_2.jsp.
Auf diese Weise können wir den Browser ganz schön hereinlegen. Wie Sie bemerken, findet der Browser die Bilder nicht mehr, da er sich auf /jspkurs/redirect2 wähnt und das Bild wegen der relativen Verlinkung in an der falschen Stelle sucht. Das ist natürlich unschön. Was können wir tun?
Eine einfache Abhilfe wäre, das Servlet in dem Deployment-Descriptor (web.xml) auf denselben Pfad zu mappen, in dem sich auch die JSP befindet, auf die es forwardet. Wir würden dann schreiben:
<servlet-mapping>
<servlet-name>Redirect_2</servlet-name>
<url-pattern>/bsp/kap3/redirect2</url-pattern>
</servlet-mapping>
und das Servlet mit http://localhost:8080/jspkurs/jsp/redirect2 aufrufen. Damit wären wir aus dem Schneider, außer:
- wir wollen Verzeichnisstruktur unseres Servers beispielsweise aus Sicherheitsgründen nicht offen legen,
- wir wünschen gerade eine kurze URL für unser Servlet (Einsprungseite für Bannerwerbung etc.)
- wir verwenden das Servlet mit unterschiedlichen JSP, auf die wir forwarden.
Eine zweite Möglichkeit ist, in der JSP den BASE Tag zu setzen:
Code: /bsp/kap3/redirect_2.jsp
Wenn Sie den Base-Tag im Head-Bereich der HTML-Seite unterbringen, werden Sie bemerken, dass nun die Bilder erscheinen, da der Browser dann die korrekte URL kennt. Leider interpretieren nicht alle Browser das BASE Tag auf gleiche Weise, und insbesondere bei anschließenden Seitenaufrufen mit JavaScript hat man auch schon einmal Pech.
Als letzte Möglichkeit kann man auch alle Ressourcen, die in der JSP genutzt werden, auf die Document Root verlinken. Unser Image Tag würde dann heißen:
<img src="<%=request.getContextPath()%>/bsp/template/tomcat.gif">
Das kann natürlich recht aufwändig sein.
Welche Methode Sie verwenden, hängt vom Einzelfall ab und lässt sich nicht generell entscheiden. Seien Sie sich aber bewusst, dass beim Forward über den Request-Dispatcher schnell Probleme mit verlinkten Ressourcen auftreten können.