重定向与转发本质都是跳转到新的URL
重定向与转发的本质区别在于:转发是一个服务端的行为,而重定向是一个浏览器的行为。
下面是图解:
转发
转发的作用在服务器端,将请求发送给服务器上的其他资源,以共同完成一次请求的处理。
使用forward跳转时,是在服务器内部跳转,地址栏不发生变化,属于同一次请求。
使用方式
在要跳转的地方使用getRequestDispatcher方法指定要跳转的位置。
req.getRequestDispatcher("/url-pattern").forward(req,resp);
数据传递
forward表示一次请求,是在服务器内部跳转,可以共享同一次request作用域中的数据
request作用域:拥有存储数据的空间,作用范围是一次请求有效(一次请求可以经过多次转发)。可以将数据存入request后,在一次请求过程中的任何位置进行获取
可传递任何数据(基本数据类型、对象、数组、集合等)存数据:request.setAttribute(key,value);
以键值对形式存储在request作用域中。key为string类型,value为object类型取数据:requestgetAttribute(key);
通过string类型的key访问object类型的value
例子:
建立两个Servlet,AServlet
、BServlet
,在AServlet
添加一个数据,跳转到BServlet
,再将数据取出。
package com.zjw;
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("/a")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet doGet...");
//向request中存入数据
req.setAttribute("name","张三");
//请求转发 跳转到AServlet
req.getRequestDispatcher("/b").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet doPost...");
doPost(req,resp);
}
}
package com.zjw;
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("/b")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doGet...");
//从request域中取数据
String name = (String) req.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doPost...");
doPost(req,resp);
}
}
通过浏览器访问AServlet
,观察浏览器的地址没有发生变化
http://localhost:8080/servlet_war_exploded/a
控制台输出
AServlet doGet...
BServlet doGet...
张三
重定向
重定向作用在客户端,客户端将请求发送给服务器后,服务器响应给客户端一个新的请求地址,客户端重新发送新请求。
使用方式
在调用业务逻辑的Servlet中,编写以下代码
response.sendRedirect("目标URI");
- URl:统一资源标识符(Uniform Resource ldentifier),用来表示服务器中定位一个资源,资源在web项目中的路径(/project/source)
例子:
建立两个Servlet,AServlet
、BServlet
,在AServlet
添加一个数据,跳转到BServlet
,再将数据取出。
package com.zjw;
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("/a")
public class AServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet doGet...");
//向request中存入数据
req.setAttribute("name","张三");
//重定向
resp.sendRedirect(req.getContextPath()+"/b");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("AServlet doPost...");
doPost(req,resp);
}
}
package com.zjw;
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("/b")
public class BServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doGet...");
//从request域中取数据
String name = (String) req.getAttribute("name");
System.out.println(name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("BServlet doPost...");
doPost(req,resp);
}
}
通过浏览器访问AServlet
,观察浏览器的地址发生变化
//访问
http://localhost:8080/servlet_war_exploded/a
//改变
http://localhost:8080/servlet_war_exploded/b
控制台输出,发现无法取得request域中的值。
AServlet doGet...
BServlet doGet...
null