$KK(Request Dispatcher) $R(Objective) Describe the RequestDispatcher mechanism; write servlet code to create a request dispatcher; write servlet code to forward or include the target resource; and identify and describe the additional request-scoped attributes provided by the container to the target resource. $R\ $KKK(Erklärung Request Dispatcher) Die Aufgabe eines Request Dispatchers ist es eine Anfrage an eine andere Ressource (z.B ein Servlet, eine Html Seite oder JSP Datei) weiterzuleiten. Der Servlet Container Ein RequestDispatcher wird durch eine der folgenden Methoden erzeugt * aServletContext.getRequestDispatcher(String path) * aServletContext.getRequestDispatcher(String name) * aServletRequest.getRequestDispatcher(String path) Die erste Methode aServletContext.getRequestDispatcher(String path) erwartet einen Pfad der mit einem Slash '/' beginnt. Der Pfad ist relativ zum Wurzelverzeichnis des ServletContext. Der Container versucht dann mit den servlet-mapping Regeln die Ressource zu finden. Es wird einen RequestDispatcher der das Zielobjekt umwrappt zurückgegeben, oder falls das Ziel Objekt nicht gefunden wird der null Wert zurückgegeben. Mit der zweiten Methode aServletContext.getRequestDispatcher(String name) ist es möglich direkt auf eine Ressource zuzugreifen, wenn der Name dem ServletContainer bekannt ist. Auch hier wird ein RequestDispatcher oder der null Wert zurückgegeben. Mit der dritten Methode aServletRequest.getRequestDispatcher(String path) kann man einen Pfad relative zu der aktuellen Servlet angeben. $KKK(Include und Forward) Das folgende Code-Fragment zeigt die Benutzung eines Request Dispatchers mit der forward Methode $S() public class Dispatcher extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) { RequestDispatcher dispatcher = request.getRequestDispatcher(/template.jsp"); if (dispatcher != null) dispatcher.include(request, response); } } $S\ Die forward Methode leitet die Anfrage an die template.jsp weiter. Mit der forward Methode ist es nicht möglich die Ausgabe der Qúellressource und der Ziel-Ressource zu mischen. Wurde schon vor der forward Anweisung etwas in den response Puffer geschrieben, geht dies verloren.Wurde der Puffer schon committed (ein flush() auf den entsprechenden OutputStream) erzeugt die forward Methode ein IllegalStateException. Dasselbe Code-Fragment mit der include Methode: $S() public class Dispatcher extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) { RequestDispatcher dispatcher = request.getRequestDispatcher(/template.jsp"); if (dispatcher != null) dispatcher.include(request, response); } } $S\ Mit der Include Methode ist es durchaus möglich, die Ausgabe der Quell- und Zielressource zu mischen. Beispiel: $S() public class Dispatcher extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) { res.getContentType("text/html"); PrintWriter out = res.getWriter(); out.println("...."); RequestDispatcher dispatcher = request.getRequestDispatcher(/template.jsp"); if (dispatcher != null) dispatcher.include(request, response); out.println(".."); } } $S\ Die Include Methode hat gegenüber der forward Methode einige Einschränkungen. Die Ziel Ressource kann nicht den Header von response verändern auch kann der Status Code von response nicht verändert werden. $KKK(Zusätzliche Attribute) Die Include Methode richtet automatisch in dem HttpServlet Objekt Attribute ein, die für den Fall dass das eingebundene Servlet oder die JSP-Seite diese Daten benötigen, den ursprünglichen Anfragepfad beschreiben. Diese Attribute, auf die die eingebundene Ressource durch Aufrufen von getAttribute auf dem HttpServletRequest zugreifen kann, sind nachfolgend aufgeführt. Diese Attribute müssen aber nicht gesetzt werden, falls der Include mit der getNamedDispatcher Methode ausgeführt wurde * javax.servlet.include.request_uri * javax.servlet.include.context_path * javax.servlet.include.servlet_path * javax.servlet.include.path_info * javax.servlet.include.query_string Dasselbe gilt auch für die forward Methode. Auch hier wird der Pfad der original Anfrage als Attribut automatisch eingebunden. * javax.servlet.forward.request_uri * javax.servlet.forward.context_path * javax.servlet.forward.servlet_path * javax.servlet.forward.path_info * javax.servlet.forward.query_string