在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(); } }
版权声明:本文为博主原创文章,未经博主允许不得转载。