request.getRequestDispatcher().forward() 、<jsp:forward>、response.sendRedirect()三者的区别
📅 2026/7/14 7:05:44
👁️ 阅读次数
📝 编程学习
三种跳转方式终极对比
- request.getRequestDispatcher().forward()——Servlet 里用的转发
- jsp:forward——JSP 里用的转发
- response.sendRedirect()——重定向
一、一句话总结
- 1 和 2 功能完全一样,都是服务器转发
- 3 完全不同,是浏览器重定向
二、最清晰表格(背会这个就够了)
| 特性 | request.getRequestDispatcher.forward | jsp:forward | response.sendRedirect |
|---|---|---|---|
| 属于什么 | Java 代码(Servlet) | JSP 标签 | Java 代码(Servlet) |
| 跳转方式 | 服务器内部转发 | 服务器内部转发 | 浏览器重定向 |
| 地址栏 URL | 不变 | 不变 | 会变 |
| 请求次数 | 1 次 | 1 次 | 2 次 |
| 能否传递 request 数据 | ✅能 | ✅能 | ❌不能 |
| 能否跳外部网站 | 不能 | 不能 | 能 |
| 效率 | 高 | 高 | 低 |
| 你项目用哪个 | ✅ 必须用这个 | 几乎不用 | 增删改才用 |
三、超级大白话解释
1. 转发(前两个)= 你找我办事,我帮你找同事完成
- 只找一次
- 我把你的东西(request数据)直接带给同事
- 地址栏不变
2. 重定向(第三个)= 我不帮你,我让你自己再去找别人
- 你找我 → 我让你再去一次
- 你的东西带不过去
- 地址栏变了
四、你必须记住的使用规则
✅ 查询数据 → 展示页面
必须用:request.getRequestDispatcher.forward
因为要带数据过去!
✅ 增加、删除、修改完成后
用:response.sendRedirect
防止重复提交
❌ jsp:forward 基本不用
企业开发几乎不用,只在纯 JSP 页面跳转偶尔用
五、项目里的正确写法
查询图书 → 跳 JSP(必须转发)
request.setAttribute("bookList",list);request.getRequestDispatcher("bookList.jsp").forward(request,response);删除图书 → 重新查询(重定向)
response.sendRedirect("book");六、终极记忆口诀
要带数据用转发,地址不变最省心;
不带数据重定向,增删改完用它行。
七、什么情况用重定向 sendRedirect
底层原因:防止表单重复提交
举你图书系统的场景:
- 浏览器发起POST请求,执行新增/修改/删除图书;
- 如果你用 forward 转发到列表页:
浏览器地址栏依旧是/book(提交接口地址);
用户刷新页面,浏览器会再次发送上一次POST请求,重复新增/重复删除,产生脏数据。 - 如果你用 sendRedirect 重定向:
服务器返回302状态码,让浏览器重新发一次GET请求访问图书列表;
地址栏变成/book(查询接口),刷新只会查询,不会重复执行修改操作。
对比示例(删除图书场景)
错误写法(forward,会重复提交)
// 删除逻辑完成bookDao.delete(id);// 转发,地址不变,刷新会再次删书request.getRequestDispatcher("book").forward(request,response);正确写法(sendRedirect,杜绝重复提交)
bookDao.delete(id);// 重定向到查询接口,全新GET请求response.sendRedirect("book");1. 必须重定向 sendRedirect 的场景
- POST 增、删、改(新增图书、编辑图书、删除图书)执行完毕;
- 需要跳转到项目外部网址(如百度、第三方登录页);
- 希望用户地址栏URL同步更新,方便复制分享链接;
- 登录成功后跳转首页、退出登录跳转登录页。
2. 绝对不能用重定向,必须 forward 转发的场景
- 查询数据(查图书列表、图书详情),需要把
request域数据传给JSP展示;
重定向是两次独立请求,第一次存的setAttribute数据会直接丢失,页面拿不到列表。 - 内部页面携带临时查询参数、校验提示信息展示。
场景1:查询图书(转发forward)
@OverrideprotectedvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{List<Book>bookList=bookDao.selectAll();// 把图书列表存入request域request.setAttribute("bookList",bookList);// 转发到展示页面,携带数据request.getRequestDispatcher("bookList.jsp").forward(request,response);}场景2:删除图书(重定向sendRedirect)
@OverrideprotectedvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{Stringid=request.getParameter("id");bookDao.deleteById(Integer.parseInt(id));// 删除完成,重定向回到查询页面,刷新无副作用response.sendRedirect("book");}- 重定向路径注意:
sendRedirect("book"):相对路径,匹配你web.xml里/book的servlet映射;- 写
/book代表从项目根路径访问,两种写法在你这个项目都可用;
- forward 和 sendRedirect 不能连续调用:
执行forward后响应已经提交,再调用sendRedirect会抛异常;反之同理,二选一。 - 提示信息怎么带过重定向?
重定向丢失request数据,短期提示可以用session存提示文字,页面读取后立即删除session数据。
编程学习
技术分享
实战经验