Servlet基础_0400_Session 原理探究

本文讨论Session

一.Session 是什么?

Session是服务器端的一片内存,能够往里面搁任何数据;Session的name必须是字符串,值可以是任何对象

二.Session的实现原理:

Session的实现方式有俩种:(企业常问)
a.如果客户端支持Cookie,则Session通过Cookie实现,将SessionId保存在Cookie里
b.如果客户端不支持Cookie,则必须通过编程实现,重写URL(encodingURL()方法)

a种实现方式:将sessionId存入Cookie,且存入临时的Cookie, 不需要设置时间,当浏览器关闭时,这个存有sessionId的Cookie立即消失,因为窗口关了,再也不会去访问这个Session了
 b种实现方式:通过response.encodingURL()实现,即在每个需要使用Session的页面里的超链接都加上response.encodingURL("urlString");[encodingURL()的作用有两个,一个是转码,另一个是在url后面加上sessionID]

下面针对这两种实现方式做实验:

实验a.默认Cookie启用

//SessionInfoServlet.java

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionInfoServlet extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		
		HttpSession session = request.getSession(true);
		pw.println("Session Information:"+"<br />");
		pw.println("New Session:"+session.isNew()+"<br />");
		pw.println("SessionId:"+session.getId()+"<br />");
		pw.println("Session created time:"+new Date(session.getCreationTime())+"<br />");
		pw.println("Session last access time:"+new Date(session.getLastAccessedTime())+"<br /><br />");
		
		pw.println("Request Information:"+"<br />");
		pw.println("SessionID from request:"+request.getAttribute("JSESSIONID")+"<br />");
		pw.println("Session via Cookie:"+request.isRequestedSessionIdFromCookie()+"<br />");
		pw.println("Session via written URL:"+request.isRequestedSessionIdFromUrl()+"<br />");
		pw.println("Valid Session:"+request.isRequestedSessionIdValid()+"<br />");
		pw.println("<a href='ShowCookies'>Show ALL Cookies</a>"+"<br />");
		pw.println("<a href='"+response.encodeURL("SessionInfoServlet")+"'>refresh</a>");
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
	
}

//ShowCookies.java

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ShowCookies extends HttpServlet {

	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");
		PrintWriter pw = response.getWriter();
		Cookie[] cookies = request.getCookies();
		if(cookies!=null){
			for(int i=0;i<cookies.length;i++){
				pw.println(cookies[i].getName()+"  :  "+cookies[i].getValue()+"<br />");
			}
		}else{
			pw.println("没有Cookie!");
		}
		
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		doGet(req, resp);
	}
	
}

1.配置好这两个页面,先确定浏览器的Cookie能够使用;然后访问SessionInfoServlet页面,输出如下内容:

Session Information:
 New Session:true
 SessionId:21BF726DBA2132F44A0514EA90DCAB66
 Session created time:Wed Sep 28 20:43:04 CST 2011
 Session last access time:Wed Sep 28 20:43:04 CST 2011

 Request Information:
 SessionID from request:null
 Session via Cookie:false
 Session via written URL:false
 Valid Session:false
Show ALL Cookies[超链接]
refresh[超链接]

2.然后再次刷新,输出如下内容:

Session Information:
 New Session:false
 SessionId:21BF726DBA2132F44A0514EA90DCAB66
 Session created time:Wed Sep 28 20:43:04 CST 2011
 Session last access time:Wed Sep 28 20:43:04 CST 2011

 Request Information:
 SessionID from request:null
 Session via Cookie:true
 Session via written URL:false
 Valid Session:true
Show ALL Cookies[超链接]
refresh[超链接]

3.以后再刷新,SessionID不变了,只有last access time变化了,其他的所有值都不变化了,session生效了,然后点击Show ALL Cookies,发现:

JSESSIONID  :  21BF726DBA2132F44A0514EA90DCAB66

存在一个Cookie; 说明了如果客户端没有禁用Cookie的话,Session直接以Cookie为基础实现,当在服务器端创建好一个Session后,服务器会为每隔浏览器指定一个SessionID,然后存在客户端的临时Cookie中,当客户端再次访问服务器时,服务器会验证客户端的SessionID,以找到原来的那个Session,这样就实现了Session

实验b.将Cookie禁用

1.先禁用Cookie(此功能必须要浏览器支持,这个实验跟浏览器有关,有的浏览器是禁不掉Cookie的,我用的是Opera[IE8,FireFox,Chrom好像都不行])

2.访问SessionInfoServlet页面,输出如下内容:

