jsp跳转到另一个jsp
写JSP页面最常干的一件事,就是点个按钮跳到另一个页面。但你要是真在项目里写过跳转,肯定遇到过这种尴尬:明明写了`response.sendRedirect("next.jsp")`,结果地址栏变了,request里的参数却全丢了。另一个同事用`request.getRequestDispatcher("next.jsp").forward()`,参数倒是还在,可URL纹丝不动。俩都能跳,差别咋这么大? 先说`forward`。这玩意儿是服务器内部动作,浏览器根本不知道你换了页面。你从`login.jsp`跳到`welcome.jsp`,地址栏还挂着`login.jsp`,但页面内容已经是welcome的了。好处是快,因为一次请求就完事,request对象里的attribute、参数全都能接着用。坏处也明显——用户刷新一下,表单可能又提交一遍,搞出重复数据。我见过一个老系统,登录后直接forward,用户手贱按F5,结果后台多了十几条重复订单。 再说`sendRedirect`。它是真让浏览器重新发一次请求,地址栏变成新URL,旧request里的东西全没了——想传数据只能拼URL或者塞session。慢,多一次网络往返。但有个场景非它不可:你处理完POST请求,想防止用户刷新重复提交,就得先redirect到一个GET页面。这叫Post/Redirect/Get模式,网上银行转账完跳转个“成功”页,全是这么干的。 那到底怎么选?我的经验是:如果只是页面内部流转,不涉及地址栏变化,而且你需要共享request数据,就用forward;如果跳转后用户得看到新URL,或者要防止重复提交,必须用sendRedirect。比如一个简单的查询列表,点“下一页”用forward没问题,因为数据都在request里;但你要是从购物车结算跳到支付页面,地址栏必须变,而且得清空之前的表单数据,那就得redirect。 还有个容易踩的坑:路径问题。`forward`里写相对路径,是相对于当前Servlet的映射路径;`sendRedirect`是相对于整个web应用的根目录。新手经常在子目录里写`sendRedirect("next.jsp")`,结果404,因为浏览器找的是`/子目录/next.jsp`,而实际是`/项目名/next.jsp`。所以redirect最好加`request.getContextPath()`前缀,比如`response.sendRedirect(request.getContextPath() + "/next.jsp")`。forward倒没这毛病,因为服务器内部解析,直接相对于webapp根。 最后说个反直觉的事:`forward`跳转后,JSP里用`response.getWriter()`写点东西,再forward,会报`IllegalStateException`——因为response已经提交了。同理,`sendRedirect`之前如果已经写了输出流,也会抛异常。我调试过一晚上,最后发现是前面有个`out.println()`没删干净。所以写跳转逻辑时,确保前面没有输出任何内容,别在JSP里既输出又跳转。 现在你再看项目里的跳转代码,是不是能一眼看出同事当初的选择是拍脑袋还是深思熟虑?下次写跳转前,先问自己:地址栏要不要变?request数据还要不要?刷新会不会出事?三个问题想清楚,代码自然就写对了。jsp跳转到另一个jsp,别被“转发”和“重定向”绕晕了
- 随机阅读
- 搜索
-
- 友情链接
-