原文:http://zetcode.com/java/requestdispatcher/

Java RequestDispatcher教程显示了如何使用 Java RequestDispatcher将请求分派到资源。

RequestDispatcher

RequestDispatcher从客户端接收请求,并将其发送到服务器上的资源(例如 Servlet,HTML 文件,JSP 文件,FreeMarker 或 Thymeleaf 模板)。

RequestDispatcher方法

RequestDispatcher有两种方法:

  • forward() - 将请求从 Servlet 转发到另一个资源
  • include() - 在响应中包含资源的内容

两种方法之间的区别在于,forward()方法将在调用后关闭输出流,而include()方法将打开输出流。 include()方法从另一个资源获取内容,并将其包含在 Servlet 中。 forward()方法将请求发送到另一个资源。

获取RequestDispatcher

RequestDispatcher可以从请求对象或 servlet 上下文中获得。

  1. RequestDispatcher dispatcher = request.getRequestDispatcher("greet.jsp");
  2. dispatcher.forward(request, response);

我们可以使用getRequestDispatcher()方法从请求对象中获取RequestDispatcher

  1. RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/greet.jsp");
  2. dispatcher.forward(request, response);

在这里,我们从 servlet 上下文中获取RequestDispatcher。 在这种情况下,路径必须以斜杠字符开头。

Java RequestDispatcher转发到 JSP

以下示例将来自客户端的请求发送到 JSP 页面。

index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Start Page</title>
  5. <meta charset="UTF-8">
  6. </head>
  7. <body>
  8. <form action="MyServlet">
  9. <label>Enter your name:
  10. <input type="text" name="name">
  11. </label>
  12. <button type="submit">Submit</button>
  13. </form>
  14. </body>
  15. </html>

在主页中,我们有一个简单的形式:它从用户那里获取一个值,并将其作为请求参数发送到MyServlet

MyServlet.java

  1. package com.zetcode.web;
  2. import java.io.IOException;
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. @WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
  9. public class MyServlet extends HttpServlet {
  10. @Override
  11. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  12. throws ServletException, IOException {
  13. response.setContentType("text/html;charset=UTF-8");
  14. request.getRequestDispatcher("greet.jsp").forward(request, response);
  15. }
  16. }

MyServlet中,我们使用RequestDispatcher转发到greet.jsp页面。

greet.jsp

  1. <%@page contentType="text/html" pageEncoding="UTF-8"%>
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta charset="UTF-8">
  6. <title>JSP Page</title>
  7. </head>
  8. <body>
  9. <p>Hello ${param.name}!</p>
  10. </body>
  11. </html>

greet.jsp页面中,我们显示name参数,该参数由用户在表单中设置。

Java RequestDispatcher转发到 Servlet

以下示例将来自客户端的请求发送到 Servlet,该 Servlet 将处理转发到另一个 Servlet。

index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Start Page</title>
  5. <meta charset="UTF-8">
  6. </head>
  7. <body>
  8. <p>
  9. <a href="MyServlet">Call servlet</a>
  10. </p>
  11. </body>
  12. </html>

主页包含一个调用MyServlet的链接。

MyServlet.java

  1. package com.zetcode.web;
  2. import java.io.IOException;
  3. import java.time.Instant;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. @WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
  10. public class MyServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  13. throws ServletException, IOException {
  14. response.setContentType("text/html;charset=UTF-8");
  15. request.setAttribute("now", Instant.now());
  16. request.getRequestDispatcher("AnotherServlet").forward(request, response);
  17. }
  18. }

该请求首先到达MyServlet

  1. request.setAttribute("now", Instant.now());

我们为请求设置一个属性; 这是当前时间。

  1. request.getRequestDispatcher("AnotherServlet").forward(request, response);

包括新属性的请求被发送到AnotherServlet

AnotherServlet.java

  1. package com.zetcode.web;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import java.time.Instant;
  5. import java.time.ZoneId;
  6. import java.time.format.DateTimeFormatter;
  7. import java.time.format.FormatStyle;
  8. import java.util.Locale;
  9. import javax.servlet.ServletException;
  10. import javax.servlet.annotation.WebServlet;
  11. import javax.servlet.http.HttpServlet;
  12. import javax.servlet.http.HttpServletRequest;
  13. import javax.servlet.http.HttpServletResponse;
  14. @WebServlet(name = "AnotherServlet", urlPatterns = {"/AnotherServlet"})
  15. public class AnotherServlet extends HttpServlet {
  16. @Override
  17. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  18. throws ServletException, IOException {
  19. response.setContentType("text/plain;charset=UTF-8");
  20. PrintWriter out = response.getWriter();
  21. DateTimeFormatter formatter
  22. = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
  23. .withLocale(Locale.ENGLISH)
  24. .withZone(ZoneId.of("UTC"));
  25. Instant now = (Instant) request.getAttribute("now");
  26. String output = formatter.format(now);
  27. out.println(output);
  28. }
  29. }

AnotherServlet将即时对象格式化为简短的英语日期时间格式,并将其打印到输出流中。

  1. DateTimeFormatter formatter
  2. = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
  3. .withLocale(Locale.ENGLISH)
  4. .withZone(ZoneId.of("UTC"));

我们使用DateTimeFormatter类格式化日期时间。

  1. Instant now = (Instant) request.getAttribute("now");

我们使用getAttribute()方法从请求中检索属性。

  1. String output = formatter.format(now);
  2. out.println(output);

即时被格式化并打印到输出中。

Java RequestDispatcher包括

下一个示例包括从另一个 servlet 到调用 servlet 的输出。

index.html

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>Start Page</title>
  5. <meta charset="UTF-8">
  6. </head>
  7. <body>
  8. <p>
  9. <a href="MyServlet">Call servlet</a>
  10. </p>
  11. </body>
  12. </html>

主页包含一个调用MyServlet的链接。

MyServlet.java

  1. package com.zetcode.web;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. @WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
  10. public class MyServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  13. throws ServletException, IOException {
  14. response.setContentType("text/plain;charset=UTF-8");
  15. PrintWriter out = response.getWriter();
  16. out.println("Hello from MyServlet");
  17. request.getRequestDispatcher("AnotherServlet").include(request, response);
  18. }
  19. }

MyServlet将数据打印到输出流并转发到AnotherServlet

AnotherServlet.java

  1. package com.zetcode.web;
  2. import java.io.IOException;
  3. import java.io.PrintWriter;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. @WebServlet(name = "AnotherServlet", urlPatterns = {"/AnotherServlet"})
  10. public class AnotherServlet extends HttpServlet {
  11. @Override
  12. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  13. throws ServletException, IOException {
  14. response.setContentType("text/plain;charset=UTF-8");
  15. PrintWriter out = response.getWriter();
  16. out.println("Hello from AnotherServlet");
  17. }
  18. }

AnotherServlet还将数据打印到输出流。 最后,我们将两条消息都写入输出流并发送给客户端。

在本教程中,我们介绍了 Java RequestDispatcher。 我们已经介绍了RequestDispatcherforwardinclude()方法。 您可能还需要查看相关的教程: Java servlet JSON 教程从 Java servletJava servlet 复选框教程提供纯文本 Java Servlet 图像教程Java Servlet HTTP 标头Java 教程