Session Information:
 New Session:true
 SessionId:7FA232B7C56545ABA6ADE42CE58665EC
 Session created time:Wed Sep 28 20:55:55 CST 2011
 Session last access time:Wed Sep 28 20:55:55 CST 2011

 Request Information:
 SessionID from request:null
 Session via Cookie:false
 Session via written URL:false
 Valid Session:false
Show ALL Cookies[超链接]
refresh[超链接]

3.然后刷新,发现其内容的SessionID变化了:

Session Information:
 New Session:true
 SessionId:35247C4D2BC096F5C76122EA16DA9CBE
 Session created time:Wed Sep 28 20:57:13 CST 2011
 Session last access time:Wed Sep 28 20:57:13 CST 2011

 Request Information:
 SessionID from request:null
 Session via Cookie:false
 Session via written URL:false
 Valid Session:false
Show ALL Cookies
refresh

而且不断刷新,不断变化,此时的Session功能没法用,也就是说在禁用Cookie的情况下,Session功能是没有办法基于Cookie实现的,那么怎么解决呢?

重写URL,在每一个超链接上都加上response.encodingURL("url");例如例子中的refresh,点击,发现超链接:http://localhost:8080/Servlet_0400_Session/servlet/SessionInfoServlet;jsessionid=35247C4D2BC096F5C76122EA16DA9CBE  后面跟了一个jsessionid=.....;这样同样能将SessionID传个服务器,服务器同样能找到那个Session,Session功能也就实现了。

总结:既然两种情况下都能实现Session,那么究竟使用那种方式实现呢?

在时间紧急的情况下,我们可以默认客户端的Cookie是启用的,很多大型的公司就这么干的,例如新浪等,你客户端就应该开开Cookie,不然我们写程序还不得累死?只有当你们开开了Cookie才能使用我们的服务;当然,时间充足的情况下,让程序更加健壮,更加完美,也也要加上response.encodingURL(".."),许多著名公司就是这么干的,每个需要使用Session页面的URL都添加上了,例如微软,sun,oracle等等。


三.Session和Cookie的区别和联系:

1.Session是存在服务器端的,大部分的Session应用是基于Cookie的,Session里面能够存放任何数据,Session能被一个浏览器的多个标签,多个页面共享,也能被子窗口共享,但不能被新的浏览器共享,因为这个临时的Cookie只存在与当前浏览器的内存中,而新的浏览器是不共用同一部分内存的

2.Cookie是客户端的一个文本文件,也有可能是浏览器内存的临时Cookie[不会写入文件],写入文件的Cookie能够被多个浏览器共享,且它存在一个过期时间,到期后会自动清除,它一般用于2周内自动登录之类的功能

3.Session不存在路径的问题,他能被同一个web应用程序任何页面使用;而Cookie存在路径问题,servlet/jsp只能访问它同一级路径或者其子路径


四.探讨Session为什么不存在路径问题[只讨论基于Cookie实现的Session功能]

由于Session是基于Cookie实现的,服务器只有拿到从客户端传来的SessionID才能找到那个Session,那么现在Cookie存在一个路径问题,我假设这个servlet/jsp在父路径下,岂不是访问不到Cookie,那么也就拿不到那个SessionID,Session功能岂不是实现不了?

下面我们来做一个实验:

1.将web.xml修改成如下内容://将SessionInfoServlet的路径放入servlet下,而ShowCookies放到父路径下,为了让ShowCookies访问不到那个Cookie

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
	
	<servlet>
		<servlet-name>SessionInfoServlet</servlet-name>
		<servlet-class>com.servlet.SessionInfoServlet</servlet-class>
	</servlet>  	
	<servlet-mapping>
		<servlet-name>SessionInfoServlet</servlet-name>
		<url-pattern>/servlet/SessionInfoServlet</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<servlet-name>ShowCookies</servlet-name>
		<servlet-class>com.servlet.ShowCookies</servlet-class>
	</servlet>  	
	<servlet-mapping>
		<servlet-name>ShowCookies</servlet-name>
		<url-pattern>/ShowCookies</url-pattern>
	</servlet-mapping>
	
</web-app>
2.先保证Cookie启用,访问 http://localhost:8080/Servlet_0400_Session/servlet/SessionInfoServlet,然后访问  http://localhost:8080/Servlet_0400_Session/ShowCookies  ,发现页面输出了:JSESSIONID  :  21BF726DBA2132F44A0514EA90DCAB66,这个sessionID还是访问到了,也就是说服务器还是拿到了那个SessionID,难道这个Cookie不是存在servlet路径下,打开Cookie管理器,发现确实这个Cookie没有存在servlet子路径下,而是直接存在根目录下,原来如此,虽然SessionID是基于Cookie实现的,但他并不基于Cookie的路径,而是直接将其保存在根目录下[当然是在内存中]


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值