JSP转发本质上是Servlet容器内部完成的服务器端跳转,全程只产生一次浏览器请求,所有调度都发生在应用服务器(如Tomcat)的应用层里,而不是Web服务器层。
很多刚接触Java Web的开发者经常搞混“转发”和“重定向”,甚至以为JSP转发是由浏览器发起的第二次网络请求,这篇文章直接拆开讲清楚:JSP转发到底发生在哪一层,底层走了什么路径,以及在实际项目里怎么选。
jsp服务器端跳转和客户端跳转有什么区别
要回答“JSP转发是在什么服务器端”这个问题,先要分清两个基本阵营:服务器端跳转和客户端跳转,JSP转发属于前者,JSP重定向(sendRedirect)属于后者。
服务器端跳转:控制权移交在容器内部
服务器端跳转的典型写法是:
request.getRequestDispatcher("/success.jsp").forward(request, response);
这行代码会在Servlet容器内部直接查找目标资源,把当前请求对象和响应对象继续传递下去,整个过程只有一次网络请求,浏览器地址栏不会发生变化。
具体访问流程是这样的:
- 浏览器请求
/login.jsp,请求到达Tomcat容器 login.jsp执行完逻辑后,容器在内部把控制权转交给success.jspsuccess.jsp渲染结果后,由容器统一把响应返回给浏览器- 浏览器从头到尾只发出过 1次 HTTP请求
客户端跳转:浏览器重新发起第二次请求
客户端跳转的典型写法是:
response.sendRedirect("/success.jsp");
这一步发生的是:
- 容器返回一个 302状态码,告诉浏览器“资源已经临时移动到别处”
- 浏览器收到响应后,主动向新地址再发一次请求
- 地址栏会变成新地址
与JSP转发不同,重定向是“客户端行为”,服务器的任务只是告知新地址,后续的请求由浏览器独立完成。
JSP转发真正发生在哪个层级
JSP转发是在Servlet容器(应用服务器)内部完成的,这里有个容易混淆的概念:很多开发者默认“Tomcat就是Web服务器”,这种说法并不精确。
Tomcat的双重身份
Tomcat既承担Web服务器的职责(处理HTTP连接、静态资源),也承担Servlet容器的职责(管理Servlet生命周期、执行JSP),JSP转发的调度逻辑在

Servlet容器的Catalina引擎 中执行,也就是应用服务器层,而不是网络连接层。
RequestDispatcher的底层机制
JSP转发的工作核心是 RequestDispatcher 接口,Servlet容器在启动时,会根据映射信息维护一个资源路径表,调用 forward() 时,容器内部做的是:
- 根据路径找到目标Servlet或JSP
- 暂停当前资源输出,把缓冲区清空(未commit的前提下)
- 将同一个
HttpServletRequest和HttpServletResponse传入目标资源 - 目标资源执行完毕后,由容器统一提交响应
业内专家指出,这个机制最大的特点是全程保持同一个请求对象,在login.jsp中设置的request.setAttribute("user", user),在success.jsp里可以直接通过request.getAttribute("user")取到,不需要任何额外传递。
不落地到浏览器的内部路由
做一个直观的类比:JSP转发类似公司前台帮你把内线电话转给另一个部门,你始终在同一个通话中;重定向则是前台告诉你新号码,你挂断后重新拨号,前者电话“内部转接”,后者电话“重启呼叫”。
“jsp转发是在什么服务器端”的准确答案是:发生在Servlet容器内部,是服务器端的内部路由行为,不经过浏览器的网络层。
JSP转发能做什么,不能做什么
理解了位置,再看能力边界,JSP转发适合完成同一应用内部的页面流转,但它有几个天然限制。
只能转发到同一应用内的资源
request.getRequestDispatcher() 只能写应用内路径,不能跨应用转发,如果你的项目部署在 http://localhost:8080/usercenter,想转发到另一个项目 http://localhost:8080/order,做不到,这种跨应用需求只能交给重定向。
转发前不能提交响应
容器在执行转发时,要求当前响应缓冲区未被提交,如果前面的代码已经用response.getWriter().flush()推给了浏览器,再调用forward()就会抛出 IllegalStateException,具体表现为:
- JSP页面顶部已经输出大量HTML标签
- 转发代码写在页面中部
- 页面报错提示“Cannot forward after response has been committed”
实际操作里,如果要在JSP页面里做条件转发,建议把转发逻辑放在JSP最前面,或者直接写一个Servlet做控制器,由Servlet决定转发到哪一个视图。

