请求转发
概念
请求转发(Request Forwarding)是指将一个HTTP请求从一个Servlet转发到另一个Servlet或JSP页面进行处理的操作。请求转发可以实现不同Servlet之间的数据共享和协作,以及将请求的处理过程划分为多个模块。
请求转发的作用
1. 模块化和代码复用:可以将请求处理过程划分为多个模块,每个模块负责不同的功能,提高代码的可维护性和复用性。
2. 数据共享:转发请求时,可以将数据通过请求对象(HttpServletRequest)的属性、请求参数等方式传递给目标Servlet或JSP页面,实现数据的共享。
3. 隐藏URL和保持请求状态:请求转发是在服务器内部进行的,对客户端是透明的,因此可以隐藏目标资源的URL,同时保持请求状态,比如保持用户的登录状态。
在请求转发过程中,设置域数据(Attribute)的作用是将数据存储在请求对象中,以便在转发的目标Servlet或JSP页面中获取和使用这些数据。通过设置域数据,可以实现不同Servlet之间的数据传递和共享。
获取域数据的作用是在目标Servlet或JSP页面中使用转发前的请求对象中存储的数据。通过获取域数据,可以在目标资源中访问和处理之前设置的数据,实现数据的共享和使用。
将请求对象和响应对象传递给`requestDispatcher.forward(req, resp)`方法是为了在请求转发过程中,目标Servlet或JSP页面能够访问和使用请求对象和响应对象,以便处理请求和生成响应。通过传递这两个对象,目标资源可以获取和操作请求参数、请求属性、响应头等信息,以及向客户端发送响应数据。
使用HttpServletRequest对象进行请求转发
注意:请求转发必须要以斜杠打头,/ 斜杠表示地址为:http://ip:port/工程名/ , 映射到IDEA 代码的web 目录
请求转发不能站外跳转,只能当前的项目下的资源内进行跳转【请求转发】,可以转发域数据和属性值,也就是说所有数据都可以在转发后的地址获取到,转发时地址栏网站不发生改变。
package com.sun.bean;
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;
import java.io.IOException;
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
System.out.println("在servlet1中查看参数" + username);
req.setAttribute("key1","柜台1的章");
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/servlet2");
requestDispatcher.forward(req,resp);
}
}
package com.sun.bean;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/servlet2")
public class Servlet2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
Object username = req.getParameter("username");
System.out.println("servlet2里面查看参数" + username);
Object key1 = req.getAttribute("key1");
System.out.println("查看是否有servlet1的章" + key1);
System.out.println("处理自己的业务");
}
}
重定向
使用 HttpServletResponse对象进行重定向跳转
重定向跳转,也具备跳转能力,但是属性值和域数据获取不到,但它可以跳转到站外地址,转发时地址栏网站发生变化。无须使用 /,因为/会被解析成http://localhost:8088:
跳转到站外资源
采取的是绝对路径的重定向方式
//跳转到站外资源
resp.sendRedirect("http://www.baidu.com");
跳转到站内资源
采用的是相对定位的方式,在当前工程路径下寻找
package com.sun.bean;
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;
import java.io.IOException;
@WebServlet("/servlet1")
public class Servlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
System.out.println("在servlet1中查看参数" + username);
req.setAttribute("key1","柜台1的章");
resp.sendRedirect("servlet2");
}
}
请求转发和重定向的区别
请求重定向(resp)是客户端行为,web资源收到客户端请求后,通知浏览器去访问另外一个web资源(让客户端请求另外一个url)。不可以携带参数。地址栏会发生变化。
转发请求(req)是服务器行为,web资源收到客户端请求好,通知浏览器去调用另外一个web资源(服务器自己转发到另一个url)。可以携带参数(通过forward方法将req,resp转发至另一个url)。地址栏不会发生变化。
重定向可以解决表单重复提交的问题,而请求转发不可以的原因在于它们的处理方式不同。
重定向是指服务器在接收到客户端的请求后,返回一个重定向的响应,告诉客户端需要重新发送一个新的请求到指定的URL。这样,即使客户端重新加载页面或者刷新页面,也不会重新提交表单。
而请求转发是指服务器在接收到客户端的请求后,直接将请求转发给另一个资源进行处理。这种方式下,客户端提交表单后,服务器会直接将请求转发给另一个资源进行处理,如果客户端重新加载页面或者刷新页面,会导致表单的重复提交。
因此,重定向可以有效地避免表单的重复提交问题,而请求转发则无法做到这一点。