本文最后更新于:May 13, 2023 pm
Servlet中的页面跳转可以通过转发或者重定向来实现。转发是指一个请求处理器(ServletA)将请求交给另一个处理器处理(ServletB),再将结果返回。重定向是请求处理器接收到请求时,不处理请求而是告诉用户浏览器应该发送另外的请求,然后用户浏览器再跳转到被告知的请求。
目录
1.转发(request)
转发的作用在服务器端,将请求发送给服务器上的其他资源,已达到共同完成一次请求的处理。
1.1 页面跳转
request.getRequestDispatcher(“/目标URL-pattern”).forward(request,response);
使用forward跳转时,是在服务器内部跳转,地址栏不发生变化,这一点与重定向不同。并且是属于同一次请求。即不管跳转几下,都是属于同一次请求。如图。
示例:
A.java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.tothefor.Servlet;
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; import java.util.ArrayList; import java.util.List;
@WebServlet(value = "/a") public class A extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.getRequestDispatcher("/b").forward(req,resp); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
|
B.java 代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.tothefor.Servlet;
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; import java.io.PrintWriter;
@WebServlet(value = "/b") public class B extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("B页面"); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
|
最后在控制台上可以看见打印的结果。并且可以发现,在地址栏中访问A
,跳转后并没有变成 B
。
1.2 数据传递
因为forward
表示一次请求,是在服务器内部跳转,所以可以共享同一次 request
作用域中的数据。
- request作用域:拥有存储数据的空间,作用范围是一次请求有效(一次请求可以经过多次转发)。可以将数据存入
request
中,并且可以在一次请求过程中的任何位置进行获取。而且可以传递任何数据类型(基本数据类型、对象、数组、集合等)。
1.2.1 存数据
request.setAttribute(key,value);
以键值对形式存储在 request 作用域中。其中key为String类型,value为Object类型。key任意取。
1.2.2 取数据
request.getAttribute(key);
通过String类型的key访问Object类型的value,需要进行类型强转。
示例:
A.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package com.tothefor.Servlet;
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; import java.util.ArrayList; import java.util.List;
@WebServlet(value = "/a") public class A extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { List<String> list = new ArrayList<>(); list.add("qwer"); list.add("asdf"); list.add("zxcv"); req.setAttribute("lists",list); req.getRequestDispatcher("/b").forward(req,resp); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
|
B.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.tothefor.Servlet;
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; import java.io.PrintWriter; import java.util.List;
@WebServlet(value = "/b") public class B extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("B页面"); List<String> list = (List<String>) req.getAttribute("lists"); for(String it : list){ System.out.println(it); } }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
|
1.3 转发的特点
- 转发是服务器行为。
- 转发是浏览器只做了一次访问请求。
- 转发浏览器地址不变。
- 转发的两次跳转之间传输的信息不会丢失。
- 转发只能将请求转发给同一个Web应用中的组件。即在同一个Web项目下使用。
2.重定向(response)
重定向作用在客户端,客户端将请求发送给服务器后,服务器相应给客户端一个新的请求地址,客户端再重新发生新请求。这样一来,地址栏的地址就会发生变化,这一点与转发不同。
2.1 页面跳转
response.sendRedirect(“URL”); 这里的URL需要和转发中的区别开。这里的URL需要指明的哪个项目下的哪个资源。
URL:统一资源标识符,用来表示服务器中定位一个资源,资源在Web项目中的路径。
2.2 数据传递
sendRedirect 跳转时,地址栏发生变化,代表客户端重新发送的请求。属于两次请求。
- response 没有作用域,两次 request 请求中的数据无法共享。
- 传递数据:通过URL的拼接进行数据传递(如:”/Test1_war_exploded/b?username=loong”);
- 获取数据:request.getParameter(“username”); 这种方法只能获取String类型的数据。即,重定向只能传递String类型的数据,并且是明文传递的,因为是拼接在URL后面的。
示例:
A.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.tothefor.Servlet;
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; import java.util.ArrayList; import java.util.List;
@WebServlet(value = "/a") public class A extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("/Test1_war_exploded/b?username=loong"); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
|
B.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package com.tothefor.Servlet;
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; import java.io.PrintWriter; import java.util.List;
@WebServlet(value = "/b") public class B extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("B页面2"); String name = req.getParameter("username"); System.out.println(name); }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } }
|
2.3 重定向特点
- 重定向是客户端行为。
- 重定向是浏览器做了至少两次的访问请求。
- 重定向的浏览器地址会改变。
- 重定向两次跳转之间传输的信息会丢失(request范围)。
- 重定向可以指向任何的资源,包括当前应用程序中的其他资源、同一个站点上的其他应用程序中的资源、其他站点资源。
3.总结
当两个Servlet需要传递数据时,选择forward转发。不建议使用sendRedirect进行传递。
但推荐使用转发,不使用重定向,即使是传递的数据是String类型的。因为重定向的数据传递方式是明文,不安全。