为何使用RequestDispatcher转发至JSP需setAttribute,转发至Servlet无需?
request.setAttribute(),转发到Servlet却不需要? 嘿,这个问题问得很到位,其实核心在于JSP和Servlet的职责不同,以及RequestDispatcher转发的本质,我来给你慢慢说清楚:
先搞懂RequestDispatcher转发的本质
当你调用forward(request, response)时,服务器是在内部把同一个HttpServletRequest对象传递给目标组件(不管是JSP还是另一个Servlet)。也就是说,原来请求里的所有参数、属性,在整个转发流程里都是共享的,不会丢失。
为什么转发到JSP需要用request.setAttribute()?
JSP的核心职责是渲染视图、展示数据,它属于MVC模式里的「视图层」。通常我们会用EL表达式(比如${uname})或者JSTL来在JSP页面上展示数据,而这些表达式默认是从request域对象(也就是通过setAttribute存的数据)里取值的。
举个例子,你的welcome.jsp里如果要显示用户名,大概率会写:
<h1>Welcome ${uname}!</h1>
这里的${uname}就是从request域里找名为uname的属性,所以你需要在转发前用request.setAttribute("uname", name)把用户名存进去,JSP才能拿到并展示。
当然,你也可以不用setAttribute,直接在JSP里写${param.uname}来获取请求参数,但这种做法不符合MVC的分层思想——控制层(Servlet)应该把处理好的数据传递给视图层(JSP),而不是让视图层直接去拿原始请求参数,这样代码更清晰、更易维护。
为什么转发到Servlet不需要request.setAttribute()?
另一个Servlet属于「控制层」,它的职责是处理请求、业务逻辑。它本身就可以直接通过request.getParameter("uname")来获取原始请求参数,因为转发时request对象是同一个,里面的参数还在。
比如你的welcome Servlet里可以直接写:
String uname = request.getParameter("uname"); response.getWriter().write("Welcome " + uname + "!");
这样就能直接拿到用户名并输出,完全不需要额外用setAttribute存一遍。
总结一下
- 转发到JSP:需要
setAttribute是因为JSP作为视图层,依赖request域对象来获取要展示的数据(符合分层规范) - 转发到Servlet:不需要
setAttribute是因为Servlet可以直接从同一个request对象里获取原始请求参数
内容的提问来源于stack exchange,提问作者Dil.

