📜  Servlet – forward() 和 sendRedirect() 方法示例

📅  最后修改于: 2022-05-13 01:55:48.085000             🧑  作者: Mango

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

       
                 First Number:         
                 Second Number:         
                
  


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

                         First Number:         
                 Second Number:         
                   

使用输入标签从客户端获取值,例如 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,得到首页。

主页.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,我们将获得“总和”值并执行平均操作。
  • 因此,输出将如下所示,

结果 - forward()

  • 如果您在浏览器中观察 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 中将形成另一个请求和响应,该响应将是给浏览器。