请求转发和重定向

请求转发

  请求转发,是一种服务器行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的URL地址不会改变,得到响应后,服务器端再将响应发送给客户端,这个过程只有一次请求发出。

实现方法如下,达到多个资源一起响应的效果。

1
java复制代码request.getRequestDispatcher(url).forward(request,response)
  • 特点:
  1. 服务器只能在当前内部资源进行跳转
  2. 浏览器地址栏不变
  3. 转发只有一次请求
  4. request数据可以共享

接下来通过代码解释下这几个特点。

这是requestDemo2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
java复制代码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("/requestDemo2")
public class requestDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("requestDemo2-->"+username);
request.getRequestDispatcher("/requestDemo3").forward(request,response);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}

这是requestDemo3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java复制代码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("/requestDemo3")
public class requestDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("这是requestDemo3的页面");
String username = request.getParameter("username");
System.out.println("requestDemo3-->"+username);
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}

QQ截图20210920123031.png

  向requestDemo2传入username=zhangsan的参数,接下再看这张图片。
QQ截图20210920123041.png
  Server打印这两条结果,我们发现通过访问requestDemo2的同时也访问到了requestDemo3页面,只是浏览器的地址栏没有改变。

  还有通过浏览器的抓包可以发现,在这次转发的过程中至始至终只有一次请求,服务器只发起了一次请求,但是结果是两个资源都被访问了,所以说转发只有一次请求。

  如果将getRequestDispatcher(url)替换成百度的网址,页面发生跳转就会发生404页面不存在错误,因为百度的网址不是服务器内部的资源。

request作用域

通过request对象可以在一次请求中传递数据,经过请求转发,request域中的数据依然存在,可以通过request传输和共享数据。

1
2
3
4
5
6
java复制代码// 设置域对象内容
request.setAttribute(String name, String value)
// 获取域对象内容
request.getAttribute(String name)
// 删除域对象内容
request.removeAttribute(String name)

重定向

重定向是服务器指导客户端的行为,客户端发出第一个请求,被服务器接收处理后,服务器会作出响应,在响应的同时,服务器会给客户端一个新的资源地址(就是下次请求的地址),当客户端拿到接受到响应后,会马上根据新地址发起第二个请求,服务器接收请求并作出响应,重定向完成。

1
2
3
4
5
6
7
java复制代码/*第一种方法*/
// 设置状态码302
response.setStatus(302);
// 设置响应头location
response.setHeader("location",url);
/*第二种方法*/
response.sendRedirect(url)

废话不多说上代码

这是requestDemo2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
java复制代码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("/requestDemo2")
public class requestDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("requestDemo2-->"+username);
response.sendRedirect("/requestDemo3");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}

这是requestDemo3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java复制代码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("/requestDemo3")
public class requestDemo3 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("requestDemo3-->"+username);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("demo3....");
}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}

QQ截图20210920155821.png

向requestDemo2传入username=zhangsan的参数,接下再看这张图片。
QQ截图20210920155749.png

  通过浏览器的抓包,可以得出重定向的过程有两次请求,并且requestDemo2的状态码为302,location为/requestDemo3,浏览器的地址栏发生改变。
QQ截图20210920155857.png

  Server的打印结果可以看出,requestDemo3打印zhangsan而requestDemo2却没有,所以重定向不能用request共享数据,因为这是两次请求。重定向还可以访问其他服务器的资源。

总结

请求转发与重定向的比较

请求转发forward 重定向redirect
一次请求 两次请求
数据在request域中共享 request域中数据不共享
浏览器地址栏不改变 浏览器地址栏改变
只能访问当前服务器下的资源 可以访问其他服务器的资源
服务器行为 客户端行为

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%