代码改变世界

session

2015-04-30 15:02  -夜  阅读(200)  评论(0编辑  收藏  举报

        在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。



Session和Cookie的主要区别

1. Cookie是把用户的数据写给用户的浏览器。

2. Session技术把用户的数据写到用户独占的session中。

3. cookie是客户端技术

1). 数据保存在客户端,这个信息可以保存很长时间

2). 数据随时有可能被清空,所以cookie保存的数据是不太靠谱的

3). 数据被保存在了客户端,随时有可能被人看走,如果将一些敏感信息比如用户名密码等信息存在cookie中,可能有安全问题

4. session是服务器端技术

1). 数据保存在服务区端,相对来说比较稳定和安全

2). 占用服务器内存,所以一般存活的时间不会太长,超过超时时间就会被销毁.我们要根据服务器的压力和session 的使用情况合理设置session的超时时间,既能保证session的存活时间够用,同时不用的session可以及时销毁减少对服务器内存的占用.



Session 是一个域

 1. 作用范围:当前会话范围

 2. 生命周期:
        1) 当程序第一次调用到request.getSession()方法时说明客户端明确的需要用到session此时创建出对应客户端的Session对象.

        2) 当session超过30分钟(可以在web.xml中配置<session-config>设置该时间值)没有人使用则认为session超时销毁这个session.

        3)  程序中明确的调用session.invalidate()方法可以立即杀死session.

        4)  当服务器被非正常关闭时,随着虚拟机的死亡而死亡.

        5)  *如果服务器是正常关闭,还未超时的session会被以文件的形式保存在服务器的work目录下,这个过程叫做session的钝化.下次再正常启动服务器时,钝化着的session会被恢复到内存中,这个过程叫做session的活化.

  3. 作用:在会话范围内共享数据



session 的原理(request.getSession()方法内部执行)

1. 检查请求中有没有名字为 jsessionid的cookie,如果有,则拿出值(值为session 的唯一id)找到对应的session.

2. 如果没有,则检查请求的URL后有没有以参数的名字为jsessionid ,如果有则找到对应的Session。

3. 如果cookie中和url参数中都没有找到,则认为这个浏览器没有对应的Session,创建一个Session然后再在响应中添加名字为 jsessionid 的cookie,值就是这个Session 的id。



