1 请求跳转及转发 1.1 举例 : 页面流转 可以在首页选择自己喜欢的颜色, 进入对应的页面 选择绿色, 会进入绿色界面 : 选择红色, 会进入红色界面 :
这里我们会看到四个页面 : 1. index.jsp 中选择颜色, 点击按钮后提交到 test.jsp 2. test.jsp 取得用户选择的颜色, 根据颜色值显示对应的页面 3. 如果选择了红色, 就显示 red.jsp 4. 如果选择了绿色, 就显示 green.jsp 在这里例子里,index.jsp,red.jsp,green.jsp 中的内容都是一样的, 处理逻 辑都在 test.jsp 中 现在面临的问题是如何在 test.jsp 决定实现 red.jsp 或者 green.jsp, 我们可 以在 forward 和 redirect 中任选其一 1.2 forward 方式 test.jsp 中需要这样写 : <%@ page contenttype="text/html; charset=utf-8"%> <% String color = request.getparameter("color"); if ("red".equals(color)) { request.getrequestdispatcher("red.jsp").forward(request,
response); } else if ("green".equals(color)) { request.getrequestdispatcher("green.jsp").forward(request, response); } %> 略过取得参数与比较参数值不提, 只关注 forward 的部分 : request.getrequestdispatcher("red.jsp").forward(request, response); 首先调用 request 的 getrequestdispatcher() 方法, 获得对应 red.jsp 的转 发器, 然后调用 forward() 方法执行请求转发 结果用户看到的就是 red.jsp 中 的结果了, 一个红色的页面 这里请大家注意一下浏览器的 url 地址 : 选择红色页面时 :
选择绿色页面时 :
于是, 无论转发至 red.jsp 还是 green.jsp, 地址栏上显示的都是 test.jsp 这是为什么呢? 通过下面的流程图会让我们容易理解 : 1. 浏览器向 test.jsp 发送请求 2. test.jsp 计算客户选择的颜色, 将请求转发至 red.jsp 3. red.jsp 返回响应给浏览器
这下知道为什么浏览器的地址没有变化了吧? 因为浏览器只是执行了对 test.jsp 的请求,test.jsp 到 red.jsp 的部分是在服务器内执行的, 浏览器并不知道服务器里到底发生了什么, 它只知道自己获得的响应是 test.jsp 发回来的, 甚至不知道服务器还有个 red.jsp 这就是请求转发 forward 了 1.3 redirect 方式 test.jsp 中需要这样写 : <%@ page contenttype="text/html; charset=utf-8"%> <% String color = request.getparameter("color"); if ("red".equals(color)) { response.sendredirect("red.jsp"); } else if ("green".equals(color)) { response.sendredirect("green.jsp"); } %> 略过取得参数与比较参数值不提, 只关注 redirect 的部分 : response.sendredirect("red.jsp"); response 翻译过来就是响应, 代表着 http 响应 调用 response 的 sendredirect("red.jsp") 方法, 将页面重定向到 red.jsp
再请大家注意一下浏览器的 url 地址 : 选择红色页面时 : 选择绿色页面时 :
与 forward 不同,url 地址一直在变化, 红色的时候显示 red.jsp, 绿色的时 候显示 green.jsp 再看一下流程图 : 1. 浏览器向 test.jsp 发送请求 2. test.jsp 计算客户选择的颜色, 向浏览器发送一个页面重定向 (redirect) 的响应, 响应中包含 red.jsp 的 url 地址
3. 浏览器根据页面重定向 (redirect) 响应中的 red.jsp 地址, 再次向服务 器发送请求, 这次请求的就是 red.jsp 了 4. red.jsp 执行, 返回响应
redirect 会触发另一个请求响应流程, 第二次请求的时候是由浏览器发起对 red.jsp 的请求, 所以 url 地址改变了 1.4 forward 和 redirect 的区别 3.4.1. 绝对路径与相对路径 1. 如果咱们使用的 URL 网址是以 / 开头的, 那么这个网址就叫做绝对 路径 2. 如果咱们使用的 URL 网址不是 / 开头的, 那么这个网址就叫做相对 路径 3.4.1.1. 相对路径 在相对路径上, 两者的表现是相同的 看如下例子 1. forward 的例子 :
<%request.getrequestdispatcher("result/result.jsp").forward(req uest, response);%> 这里的相对路径就是 result/result.jsp
因为刚刚请求的 test.jsp 是在 /test/ 下, 所以我们的当前路径就是 /test/, 执行 forward 的时候会寻找当前路径下的 result/result.jsp, 找到之后便转发请求 如果 :/test/ test.jsp 发送 forward 请求到 result/result.jsp 那么寻找的是 :/test/result/result.jsp 2. redirect 的例子 : <%response.sendredirect("result/result.jsp");%> 这里的相对路径也是 result/result.jsp 因为刚刚请求的 test.jsp 是在 /test/ 下, 所以我们的当前路径就是 /test/, 执行 redirect 的时候会把当前路径加上 result/result.jsp, 把结果作为重定向的地址发送给浏览器, 浏览器再去请求 /test/result/result.jsp, 从而得到响应 如果 :/test/ test.jsp 发送 sendredirect 请求到 result/result.jsp 那么寻找的是 :/test/result/result.jsp 3.4.1.2. 绝对路径 问题出现了, 绝对路径在 forward 和 redirect 中出现了差别, 还是刚才的情况, 但使用绝对路径的时候写法便不同了 1. forward 的例子 : <%request.getrequestdispatcher("/test/result/result.jsp"). forward(request, response);%>
这里的绝对路径就是 /test/result/result.jsp 在本地测试时,forward 把 http://localhost:8080/jsp3/ 当作根路径, 在它的基础上计算绝对路径 这是由 jsp 的部署方式决定的,webapp 里可以放好多项目, 为了让这些项目可以互不影响 独立运行, 不能让请求从一个项目直接在服务器内部转移到另一个项目 为了防止出现这种情况, 在执行 forward 的时候干脆把项目的路径当作根目录, 开发者看不到其他项目, 也就不会出现问题了 forward 在绝对路径时, 会从根目录计算路径, 去寻找, 如请求 : /test/result/result.jsp, 会找到 http://localhost:8080/jsp3/ test/result/result.jsp 2. redirect 的例子 : <%response.sendredirect("/test/result/result.jsp");%> 这里的绝对路径却是 http:localhost:8080//test/result/result.jsp
因为 redirect 会让浏览器重新发起一个新请求, 所以不会搅乱服务器里多个项目之间的关系, 也就不需要对它做限制, 如果需要在多个项目之间进行跳转, 就只能使用 redirect 不过因为重新发起了新的请求, 上次请求的那些数据都会丢失, 如果有什么重要的数据, 记得要重新设置 3.4.2. 注意 forward 导致找不到图片等资源 找不到图片, 找不到 js 脚本, 找不到 css 样式表, 都属于这个问题 这个问题, 是非常容易出现的, 只需要满足两个条件 : 1. forward 前后的 jsp 页面不在一个目录下 2. forward 后的 jsp 页面里使用相对路径引用一些资源, 图片,js 脚本,css 样式表什么的 ***