Servlet笔记系列(4):Servlet跳转(forward、Redirect )
发表于 2014-12-04 | 分类于 Servlet | 阅读次数: 11
转发 Forward
Api 详解
- 转发
Forward
是通过RequestDispatcher
对象的 forward()方法实现。RequestDispatcher 可以通过以下两种方式获取:
-
- HttpServletRequest 的
getRequestDispatcher()
方法获得
- HttpServletRequest 的
-
- ServletContext 的
getRequestDispatcher()
方法获取
- ServletContext 的
1 2 | RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/downloadServlet"); RequestDispatcher dispatcher = req.getRequestDispatcher("/downloadServlet"); |
-
getRequestDispatcher()
方法的参数必须为以/
开始,/
表示本 Web 应用程序的根路径。如果要跳转到Servlet为 http://IP:PORT/servlet/RequestServlet。则参数应该为/servlet/RequestServlet
。 -
跳转在服务器,地址栏不变。当使用 Forward 形式跳转 Servlet 时,地址栏会显示跳转前的 Servlet 访问地址。因为该跳转是在服务器端实现,客户端浏览器并不知道该跳转动作,也就是说 Forward 跳转对客户端浏览器是透明的
-
Forward是最常用的方式。在struts等框架中,都是用Servlet来处理用户请求,把结果通过 request.setAttribute() 放到 request 中,然后 Forward 到JSP显示
-
当执行 Forward 动作的时候不能有任何输出到达客户端,否则会抛出
illegalStateException
。
1 | java.lang.IllegalStateException: Cannot forward after response has been committed |
-
转发:同一个HttpServletRequest, 这时web 数据的共享要使用 Request 域即可
-
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class ForwardServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { PrintWriter writer = resp.getWriter(); writer.write("在 Forward 之前不能向客户端输出结果"); writer.flush(); // 跳转到文件下载的 Servlet // RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/downloadServlet") RequestDispatcher dispatcher = req.getRequestDispatcher("/downloadServlet"); dispatcher.forward(req, resp); } } |
重定向 Redirect
原理
-
重定向是利用服务器返回的状态来实现的。客户端浏览器请求服务器的时候,服务器端会返回一个状态码。服务器端通过 HttpServletResponse 的 setStatus()方式设置状态码。如果服务器返回301 或者 302,则浏览器会到新的网址重新请求该资源。状态码的意思如下
—|—
100 ~ 199 | 表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程
200 ~ 299 | 表示成功接收请求,已经完成整个过程。如200
300 ~ 399 | 为完成请求,客户端需要进一步细化请求。例如,请求的资源已经移动到一个新的地址。常用 301、302、307、304
400 ~ 499 | 客户端的请求有错误。常用404
500 ~ 599 | 服务器端出现错误。常用500 -
301 、302都表示重定向,区别是 301是永久性重定向,302是临时性重定向。下面的代码将访问该Servlet的请求重定向到另一个网址
1 2 | response.setStates(301);//设置状态码为301 response.setHeader("Location","http://www.baidu.com") //新网址 |
实现
-
HttpServletResponse 类中把重用的状态码封装成了静态常量。并且把setStates() 与 setHeader() 方法封装成另一个方法 sendRedirect(String location),只需要调用 sendRedirect() 方法就能实现重定向
-
与转发不同,重定向(Redirect)的跳转是在客户端实现的。实际上客户端浏览器请求了 2 次服务器,第1 次获取重定向的状态码与重定向的网址,第 2 次访问真实地址
-
重定向:是不同的 HttpServletRequest 对象,每一次访问都会new 一个 HttpServletRequest 对象。这时web数据的共享要使用 session 域 和 context 域
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class RedirectServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 重定向到文件下载页面 resp.setStatus(301); resp.setStatus(HttpServletResponse.SC_MOVED_PERMANENTLY); resp.setHeader("Location", "/requestServlet"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.sendRedirect("/requestServlet"); } } |
自动刷新(Refresh)
- 自动刷新不仅可以实现一段时间之后自动跳转到另一个页面,还可以实现一段时间之后刷新本页面。Servlet中通过设置HttpServletResponse 对象的Header属性实现自动刷新效果
- 其中 1000 为时间,单位为毫秒
- URL参数指定的网址就是1 秒之后跳转的页面。当URL设置的路径为Servlet自己的路径时,就会每隔1秒钟自动访问页面一次
1 | response.setHeader("Refresh","1000; url=http://www.baidu.com") |
- 自动刷新与重定向原理是差不多。如果时间设为 0,把URL设为另一个网址,效果就是重定向
1 | response.setHeader("Refresh","0; url=http://www.baidu.com") // 重定向 |