服务器的两大跳转方式
凯哥学堂(www.kaige123.com )
服务器的两大跳转方式:
1.1浏览器跳转(重定向跳转)
Servlet 中使用的最多的跳转就是浏览器跳转,也就是重定向跳转,而浏览器跳转也是最常用的跳转方法之一。
图1:浏览器跳转的基本流程示意图
浏览器跳转,在跳转的过程中会通知浏览器,也就是说,每一次发生跳转,浏览器都是可以知道的,并且浏览器上的URL 路径会随着页面的跳转而发生改变。我们从上节课的知识中知道了请求头和响应头的存在,浏览器会将请求的信息封装在请求头中,并发送给Servlet ,而响应头则会在第一时间将信息响应给浏览器,因为响应头中并不包含网页代码,它只包含了是否发生跳转、网页访问是否超时等诸如此类的信息,浏览器在解析了响应头中的信息后,如果发现需要进行跳转,那么浏览器就会再次访问跳转后的目标页面,然后再将新的页面信息呈现给用户。
浏览器跳转,会对Tomcat 服务器产生两次访问,因为浏览器除
,凯哥学堂(www.kaige123.com )
了访问最初的页面外还访问了跳转后的新的页面,所以同理,由于它对Tomcat 服务器发生了两次访问,所以它具有两副Request 和Response 对象(第一次访问Tomcat 服务器和第二次访问Tomcat 服务器都分别产生了一副Request 和Response 对象)。
1.2服务器转发(服务器内部跳转)
服务器转发和浏览器转发最大的不同就是,在服务器转发的过程中浏览器是全然不知的,也就是说,在使用服务器转发的方式进行跳转页面时,浏览器是根本不知道服务器发生了跳转的,所以这种跳转方式也叫做服务器内部跳转。
图2:服务器转发的基本流程示意图
而使用服务器转发,浏览器上的URL 路径也是不会发生改变的,就如,用户看到的URL 路径是对A 页面进行访问的路径,但实际上用户已经访问到了B 页面(这里可以是对静态页面进行访问,也可以是对Servlet 进行访问),只是浏览器并不知道在服务器内部发生了转发而已,在整个服务器转发的过程中只会产生一副Request 和Response 对象。
,凯哥学堂(www.kaige123.com )
1.3浏览器跳转和服务器转发的实际举例
1.3.1浏览器跳转:
我们书写一个简单的浏览器跳转:当我们访问ServletAAA 页面时,它会跳转到ServletBBB 页面上:
代码部分:
public class AAA extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletR esponse response)throws ServletException, IOException { //跳转到ServletBBB ,当然也可以跳转到Html 页面
response.sendRedirect("BBB" );
}
}
public class BBB extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResp onse response)throws ServletException, IOException {
//带值给浏览器,也就是将信息显示在浏览器而不是控制台上
PrintWriter out = response.getWriter();
out.println(" 我是ServletBBB~BBB~BBB~");
out.flush();
out.close();
}
}
代码执行结果:
,凯哥学堂(www.kaige123.com )
由图上,我们可以看到,我们明明输入的路径是
那么,我们怎么才能知道,浏览器跳转中使用的是两副Request 和Response 对象呢?我们可以分别将它们的Request 和Response 对象的内存地址打印出来,并让AAA 中的Request 对象带上一个值,看在BBB 中的Request 对象是否可以得到这个值(如果是同一个Request 对象就一定可以取到这个值):
代码部分:
public class AAA extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)throws ServletException,
IOException {
//为Request 对象设置一个键值对(存入值)
request.setAttribute("user" , "yezi" );
//跳转到ServletBBB ,当然也可以跳转到Html 页面
System. out .println("AAA_request:" request);
System. out .println("AAA_response" response);
response.sendRedirect("BBB" );
}
}
,凯哥学堂(www.kaige123.com )
public class BBB extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResp onse response)throws ServletException, IOException {
System. out .println("BBB_request:" request);
System. out .println("BBB_response" response);
System. out .println("Request_Value:" request.getAttribute ("user" ));
PrintWriter out = response.getWriter();
out.println("ServletBBB~BBB~BBB~");
out.flush();
out.close();
}
}
代码执行结果:
由图我们可以看到,虽然AAA 和BBB 的Request 和Response 对象的内存地址看起来好像是相同的,但是最重要的值却没有被取出来,图上显示为null ,这就说明了它们并不是同一个Request 对象。
1.3.1服务器转发:
接下来我们书写一个服务器转发,同样使用Request 对象带值的方式来检测转发前后的Request 对象是否为同一个Request 对象: 代码部分:
public class extends HttpServlet {
,凯哥学堂(www.kaige123.com )
public void doGet(HttpServletRequest request, HttpServletR esponse response)throws ServletException, IOException { // 为Request 对象设置一个键值对(存入值)
request.setAttribute("user" , "yezi" );
// 获得一个转发对象(目标页面BBB)
RequestDispatcher re_D = request.getRequestDispatcher ("BBB" );
// 开始服务器转发(并将Request 对象和Response 对象一齐传递 下去)
re_D.forward(request, response);
}
}
public class extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletR esponse response)throws ServletException, IOException {
System. out .println("Request_Value:" request.getAttribute ("u ser" ));
PrintWriter out = response.getWriter();
out.println("ServletBBB~BBB~BBB~");
out.flush();
out.close();
}
}
代码执行结果:
浏览器结果:
,凯哥学堂(www.kaige123.com )
从上述两个结果我们可以看到,使用Request 带值的方法可以看出服务器转发中的Request 对象是同一个对象,并且使用服务器转发的方式时,URL 路径不会发生改变,虽然我们访问到的是BBB 页面,但是URL 路径依然显示为AAA 页面的地址。
PS :以下四个方法十分重要,如我我们想使用到这几个方法,就需要使用服务器转发的方式,因为只有服务器转发的方式才可以将值带给下一个页面,只有服务器转发方式产生的Request 对象和Response 对象才会一直传递下去,数据才不会丢失:
request.setAttribute(" 键" , " 值" );
request.getAttribute(" 键" );
request.removeAttribute(" 键" );
//得到所有键值对的键的名称
request.getAttributeNames();
这几个方法在重定向跳转中是没有用的,因为它每一次的Request 对象和Response 对象都是新的。
1.4使用两种转发方式的具体情况
通过实验,我们可以看到,在浏览器跳转中我们使用到了两副Request
,凯哥学堂(www.kaige123.com )
和Response 对象,它的这两个对象,在完成一来一回的数据传递后生命周期就会结束,所以,如果我们想利用Request 和Response 对象为我们携带数据到下一个页面,是不可能的;而服务器转发全程只是用到了一副Request 和Response 对象,所以我们完全可以使用它为我们携带数据去下一个页面中,因为它的Request 和Response 对象在整个过程是是一直被传递下去的,所以它完全可以作为携带数据的载体。
综上所述我们可以知道:浏览器跳转方式,也就是我们所说的重定向跳转适用于大部分时候的转发,而服务器转发适用于我们想要给下一个页面带去值和对象的时候。
1.Cookie 和Session
我们知道,Request 对象和Response 对象的生命周期是很短的,当浏览器对Tomcat 服务器发出请求时Request 对象和Response 对象的生命周期就开始了,然后当Servlet 将内容响应给浏览器后Request 对象和Response 对象的生命周期就结束了,那么有没有生命周期更长的
,凯哥学堂(www.kaige123.com )
通讯技术呢?那就是我们接下来要讲到的Cookie 技术。
图3:Request 对象和Response 对象的生命周期
2.1 Http协议
Http 也就是超文本传输协议它基于TCP 协议之上,TCP 由
ServerSocket 类和Socket 类进行支撑,Tcp 协议是有状态的,它的连接过程是由客户端连接到服务器,它会询问服务器时候存在,如果服务器存在,它才会建立连接,一旦连接建立起来,通讯就可以一直进行下去,进行长时间的连接。
但是,Http 协议没有办法做成长时间的连接,这是因为长时间连接十分耗费服务器的资源,因此,Http 协议的需求就是既要使用TCP 的特性,又要打破TCP 长时间连接的特点,从而制作一个短时间交互的通讯。
使用Http 协议访问页面时,数据一去一回生命周期就结束了,下一次再访问页面就又是是新的的用户新的一去一回了,Http 协议是无状态的,所以对于Http 协议来说,每一次来访问的对象都是新的客户,至于客户来了多少次,是否登陆过这个网站,是否在网站中购物过,我们都无法知道,这样我们就很被动,所以我们需要一个可以描述这
,凯哥学堂(www.kaige123.com )
种状态的事务。
那么,如何在Http 这种无状态的协议下做出有状态的描述呢? 为了解决这种问题我们就想到了一些解决的方法,假如我们给访问过网站的客户端发送一张卡片这样下一次客户端再次对服务器进行访问时,它就会主动向我们出示它的卡片,这样我们就可以通过这张卡片知道它以前的一些数据了。
而现在就想出了这样一种通讯技术,当浏览器去访问Tomcat 服务器,由于它是一种无状态的访问,所以无法知道浏览器是否来过,所以这时候Tomcat 就给浏览器带了一些信息,然后浏览器就会将这些信息载入到用户的内存或是硬盘中,这样当下一次浏览器进行访问的时候,浏览器就会将这些信息带回到Tomcat 服务器上,这时Tomcat 服务器就可以取得浏览器的一些历史信息了。(如,我们可以认定带有信息的用户就默认为是老用户,而没有带信息的用户则认定为是新的用户,但是,这种技术必须依赖浏览器一起使用)
这种技术就是Cookie 。
2.2 Cookie(会话技术Ⅰ)
Cookie 技术就是利用浏览器帮我们存储信息,当浏览器再次访问服务器时再将这些信息发送给服务器,它是根据域名来发送的,当客户端第一次访问服务器时,服务器就会为客户端带上一些Cookie 信息,这些Cookie 信息存储的位置和它们时候带有有效期有关,当Cookie
上一篇 分析怎样加强网站优化提高权重
下一篇 新手该如何自己建立网站