服务器的两大跳转方式.docx
- 文档编号:5526190
- 上传时间:2022-12-18
- 格式:DOCX
- 页数:11
- 大小:22.32KB
服务器的两大跳转方式.docx
《服务器的两大跳转方式.docx》由会员分享,可在线阅读,更多相关《服务器的两大跳转方式.docx(11页珍藏版)》请在冰豆网上搜索。
服务器的两大跳转方式
服务器的两大跳转方式:
1.1浏览器跳转(重定向跳转)
Servlet中使用的最多的跳转就是浏览器跳转,也就是重定向跳转,而浏览器跳转也是最常用的跳转方法之一。
图1:
浏览器跳转的基本流程示意图
浏览器跳转,在跳转的过程中会通知浏览器,也就是说,每一次发生跳转,浏览器都是可以知道的,并且浏览器上的URL路径会随着页面的跳转而发生改变。
我们从上节课的知识中知道了请求头和响应头的存在,浏览器会将请求的信息封装在请求头中,并发送给Servlet,而响应头则会在第一时间将信息响应给浏览器,因为响应头中并不包含网页代码,它只包含了是否发生跳转、网页访问是否超时等诸如此类的信息,浏览器在解析了响应头中的信息后,如果发现需要进行跳转,那么浏览器就会再次访问跳转后的目标页面,然后再将新的页面信息呈现给用户。
浏览器跳转,会对Tomcat服务器产生两次访问,因为浏览器除了访问最初的页面外还访问了跳转后的新的页面,所以同理,由于它对Tomcat服务器发生了两次访问,所以它具有两副Request和Response对象(第一次访问Tomcat服务器和第二次访问Tomcat服务器都分别产生了一副Request和Response对象)。
1.2服务器转发(服务器内部跳转)
服务器转发和浏览器转发最大的不同就是,在服务器转发的过程中浏览器是全然不知的,也就是说,在使用服务器转发的方式进行跳转页面时,浏览器是根本不知道服务器发生了跳转的,所以这种跳转方式也叫做服务器内部跳转。
图2:
服务器转发的基本流程示意图
而使用服务器转发,浏览器上的URL路径也是不会发生改变的,就如,用户看到的URL路径是对A页面进行访问的路径,但实际上用户已经访问到了B页面(这里可以是对静态页面进行访问,也可以是对Servlet进行访问),只是浏览器并不知道在服务器内部发生了转发而已,在整个服务器转发的过程中只会产生一副Request和Response对象。
1.3浏览器跳转和服务器转发的实际举例
我们书写一个简单的浏览器跳转:
当我们访问ServletAAA页面时,它会跳转到ServletBBB页面上:
代码部分:
publicclassAAAextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//跳转到ServletBBB,当然也可以跳转到Html页面
response.sendRedirect("BBB");
}
}
publicclassBBBextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//带值给浏览器,也就是将信息显示在浏览器而不是控制台上
PrintWriterout=response.getWriter();
out.println("我是ServletBBB~BBB~BBB~");
out.flush();
out.close();
}
}
代码执行结果:
由图上,我们可以看到,我们明明输入的路径是14/AAA,但在我们点击回车请求访问后它的路径就变为了//BBB,这就是浏览器跳转,它的URL路径地址是随着页面的变化而发生变化的。
那么,我们怎么才能知道,浏览器跳转中使用的是两副Request和Response对象呢?
我们可以分别将它们的Request和Response对象的内存地址打印出来,并让AAA中的Request对象带上一个值,看在BBB中的Request对象是否可以得到这个值(如果是同一个Request对象就一定可以取到这个值):
代码部分:
publicclassAAAextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//为Request对象设置一个键值对(存入值)
request.setAttribute("user","yezi");
//跳转到ServletBBB,当然也可以跳转到Html页面
"AAA_request:
"+request);
"AAA_response"+response);
response.sendRedirect("BBB");
}
}
publicclassBBBextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
"BBB_request:
"+request);
"BBB_response"+response);
"Request_Value:
"+request.getAttribute("user"));
PrintWriterout=response.getWriter();
out.println("ServletBBB~BBB~BBB~");
out.flush();
out.close();
}
}
代码执行结果:
由图我们可以看到,虽然AAA和BBB的Request和Response对象的内存地址看起来好像是相同的,但是最重要的值却没有被取出来,图上显示为null,这就说明了它们并不是同一个Request对象。
接下来我们书写一个服务器转发,同样使用Request对象带值的方式来检测转发前后的Request对象是否为同一个Request对象:
代码部分:
publicclassAAAextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//为Request对象设置一个键值对(存入值)
request.setAttribute("user","yezi");
//获得一个转发对象(目标页面BBB)
RequestDispatcherre_D=request.getRequestDispatcher("BBB");
//开始服务器转发(并将Request对象和Response对象一齐传递下去)
re_D.forward(request,response);
}
}
publicclassBBBextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
"Request_Value:
"+request.getAttribute("user"));
PrintWriterout=response.getWriter();
out.println("ServletBBB~BBB~BBB~");
out.flush();
out.close();
}
}
代码执行结果:
浏览器结果:
从上述两个结果我们可以看到,使用Request带值的方法可以看出服务器转发中的Request对象是同一个对象,并且使用服务器转发的方式时,URL路径不会发生改变,虽然我们访问到的是BBB页面,但是URL路径依然显示为AAA页面的地址。
PS:
以下四个方法十分重要,如我我们想使用到这几个方法,就需要使用服务器转发的方式,因为只有服务器转发的方式才可以将值带给下一个页面,只有服务器转发方式产生的Request对象和Response对象才会一直传递下去,数据才不会丢失:
request.setAttribute("键","值");
request.getAttribute("键");
request.removeAttribute("键");
//得到所有键值对的键的名称
request.getAttributeNames();
这几个方法在重定向跳转中是没有用的,因为它每一次的Request对象和Response对象都是新的。
1.4使用两种转发方式的具体情况
通过实验,我们可以看到,在浏览器跳转中我们使用到了两副Request和Response对象,它的这两个对象,在完成一来一回的数据传递后生命周期就会结束,所以,如果我们想利用Request和Response对象为我们携带数据到下一个页面,是不可能的;而服务器转发全程只是用到了一副Request和Response对象,所以我们完全可以使用它为我们携带数据去下一个页面中,因为它的Request和Response对象在整个过程是是一直被传递下去的,所以它完全可以作为携带数据的载体。
综上所述我们可以知道:
浏览器跳转方式,也就是我们所说的重定向跳转适用于大部分时候的转发,而服务器转发适用于我们想要给下一个页面带去值和对象的时候。
1.Cookie和Session
我们知道,Request对象和Response对象的生命周期是很短的,当浏览器对Tomcat服务器发出请求时Request对象和Response对象的生命周期就开始了,然后当Servlet将内容响应给浏览器后Request对象和Response对象的生命周期就结束了,那么有没有生命周期更长的通讯技术呢?
那就是我们接下来要讲到的Cookie技术。
图3:
Request对象和Response对象的生命周期
2.1Http协议
Http也就是超文本传输协议它基于TCP协议之上,TCP由ServerSocket类和Socket类进行支撑,Tcp协议是有状态的,它的连接过程是由客户端连接到服务器,它会询问服务器时候存在,如果服务器存在,它才会建立连接,一旦连接建立起来,通讯就可以一直进行下去,进行长时间的连接。
但是,Http协议没有办法做成长时间的连接,这是因为长时间连接十分耗费服务器的资源,因此,Http协议的需求就是既要使用TCP的特性,又要打破TCP长时间连接的特点,从而制作一个短时间交互的通讯。
使用Http协议访问页面时,数据一去一回生命周期就结束了,下一次再访问页面就又是是新的的用户新的一去一回了,Http协议是无状态的,所以对于Http协议来说,每一次来访问的对象都是新的客户,至于客户来了多少次,是否登陆过这个网站,是否在网站中购物过,我们都无法知道,这样我们就很被动,所以我们需要一个可以描述这种状态的事务。
那么,如何在Http这种无状态的协议下做出有状态的描述呢?
为了解决这种问题我们就想到了一些解决的方法,假如我们给访问过网站的客户端发送一张卡片这样下一次客户端再次对服务器进行访问时,它就会主动向我们出示它的卡片,这样我们就可以通过这张卡片知道它以前的一些数据了。
而现在就想出了这样一种通讯技术,当浏览器去访问Tomcat服务器,由于它是一种无状态的访问,所以无法知道浏览器是否来过,所以这时候Tomcat就给浏览器带了一些信息,然后浏览器就会将这些信息载入到用户的内存或是硬盘中,这样当下一次浏览器进行访问的时候,浏览器就会将这些信息带回到Tomcat服务器上,这时Tomcat服务器就可以取得浏览器的一些历史信息了。
(如,我们可以认定带有信息的用户就默认为是老用户,而没有带信息的用户则认定为是新的用户,但是,这种技术必须依赖浏览器一起使用)
这种技术就是Cookie。
2.2Cookie(会话技术Ⅰ)
Cookie技术就是利用浏览器帮我们存储信息,当浏览器再次访问服务器时再将这些信息发送给服务器,它是根据域名来发送的,当客户端第一次访问服务器时,服务器就会为客户端带上一些Cookie信息,这些Cookie信息存储的位置和它们时候带有有效期有关,当Cookie信息带有有效期时,这些Cookie信息就会存储在硬盘之中,而如果这些Cookie信息没有带有有效期,则它们就会存储在内存之中,这些存储在内存之中的Cookie信息在浏览器关闭的时候就会被销毁,所以一般将这些Cookie信息保存在内存中会更加安全,而服务器根据浏览器提供的Cookie信息,就可以区分新用户和老用户了,这样就可以依靠Cookie做出了客户的有状态描述。
图4:
Cookie的传输示意图
下面我们就来简单的进行一次Cookie传输:
代码部分---下载Cookie:
publicclassServlet_CookieextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//创建一个Cookie
Cookiec=newCookie("user","yezi");
//设置Cookie的最大存活时间,这样Cookie就会存放在硬盘中
单位:
秒
c.setMaxAge(300);
//设置Cookie版本
c.setVersion(12);
//要给客户端带去信息用到Response对象
response.addCookie(c);
"Cookie下载成功!
");
}
}
代码部分---查看Cookie:
publicclassCookie_ShowextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//获得Cookie列表(从请求头获得)
Cookiecs[]=request.getCookies();
//防止空指针异常
if(cs!
=null){
for(Cookiecookie:
cs){
;
}
}
}
}
代码执行结果:
我们可以看到,但我们访问,Cookie被下载到了我们的电脑中,当我们再访问4/Show时,可以看到Cookie的名字被显示了出来,证明Cookie是下发成功的。
2.3Session技术(会话技术Ⅱ)
Session技术是cookie技术的升级和使用,Session技术是基于Cookie技术之上制作的,它可以脱离Cookie使用也可以不脱离cookie使用,它是网页上的有状态描述Session的会话跟踪技术的实现。
图5:
Cookie的使用方式示意图
说到Session会话技术,就不得不说一下Cookie技术的缺点,由于Cookie技术将信息存储在了本地,所以它是不太安全,这使得这些信息随时都可能被别人读取;并且,Cookie技术没有办法携带过多信息,因为,如果Cookie中带有1M的信息内容,那么就意味着当用户每一次访问页面的时候都需要将这1M的信息上传到服务器,而当访问结束后,浏览器又必须将这些Cookie信息从服务器下载下来,这样十分消耗资源,并且会产生了一些网络垃圾。
那么Session的使用流程又是怎样的呢?
通过下面的示意图我们可以看到,当浏览器对Tomcat服务器第一次发出请求时,由于用户之前并没有访问过Tomcat服务器,所以用户没有属于他的Session对象,所以如果用户需要Session时,Servlet就会为用户创建并分配一个Session对象,并将这个Session对象放入Tomcat服务器的Session池中,再将创建对象时所得到的SessionID存入Cookie中并返回给浏览器,这些数据时存储在内存中的;当客户端第二次对服务器进行访问时,这时用户已经有cookie了,所以它会带着它的Cookie中存储的SessionID一同访问Tomcat服务器,而这时Tomcat服务器它就会去询问它的Session池,并对照用户的SessionID查看是否存有这个对象,如果找到了这个对象则取出这个对象,立刻进行使用,而如果没有找到对应的对象(Session对象有可能被销毁),就创建一个新的Session对象再扔进池子里,并使用这个对象。
图6:
***Session对象的终极使用流程示意图***
Session对象的默认生命周期是30分钟,也就是说如果30分钟内用户没有一次访问Tomcat服务器,那么Tomcat服务器就会对Session对象进行销毁。
当然,我们也可以对这个时间进行手动设置;
Session对象会将所有的信息都存放在Tomcat服务器上,所以它就比Cookie将信息存储在本地相对安全很多,用户只需要保存好他们的SessionID这把钥匙就可以了,而不需要再进行繁琐的上传与下载,并且,SessionID这把钥匙也不会占用用户过多的带宽,从而也就解决了我们上面所说到的Cookie的缺点。
下面我们就简单的使用一下Session对象:
方法不带参数时,代码部分:
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
//获取Session对象的方法(无参数默认为true):
HttpSessionsession=request.getSession();
}
代码执行结果:
方法带参数时,代码部分:
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
HttpSessionsession02=request.getSession(false);
}
代码执行结果:
这里的参数表示在客户端没有SessionID的情况下是否创建一个Session对象,传入True表示如果客户端有SessionID则去池子里抓Session对象,如果客户端没有SessionID就创建一个Session对象,而传入flase表示不创建如果客户端有SessionID则去池子里抓Session对象,如果抓不到Session对象就返回null。
我们还可以手动设置Session对象的有效时间,我们只需要在web.xml中配置一句话就可以了:
设置Session对象超时时间,单位:
分钟(下面就将超时时间设置为了15分钟):
作业:
做出一个简单的登录页面,将登录信息放入LoginServlet,LoginServlet回去判断用户名是否存在,(存储两套,写死),如果判断成功,如果失败,就跳回原来的页面,就会跳转到VipServlet,然后就会写上欢迎会员XX这句话输出,如果直接登录VIPServlet,会直接跳转到登录页面上去。
使用cookie技术。
代码部分:
登陆页面:
center">叶子的VIP登录页面
center"> 用户名: 密码:
Login_Servlet:
publicclassL_ServletextendsHttpServlet{
publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException,IOException{
response.setContentType("text/html;GBK");
PrintWriterout=response.getWriter();
Stringuser=(String)request.getParameter("username");
Stringpass=(String)request.getParameter("password");
if(user==null||pass==null){
out.print("Theusernameorpasswordisblank,pleasecheck!
");
}elseif((user.equals("yezi")&&pass.equals("521"))
||(user.equals("zhangsan")&&pass.equals("123"))){
if(user.equals("yezi")){
Cookiec=newCookie("c_name","YeZi");
c.setVersion(12);
response.addCookie(c);
}else{
Cookiec=newCookie("c_name","ZhangSan");
c.setVersion(12);
response.addCookie(c);
}
RequestDispatcherre=request.getRequestDispatcher("VIP");
re.forward(req
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 服务器 跳转 方式