ZetCode

Java RequestDispatcher

最后修改于 2024 年 1 月 27 日

Java RequestDispatcher 教程展示了如何使用 Java RequestDispatcher 将请求调度到资源。

RequestDispatcher

RequestDispatcher 接收来自客户端的请求,并将它们发送到服务器上的资源(例如 servlet、HTML 文件、JSP 文件、FreeMarker 或 Thymeleaf 模板)。

RequestDispatcher 方法

RequestDispatcher 有两个方法

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

获取 RequestDispatcher

可以从请求对象或 servlet 上下文获取 RequestDispatcher

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

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

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

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

Java RequestDispatcher 转发到 JSP

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

index.html
<!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
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
<%@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
<!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
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

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

我们将一个属性设置为请求;它是当前的时间瞬间。

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

该请求(包括新属性)被发送到 AnotherServlet

AnotherServlet.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 将 instant 对象格式化为简短的英语日期时间格式,并将其打印到输出流中。

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

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

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

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

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

该瞬间被格式化并打印到输出中。

Java RequestDispatcher include

下一个示例将来自另一个 servlet 的输出包含到调用 servlet 中。

index.html
<!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
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
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 ReguestDispatcher

在本文中,我们介绍了 Java RequestDispatcher。 我们介绍了 RequestDispatcherforwardinclude 方法。

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直撰写编程文章。 迄今为止,我已经撰写了 1,400 多篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有Java教程