Servlet跳转页面的重定向和转发
重定向
1.原理
简单解释过程:
如图,浏览器A发送请求服务器B,B不能完全完成A想要的任务,所以B返回告诉A,让A去找服务器C完成接下来的任务,此时浏览器A重新发送新的请求给C,直到完成任务,这是一种直白的重定向解释。
实际整个重定向过程:
客户浏览器发送http请求—-》web服务器接受后发送302状态码响应及对应新的location给客户浏览器–》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址—-》服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。
2.特点
(1) 重定向是客户端行为。(浏览器重新请求)
(2)重定向是浏览器做了至少两次的访问请求的(当然也可以重定向多次)。
(3)定向浏览器地址改变。
(4)重定向两次跳转之间传输的信息会丢失(request范围)。
(5)重定向可以指向任何的资源,包括当前应用程序中的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源(如自己工程重定向到百度)。注意:传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录。
3.代码实现
下面是具体实现代码:
package com.qjl.web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 重定向 * @author Joe * */ @WebServlet("/login") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; public LoginServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("text/html;charset=utf-8"); String username = request.getParameter("username"); String password = request.getParameter("pwd"); System.out.println(username + "..." + password); //重定向 // request.getContextPath();//获取上下文路径(/项目名称) //告诉浏览器重定向到index.html response.sendRedirect(request.getContextPath()+"/index.html"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
大家可以看到response.sendRedirect()这个方法可以重定向到index.html页面,这里是respone(重点哦),响应给浏览器的,当然这里写的是根路径也就是/项目名/index.html,这里说一下WebContent目录下的资源是可以直接访问的。
1 request.setCharacterEncoding("utf-8"); 2 response.setCharacterEncoding("text/html;charset=utf-8");
这两行代码第一行:设置请求进来的数据成utf-8,第二行:设置服务器响应给浏览器的数据,让浏览器报头设置成utf-8。这样就不会中文乱码了。
4.实际过程测试(IE浏览器)
主要servlet代码如上,页面就不给代码了。
从login.html页面输入username和password参数,点击提交,数据提交到servlet中,页面会重定向到index.html页面,通过开发者工具可以看到如下过程:
图里有几点需要注意:
(1)请求login.html后,状态码是302,302代表服务器告诉浏览器需要重新请求其他页面,所以浏览器得到302码以及login.html告诉浏览器重定向的位置信息,重定向到index.html页面了,状态码200,整个过程完成。
(2)请求login.html时上图圈出部分,是带参数的,但是在重定向到index.html时就不会带参数了如下图:
这就是整个的重定向过程。
转发
原理
简单解释:
浏览器A请求服务器B,B无法完成A所有的请求任务,所以直接将请求发送给服务器C了,这里不再经过A了,B发送给C的同时带着A给B的数据。
实际整个转发过程:
客户浏览器发送http请求—-》web服务器接受此请求–》调用内部的一个方法在容器内部完成请求处理和转发动作—-》将目标资源发送给客户。在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。
2.特点
1,转发是服务器行为(这是不经过浏览器的)
2,转发是浏览器只做了一次访问请求
3,转发浏览器地址不变
4,转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递
5,转发只能将请求转发给同一个WEB应用中的组件
注意:如果创建RequestDispatcher 对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。(只能是本工程下的,因为是服务器行为)
3.代码实现
具体实现代码如下:
package com.qjl.web.servlet; import java.io.IOException; import java.util.List; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 转发 */ @WebServlet("/reg") public class RegServlet extends HttpServlet { private static final long serialVersionUID = 1L; public RegServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("text/html;charset=utf-8"); String username = request.getParameter("username"); String password = request.getParameter("pwd"); System.out.println(username + "..." + password); // //1转发到login.html // //1.1获取转发器 // RequestDispatcher dispatcher = request.getRequestDispatcher("/login.html"); // //1.2转发 // dispatcher.forward(request, response); request.getRequestDispatcher("/index2.html").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
大家可以看到通过request.getRequestDispatcher(“index2.html”)方法再.forward(request,respone)将浏览器请求信息直接转发给index2.html页面,这就是转发过程,注意这里是request,服务器直接请求了另一个服务器也就是login直接请求了index2并且通过forward传递给index2浏览器请求时的数据。
4.实际过程测试(IE浏览器)
主要servlet代码如上,页面就不给代码了。
从reg.html页面输入username和password参数,点击提交,数据提交到servlet中,页面会重定向到index2.html页面,通过开发者工具可以看到如下过程:
图里有几点需要注意:
(1)这次转发过程浏览器只请求了一次,也就是对于reg.html页面的请求,服务器在内部直接请求了index2.html而不经过浏览器了。
(2)在reg.html直接转发到index2.html过程中,通过forward方法直接将浏览器请求的数据转发给index2了(封装在了request中)。
这就是整个转发过程。