Servlet – forward() 和 sendRedirect() 方法示例
正如我们在前面的主题中所了解的,Servlet 是在服务器端运行并生成对客户端请求的动态响应的Java程序。 Servlet的执行包括以下步骤:
- 客户端通过浏览器将请求发送到 Web 服务器/应用服务器。
- 服务器将客户端请求传递给相应的 servlet。
- Servlet 处理请求生成响应并将响应发送回服务器。
- 服务器将生成的响应传递给浏览器/客户端。
现在,让我们考虑我们需要从另一个 servlet 调用一个 servlet,从而绕过使用请求和响应对象的信息。我们可以通过 2 种方式实现这一点,servlet 提供
- RequestDispatcher(I) 中的 forward() 方法。
- HttpServletResponse(I) 中的 sendRedirect() 方法
RequestDispatcher 接口
Servlet 在javax.servlet 包中提供 RequestDispatcher。它定义了一个对象,用于将客户端请求从一个 servlet 分派到同一服务器上的另一个 servlet。基本上,这可用于接收客户端请求对象并将该对象发送到任何其他资源,例如 Servlet、JSP、HTML 文件等。我们可以使用以下语法获取 RequestDispatcher 对象:
Java
RequestDispatcher r = req.getRequestDispatcher(String arg);
Java
// r - requestDispatcher object
r.forward(req, resp);
Java
resp.sendRedirect(java.lang.String location)
HTML
Home Page
Enter two numbers to find their Sum and Average
Java
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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("/add")
public class AddNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the x, y parameters from the request
// object and save in num1, num2 variables.
int num1 = Integer.parseInt(req.getParameter("x"));
int num2 = Integer.parseInt(req.getParameter("y"));
// Perform addition operation on num1, num2
// and save the result in add variable.
int add = num1 + num2;
// Set the add value in 'sum'
// attribute of request object
req.setAttribute("sum", add);
// Get the Request Dispatcher object and pass
// the argument to which servlet we need to call - AvgNum.java
RequestDispatcher reqd = req.getRequestDispatcher("avg");
// Forward the Request Dispatcher object.
reqd.forward(req, resp);
}
}
Java
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("/avg")
public class AvgNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the 'sum' attribute value from the request
int sum = (int) req.getAttribute("sum");
// perform the average operation and
// save the result in 'avg' variable.
float avg = (float) (sum / 2.0);
// Get the PrintWriter object to write
// the output in the response to the browser.
PrintWriter out = resp.getWriter();
out.println("Sum is: " + sum);
out.println("Average is: " + avg);
}
}
HTML
Java
@WebServlet("/add")
Java
// Get the Request Dispatcher object and pass the argument
// to which servlet we need to call - AvgNum.java
RequestDispatcher reqd = req.getRequestDispatcher("avg");
// Forward the Request Dispatcher object.
reqd.forward(req, resp);
Java
@WebServlet("/avg")
Java
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("/add")
public class AddNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the x, y parameters from the request
// object and save in num1, num2 variables.
int num1 = Integer.parseInt(req.getParameter("x"));
int num2 = Integer.parseInt(req.getParameter("y"));
// Perform addition operation on num1,
// num2 and save the result in add variable.
int add = num1 + num2;
// Redirect the response to the
// other servlet - AvgNum.java
resp.sendRedirect("avg?sum="+add);
}
}
Java
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("/avg")
public class AvgNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the 'sum' parameter from the request
int sum = Integer.parseInt(req.getParameter("sum"));
// perform the average operation and
// save the result in 'avg' variable.
float avg = (float) (sum / 2.0);
// Get the PrintWriter object to write the
// output in the response to the browser.
PrintWriter out = resp.getWriter();
out.println("Sum is: " + sum);
out.println("Average is: " + avg);
}
}
forward() 方法
此方法将来自 servlet 的请求转发到同一服务器上的另一个 servlet。它允许一个 servlet 对请求进行初始处理,获取 RequestDispatcher 对象,并将请求转发给另一个 servlet 以生成响应。
forward() 的语法:
Java
// r - requestDispatcher object
r.forward(req, resp);
当我们使用 forward() 方法转发客户端请求时,客户端/浏览器甚至不知道请求正在转发到另一个 servlet 文件或 JSP 文件,也不知道将从哪个文件响应生成。浏览器中的 URL 不会发生变化。
sendRedirect() 方法
它使用方法中给出的指定重定向位置 URL 向客户端发送临时重定向响应并清除缓冲区。让我们考虑一个场景,我们需要将请求从 servlet 重定向到另一个服务器中的其他 servlet,在这种情况下,我们可以使用 sendRedirect() 方法,以便客户端/浏览器知道请求的去向和获取处理。
使用 sendRedirect() 的语法:
Java
resp.sendRedirect(java.lang.String location)
让我们举个例子来更多地了解这两种方法。
例子:
考虑一个简单的例子——从客户端获取两个整数值并生成这两个数字的总和和平均值。为了演示 forward() 和 sendRedirect() 方法的使用,我们将在一个 servlet 中执行加法操作,然后将该请求对象分派给另一个 servlet 以执行平均操作。
程序 1:使用 forward() 方法
脚步:
- 创建一个简单的 HTML 页面以从浏览器中获取值。
- 创建第一个 servlet 以获取请求并执行添加操作。
- 创建第二个 servlet 以执行平均操作并发送响应。
第 1 步:创建一个简单的 HTML 页面以从浏览器中获取值
主页.html
HTML
Home Page
Enter two numbers to find their Sum and Average
使用输入标签从客户端获取值,例如 x、y。我们有一个表单标签,它会在提交页面时根据动作属性“add”和 servlet 中的“doGet”方法映射 servlet。
第 2 步:创建第一个 servlet 以获取请求并执行附加操作
加号。Java
Java
import java.io.IOException;
import javax.servlet.RequestDispatcher;
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("/add")
public class AddNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the x, y parameters from the request
// object and save in num1, num2 variables.
int num1 = Integer.parseInt(req.getParameter("x"));
int num2 = Integer.parseInt(req.getParameter("y"));
// Perform addition operation on num1, num2
// and save the result in add variable.
int add = num1 + num2;
// Set the add value in 'sum'
// attribute of request object
req.setAttribute("sum", add);
// Get the Request Dispatcher object and pass
// the argument to which servlet we need to call - AvgNum.java
RequestDispatcher reqd = req.getRequestDispatcher("avg");
// Forward the Request Dispatcher object.
reqd.forward(req, resp);
}
}
- 在这个 servlet 中,我们从请求对象中获取输入值并执行加法操作。
- 现在,要调用另一个 servlet 来执行平均操作,我们需要将“add”值传递给该 servlet。
- 因此,通过使用 setAttribute,我们需要将 'sum' 属性设置为 'add' 值。
- 最后,获取 Request Dispatcher 对象并传递参数并转发该对象。在这个例子中,我们提到了 AddNum。 Java作为'/add'和AvgNum。 Java作为'/avg'。
第 3 步:创建第二个 servlet 以执行平均操作并发送响应。
平均数。Java
Java
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("/avg")
public class AvgNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the 'sum' attribute value from the request
int sum = (int) req.getAttribute("sum");
// perform the average operation and
// save the result in 'avg' variable.
float avg = (float) (sum / 2.0);
// Get the PrintWriter object to write
// the output in the response to the browser.
PrintWriter out = resp.getWriter();
out.println("Sum is: " + sum);
out.println("Average is: " + avg);
}
}
- 在第二个 servlet 中,获取我们在第一个 servlet 中设置的请求对象“sum”。
- 执行平均操作,并通过使用 PrintWriter 对象,在响应中将结果输出到客户端。
执行:
- 使用 Eclipse 中的“运行方式 -> 在服务器上运行”运行 Home.html 页面。
- 在浏览器中运行网址:http://localhost:8081/ServletCall/Home.html,得到首页。
- 输入值并单击提交。
- 提交页面后,请求将转到 AddNum 中的“doGet”方法。 Java servlet,正如我们提到的
HTML
- 在 AddNum 中。 Java servlet,我们指定了 servlet
Java
@WebServlet("/add")
- 因此,Home.html 页面映射到 AddNum。 Java servlet 并发送请求。
- 在 AddNum 中。 Java,它对给定的 2 个值执行加法操作,并在请求中设置加法值,以使用 RequestDispatcher 发送到另一个 servlet。
Java
// Get the Request Dispatcher object and pass the argument
// to which servlet we need to call - AvgNum.java
RequestDispatcher reqd = req.getRequestDispatcher("avg");
// Forward the Request Dispatcher object.
reqd.forward(req, resp);
- 在这里,我们将参数作为“avg”传递,因此它映射到 AvgNum。我们指定的Java servlet
Java
@WebServlet("/avg")
- 在平均数中。 Java,我们将获得“总和”值并执行平均操作。
- 因此,输出将如下所示,
- 如果您在浏览器中观察 URL,它只会显示“/add”servlet。所以在服务器端完成的转发请求不会影响客户端。
程序 2:使用 sendRedirect() 方法
现在,我们将在同一个示例中使用 sendRedirect() 方法而不是 forward()。
- 无需更改 Home.html 页面上的任何内容。
- 在第一个 servlet 中,使用 sendRedirect() 方法代替 forward() 方法。
- 在第二个 servlet 中,从请求中获取属性。
加号。Java
Java
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("/add")
public class AddNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the x, y parameters from the request
// object and save in num1, num2 variables.
int num1 = Integer.parseInt(req.getParameter("x"));
int num2 = Integer.parseInt(req.getParameter("y"));
// Perform addition operation on num1,
// num2 and save the result in add variable.
int add = num1 + num2;
// Redirect the response to the
// other servlet - AvgNum.java
resp.sendRedirect("avg?sum="+add);
}
}
- 在这里,我们使用 sendRedirect() 绕过“add”值将响应发送到另一个 servlet。
平均数。Java
Java
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("/avg")
public class AvgNum extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Get the 'sum' parameter from the request
int sum = Integer.parseInt(req.getParameter("sum"));
// perform the average operation and
// save the result in 'avg' variable.
float avg = (float) (sum / 2.0);
// Get the PrintWriter object to write the
// output in the response to the browser.
PrintWriter out = resp.getWriter();
out.println("Sum is: " + sum);
out.println("Average is: " + avg);
}
}
- 在这里,我们从请求中获取“sum”值作为参数。
执行:
- 同上,运行程序“在服务器上运行”。
- 在浏览器中运行 URL http://localhost:8081/ServletCall/Home.html。
- 输入值并单击提交。
- 现在,如果您观察 URL,我们可以看到请求被重定向到另一个带有 sum 值的 servlet。
- 请求的重定向在浏览器端可见。
结论
与两个输出相比,
我们可以看到在使用 forward() 方法时只有一个请求和响应对象。在内部,forward() 方法会将相同的请求从一个 servlet 传递到另一个 servlet,而浏览器端并不知道。但是在使用 sendRedirect() 方法时,有两个请求和响应,第一个 servlet 接收来自浏览器的请求并将该请求重定向到另一个 servlet,因此在第二个 servlet 中将形成另一个请求和响应,该响应将是给浏览器。