1. 重定向原理解析
1.1 基本概念
- 首先客户浏览器发送http请求,
- 当web服务器接受后发送302状态码响应及对应新的location给客
户浏览器, - 客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location
地址,服务器根据此请求寻找资源并发送给客户。
1.2 流程图
- 通过浏览器向 Tomact 服务器发送请求
register-servlet
- Tomact 服务器接收到请求后向浏览器发送一个302状态码以及新的 location
- 浏览器接收到302状态码以后重新向Tomact服务器发送地址为新的location的请求 此时浏览器地址会改变
- Tomact服务器处理该请求
1.3 代码示例
-
注册页面
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>注册页面</title> </head> <body> <form action="register-servlet" method="post"> 姓名 : <input type="text" name="name" /> <br/> 年龄 : <input type="text" name="name" /> <br/> 技能 : <input type="checkbox" name="skills" value="Java"/> Java <input type="checkbox" name="skills" value="C++" /> C++ <input type="checkbox" name="skills" value="Python" /> Python <input type="checkbox" name="skills" value="Scala" /> Scala <br /> <br /> <input type="submit" value="注册"/> </form> </body> </html>
-
处理注册请求的Servlet
package cn.knightzz.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; @WebServlet(name = "RegisterServlet", urlPatterns = "/register-servlet") public class RegisterServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("success.html"); } }
-
success.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>成功页面</title> </head> <body> <h2>注册成功</h2> </body> </html>
1.4 重定向的特点
- 重定向之后,浏览器地址栏的URL会发生改变。
- 重定向过程中会将前面Request对象销毁,然后创建一个新的Request对象。
- 重定向的URL可以是其它项目工程。比如可以是
https://www.baidu.com/
2. 转发的概念和原理
2.1 转发器的概念
- 一个Web组件(Servlet/JSP)将未完成的处理通过容器转交给另外一个Web组件继续处理,转发
的各个组件会共享Request和Response对象
2.2 转发器常用方法
-
获取/设置 request 属性
-
获取转发器对象
-
转发操作
### 2.3 转发的特点
- 转发之后浏览器地址栏的URL不会发生改变。
- 转发过程中共享Request对象。
- 转发的URL不可以是其它项目工程。比如 百度之类的
2.4 代码示例
-
ForwardServlet
package cn.knightzz.servlet; 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(name = "ForwardServlet", urlPatterns = "/forward-servlet") public class ForwardServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 在 request 中设置属性信息 req.setAttribute("name", "张三"); // 设置转发地址 RequestDispatcher dispatcher = req.getRequestDispatcher("/target-servlet"); dispatcher.forward(req, resp); } }
-
TargetServlet
package cn.knightzz.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; /** * @author 王天赐 * @title: TargetServlet * @projectName spring-aop-01 * @description: * @website http://knightzz.cn/ * @github https://github.com/knightzz1998 * @date 2022/1/6 16:09 */ @WebServlet(name = "TargetServlet", urlPatterns = "/target-servlet") public class TargetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 获取 request 的属性 String name = (String) req.getAttribute("name"); System.out.println("获取来自 ForwardServlet的 name 属性 : " + name); // 重定向到 success.html resp.sendRedirect("success.html"); } }