# Java `RequestDispatcher`

原文：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 上下文中获得。

```java
RequestDispatcher dispatcher = request.getRequestDispatcher("greet.jsp");
dispatcher.forward(request, response);

```

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

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

```

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

## Java `RequestDispatcher`转发到 JSP

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

`index.html`

```java
<!DOCTYPE html>
<html>
    <head>
        <title>Start Page</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <form action="MyServlet">

            <label>Enter your name:
                <input type="text" name="name">
            </label>

            <button type="submit">Submit</button>

        </form>
    </body>
</html>

```

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

`MyServlet.java`

```java
package com.zetcode.web;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");

        request.getRequestDispatcher("greet.jsp").forward(request, response);
    }
}

```

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

`greet.jsp`

```java
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <p>Hello ${param.name}!</p>
    </body>
</html>

```

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

## Java `RequestDispatcher`转发到 Servlet

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

`index.html`

```java
<!DOCTYPE html>
<html>
    <head>
        <title>Start Page</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <p>
            <a href="MyServlet">Call servlet</a>
        </p>
    </body>
</html>

```

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

`MyServlet.java`

```java
package com.zetcode.web;

import java.io.IOException;
import java.time.Instant;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=UTF-8");

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

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

```

该请求首先到达`MyServlet`。

```java
request.setAttribute("now", Instant.now());

```

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

```java
request.getRequestDispatcher("AnotherServlet").forward(request, response);

```

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

`AnotherServlet.java`

```java
package com.zetcode.web;

import java.io.IOException;
import java.io.PrintWriter;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.util.Locale;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "AnotherServlet", urlPatterns = {"/AnotherServlet"})
public class AnotherServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/plain;charset=UTF-8");

        PrintWriter out = response.getWriter();

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

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

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

```

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

```java
DateTimeFormatter formatter
        = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.SHORT)
                .withLocale(Locale.ENGLISH)
                .withZone(ZoneId.of("UTC"));

```

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

```java
Instant now = (Instant) request.getAttribute("now");

```

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

```java
String output = formatter.format(now);
out.println(output);

```

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

## Java `RequestDispatcher`包括

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

`index.html`

```java
<!DOCTYPE html>
<html>
    <head>
        <title>Start Page</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <p>
            <a href="MyServlet">Call servlet</a>
        </p>
    </body>
</html>

```

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

`MyServlet.java`

```java
package com.zetcode.web;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "MyServlet", urlPatterns = {"/MyServlet"})
public class MyServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/plain;charset=UTF-8");

        PrintWriter out = response.getWriter();
        out.println("Hello from MyServlet");

        request.getRequestDispatcher("AnotherServlet").include(request, response);
    }
}

```

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

`AnotherServlet.java`

```java
package com.zetcode.web;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "AnotherServlet", urlPatterns = {"/AnotherServlet"})
public class AnotherServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/plain;charset=UTF-8");

        PrintWriter out = response.getWriter();

        out.println("Hello from AnotherServlet");
    }
}

```

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

在本教程中，我们介绍了 Java `RequestDispatcher`。 我们已经介绍了`RequestDispatcher`，`forward`和`include()`方法。 您可能还需要查看相关的教程： [Java servlet JSON 教程](/articles/javaservletjson/)，[从 Java servlet](/articles/javaservlettext/) ， [Java servlet 复选框教程](/articles/javaservletcheckbox/)，[提供纯文本 Java Servlet 图像教程](/articles/javaservletimage/)， [Java Servlet HTTP 标头](/articles/javaservlethttpheaders/)或 [Java 教程](/lang/java/)，