根据原理,实现多开同种浏览器共享session、关闭浏览器再打开不丢失session

       默认情况下,JSESSIONID 的path为当前web应用的名称,并且没有设置过MaxAge,是一个会话级别的cookie. 这意味着一旦关闭浏览器再新开浏览器时,由于JSESSIONID丢失,会找不到之前的Session。另外同时打开多个IE浏览器也无法共享同一session

     因此我们可以手动的发送名字为 jsessionid 的cookie,名字和path设置的和自动发送时一样,但是设置一下MaxAge,使浏览器除了在内存中保存JSESSIONID信息以外还在临时文件夹中以文件的形式保存,这样即使重开浏览器仍然可以使用之前的session。

	/**
	 * 设置session ,自定义jsessionid 的cookie。 
	 * ① 防止浏览器关闭等情况造成的session丢失
	 * ② 同时打开多个同种(IE)浏览器 ,共享session
	 * 
	 * @param strName
	 * @param strValue
	 * @param hour
	 *            有效小时数,如果此参数为0,cookie在浏览器关闭的时候自动失效
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static void SetSesionCookie(HttpServletRequest request,
			HttpServletResponse response, String strName, String strValue,
			int hour) throws UnsupportedEncodingException {
		// String prod = request.getParameter(strName);
		// prod = new String(prod.getBytes("iso8859-1"), "utf-8");

		HttpSession session = request.getSession();
		// 自定义jsessionid 的cookie义
		Cookie jc = new Cookie("JSESSIONID", session.getId());
		jc.setPath(request.getContextPath());
		jc.setMaxAge(hour);
		response.addCookie(jc);

		session.setAttribute(strName, strValue);
	}



IE禁用Cookie后的session处理(URL重写)

        如果浏览器禁用了Cookie,浏览器就没有办法JSESSIONID cookie,这样就用不了Session了.

1). 我们可以使用URL重写的机制,在所有的超链接后都以参数的形式拼接JSESSIONID信息,从而在点击超链接时可以使用URL参数的方式待会JSESSIONID,从而使用Session

2). 将URL进行重写拼接上JSESSIONID的过程就叫做URL重写

request.getSession() --在URL重写之前一定要先创建出Session,才有Session id,才能进行重写

response.encodeURL()--- 一般的地址都用这个方法重写

response.encodeRedirectURL() --- 如果地址是用来进行重定向的则使用这个方法

*url重写的方法一旦发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作

<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
			
	request.getSession();
	String url1 = path + "/servlet/BuyServlet?prod=电视机";
	//encodeURL 方法,如果发现浏览器带回了任意cookie信息,则认为客户端没有禁用cookie,就不会再进行重写操作,否则会重写,
	//在url后面加jsessionid,改成	path + "/servlet/BuyServlet;jessionid=ASDADKLADJFIOJQEWLADFAL?prod=电视机
	url1 = response.encodeURL(url1);
	String url2 = path + "/servlet/BuyServlet?prod=冰箱";
	url2 = response.encodeURL(url2);
	String url3 = path + "/servlet/PayServlet";
	url3 = response.encodeURL(url3);
%>

		<a href="<%=url1%>">电视机</a>
		<br />
		<a href="<%=url2%>">冰箱</a>
		<br />
		<a href="<%=url3%>">结账</a>
		<br />



session案例-防止表单重复提交

1.  在页面上生成一个随机数的session,同时将值赋值隐藏控件,两个值是相等的。

		<%
		  	Random r = new Random();
		  	int valinum = r.nextInt();
		  	session.setAttribute("valinum",valinum+"");
		%>
		<form
			action="${pageContext.request.contextPath }/servlet/ResubServlet"
			method="POST" onsubmit="return canSub()">
			用户名:
			<input type="text" name="username" />
			<input type="hidden" name="valinum" value="<%=valinum %>" />
			<input type="submit" value="注册" />
		</form>


2. 在后台取出,隐藏控件中的值、session中的值,第一次提交后,移除session中的值,此时两个值不再相等了。

3. 如果是第二次提交,两个值不相等,说明是重复提交。

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		response.setContentType("text/html;charset=utf-8");
		request.setCharacterEncoding("utf-8");
		String username = request.getParameter("username");
		String hideVal = request.getParameter("valinum");
		String sessionVal = (String) request.getSession().getAttribute(
				"valinum");
		if (sessionVal != null && !"".equals(sessionVal)
				&& hideVal.equals(sessionVal)) {
			request.getSession().removeAttribute("valinum");
			System.out.println("向数据库中注册一次:" + username);
		} else {
			response.getWriter().write("from web:不要重复提交!!");
		}
	}





删除获取设置Session

	/**
	 * 设置session ,自定义jsessionid 的cookie。 
	 * ① 防止浏览器关闭等情况造成的session丢失 
	 * ② 同时打开多个同种(IE)浏览器 ,共享session
	 * 
	 * @param strName
	 * @param strValue
	 * @param hour
	 *            有效小时数,如果此参数为0,cookie在浏览器关闭的时候自动失效
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static void SetSesionCookie(HttpServletRequest request,
			HttpServletResponse response, String strName, String strValue,
			int hour) throws UnsupportedEncodingException {
		// String prod = request.getParameter(strName);
		// prod = new String(prod.getBytes("iso8859-1"), "utf-8");

		HttpSession session = request.getSession();
		// 自定义jsessionid 的cookie义
		Cookie jc = new Cookie("JSESSIONID", session.getId());
		jc.setPath(request.getContextPath());
		jc.setMaxAge(hour);
		response.addCookie(jc);

		session.setAttribute(strName, strValue);
	}

	/**
	 * 设置session
	 * 
	 * @param strName
	 * @param strValue
	 * @param hour
	 *            有效小时数,如果此参数为0,cookie在浏览器关闭的时候自动失效
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static void SetSesion(HttpServletRequest request, String strName,
			String strValue) throws UnsupportedEncodingException {
		HttpSession session = request.getSession();
		session.setAttribute(strName, strValue);
	}

	/**
	 * 读取session 如果为空,返回null
	 * 
	 * @param strName
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String GetSession(HttpServletRequest request,
			HttpServletResponse response, String strName)
			throws UnsupportedEncodingException {
		// 通知浏览器以UTF-8码表打开回送的数据
		response.setContentType("text/html;charset=utf-8");

		HttpSession session = request.getSession();
		// String prod = new String(prod.getBytes("iso8859-1"), "utf-8");
		String prod = (String) session.getAttribute(strName);
		return prod;
	}

	/**
	 * 删除指定session
	 * 
	 * @param strName
	 * @return
	 */
	public static void DelSession(HttpServletRequest request, String strName) {
		if (request.getSession(false) != null
				&& request.getSession().getAttribute(strName) != null) {
			request.getSession().removeAttribute(strName);
			// request.getSession().invalidate();
		}
	}

	/**
	 * 删除所有session
	 * 
	 * @return
	 */
	public static void DelAllSession(HttpServletRequest request) {
		if (request.getSession(false) != null) {
			request.getSession(false).invalidate();
		}
	}


版权声明:本文为博主原创文章,未经博主允许不得转载。

作者:夜 本文地址:http://www.cnblogs.com/ful1021 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明。如有问题,可以邮件:531761819@qq.com 联系我,非常感谢。