zoukankan      html  css  js  c++  java
  • session

            在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();
    		}
    	}


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

  • 相关阅读:
    [整] Android Fragment 生命周期图
    LruCache--远程图片获取与本地缓存
    Android基于XMPP Smack openfire 开发的聊天室
    基于XMPP协议的Android即时通信系
    Android实现推送方式解决方案
    日历工具类(一)——公历农历互相转换
    IdHTTPServer使用注意问题
    用TIdIPWatch获取本地IP
    delphi TStringList 用法详解
    WIN7 64位配置X86 MySQL 数据源
  • 原文地址:https://www.cnblogs.com/ful1021/p/4804315.html
Copyright © 2011-2022 走看看