request.getRequestDispatcher().forward() 、<jsp:forward>、response.sendRedirect()三者的区别

📅 2026/7/14 7:05:44 👁️ 阅读次数 📝 编程学习
request.getRequestDispatcher().forward() 、<jsp:forward>、response.sendRedirect()三者的区别

三种跳转方式终极对比

  1. request.getRequestDispatcher().forward()——Servlet 里用的转发
  2. jsp:forward——JSP 里用的转发
  3. response.sendRedirect()——重定向

一、一句话总结

  • 1 和 2 功能完全一样,都是服务器转发
  • 3 完全不同,是浏览器重定向

二、最清晰表格(背会这个就够了)

特性request.getRequestDispatcher.forwardjsp:forwardresponse.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

底层原因:防止表单重复提交

举你图书系统的场景:

  1. 浏览器发起POST请求,执行新增/修改/删除图书;
  2. 如果你用 forward 转发到列表页:
    浏览器地址栏依旧是/book(提交接口地址);
    用户刷新页面,浏览器会再次发送上一次POST请求,重复新增/重复删除,产生脏数据。
  3. 如果你用 sendRedirect 重定向:
    服务器返回302状态码,让浏览器重新发一次GET请求访问图书列表;
    地址栏变成/book(查询接口),刷新只会查询,不会重复执行修改操作。

对比示例(删除图书场景)

错误写法(forward,会重复提交)

// 删除逻辑完成bookDao.delete(id);// 转发,地址不变,刷新会再次删书request.getRequestDispatcher("book").forward(request,response);

正确写法(sendRedirect,杜绝重复提交)

bookDao.delete(id);// 重定向到查询接口,全新GET请求response.sendRedirect("book");

1. 必须重定向 sendRedirect 的场景

  1. POST 增、删、改(新增图书、编辑图书、删除图书)执行完毕;
  2. 需要跳转到项目外部网址(如百度、第三方登录页);
  3. 希望用户地址栏URL同步更新,方便复制分享链接;
  4. 登录成功后跳转首页、退出登录跳转登录页。

2. 绝对不能用重定向,必须 forward 转发的场景

  1. 查询数据(查图书列表、图书详情),需要把request域数据传给JSP展示;
    重定向是两次独立请求,第一次存的setAttribute数据会直接丢失,页面拿不到列表。
  2. 内部页面携带临时查询参数、校验提示信息展示。

场景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");}
  1. 重定向路径注意:
    • sendRedirect("book"):相对路径,匹配你web.xml里/book的servlet映射;
    • /book代表从项目根路径访问,两种写法在你这个项目都可用;
  2. forward 和 sendRedirect 不能连续调用:
    执行forward后响应已经提交,再调用sendRedirect会抛异常;反之同理,二选一。
  3. 提示信息怎么带过重定向?
    重定向丢失request数据,短期提示可以用session存提示文字,页面读取后立即删除session数据。