转发不等于include
JSP转发和JSP include经常被放在一起比较,include是把另一个资源的内容嵌入当前页面,最终由当前页面统一输出;转发则是完全替换,当前资源不再负责最终响应,在JSP页面中,include可以用<jsp:include>标签或<%@ include %>指令实现,而forward只有<jsp:forward>标签或RequestDispatcher两种做法。
实际工程中如何决策:forward还是sendRedirect
既然“jsp forward和sendredirect哪个好”没有绝对答案,需要在具体场景里判断。
明显用forward的场景
| 场景 | 原因 |
|---|---|
login.jsp 提交表单,校验通过后跳到 index.jsp |
登录信息直接放在request里,转发不丢数据 |
| 防止用户刷新页面重复提交表单后,又要短暂显示一个成功页 | 转发是内部跳转,刷新时会重复提交,需要结合Post/Redirect/Get模式使用 |
| 同一个请求周期内的数据展示 | 目标页面能直接读取当前request中的属性 |
明显用sendRedirect的场景
| 场景 | 原因 |
|---|---|
| 用户登录成功后跳转到用户中心 | 地址栏必须变成用户中心地址,方便后续刷新和收藏 |
| 表单提交完成后的回跳 | 避免用户按F5刷新时重复提交,重定向之后相当于是一个全新的GET请求 |
| 跨应用或跨域跳转 | 转发根本做不到,只能重定向 |
操作上有一个判断口诀:地址栏必须变化就重定向,地址栏保持不变就转发。 还有一个更细的维度性能,转发只发生一次请求,理论上比重定向少一半网络往返,在内部页面流转时更轻量;但多出来的这半次HTTP请求在现代网络环境下成本极低,因此大多数场景可以不把性能差异作为主要考量因素。
怎么观察一次JSP转发确实发生在服务器端
想验证转发过程中“服务器端”做了什么,不需要特殊工具,打开浏览器开发者工具,切到Network面板,然后访问一个带有转发逻辑的页面。

具体操作步骤
- 启动一个Web项目,准备
test.jsp和target.jsp test.jsp里写一行:request.getRequestDispatcher("/target.jsp").forward(request, response);- 浏览器访问
test.jsp - 观察Network面板
你会看到是:
- 地址栏仍然停留在
test.jsp - 面板里只有一条
test.jsp的请求记录,状态码200 - 目标页面的内容完整显示
再换用response.sendRedirect("/target.jsp"),同样的步骤刷新,Network面板里会出现两条请求:第一条302,第二条200,地址栏自动跳到target.jsp,这个对比清晰展示了服务器端跳转和客户端跳转在网络链路上的差异。
JSP转发常见疑问解答
JSP forward和sendredirect哪个好的判断标准是什么?
判断标准是“目标地址是否需要变成浏览器地址栏的URL”,登录后进入用户主页、支付后回到订单列表这类地址必须变的,用sendRedirect;同一业务流程内的步骤跳转,如表单校验通过后进入下一个填写步骤,用forward,如果两者都可行,优先转发,因为少一次网络请求。
转发时为什么在目标页拿到的URL还是原来的?
因为forward()最终调用的目标资源写在服务器响应流里,浏览器根本不知道内部发生过跳转,请求的URL由浏览器发起时决定,转发没有改变浏览器与服务器之间的交互对象,所以request.getRequestURI()、地址栏等所有与浏览器地址相关的值都保持原样。
JSP转发在服务器端哪个容器组件发挥核心作用?
RequestDispatcher接口是转发的核心调度组件,Tomcat中由ApplicationDispatcher类具体实现,它通过解析传递给getRequestDispatcher()的路径字符串,在ServletContext映射表中找到对应目标,这个机制从Servlet 2.1规范开始就存在,多年来接口形态基本稳定,行业共识认为它是服务器端跳转能力的基准实现。
回到最初的问题:JSP转发是在什么服务器端发生的?答案落在Servlet容器内部,由RequestDispatcher驱动,与浏览器网络链路完全无关,掌握这一点,再看那些绕着地址栏和请求次数打转的“JavaWeb面试题jsp转发与重定向”,就一目了然了。
图片来源于AI模型,如侵权请联系管理员。作者:酷小编,如若转载,请注明出处:https://www.kufanyun.com/ask/827492.html


评论列表(2条)
读了这篇文章,我深有感触。作者对重定向的理解非常深刻,论述也很有逻辑性。内容既有理论深度,又有实践指导意义,确实是一篇值得细细品味的好文章。希望作者能继续创作更多优秀的作品!
这篇文章写得非常好,内容丰富,观点清晰,让我受益匪浅。特别是关于重定向的部分,分析得很到位,给了我很多新的启发和思考。感谢作者的精心创作和分享,期待看到更多这样高质量的内容!