JavaWeb之Cookie&&Session详解

来源:互联网 发布:ptc软件 编辑:程序博客网 时间:2024/06/06 00:08

会话

用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

保存会话数据的两种技术

  • Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
  • Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源时,其他web资源再从用户各自的session中取出数据为用户服务。

Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。cookie原理:

这里写图片描述
浏览器第一次访问服务器时,没带有cookie,访问完Servlet1之后带有cookie信息回送给浏览器,存在缓存区。当浏览器第二次访问服务器时就已经带着缓存中的Cookie了,Servlet2此时就知道用户原本购买的信息了。

我们先看一下官方文档的对于Cookie的介绍。
这里写图片描述

javax.servlet.http.Cookie创建一个Cookie,response接口也定义了一个addCookie方法,它用于在其响应头中增加一个相应的SetCookie头字段。同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类方法:

  • public Cookie(String name, String value) //构造方法
  • setValue getValue
  • setMaxAge getMaxAge //设置Cookie有效期,不调这个方法 Cookie有效期是浏览器进程周期(用户打开浏览器到用户关闭浏览器)
  • setPath getPath //Cookie的有效目录 默认的有效路径是哪个Servlet发出去的就是哪个servlet下的目录
  • setDomain getDomain // 设置域 如 .sina.com.cn
  • getName

Cookie的应用:获取最近访问时间,与清除Cookie

  • 创建模拟网站首页的Servlet,
package com.xuda27.cookie;import java.io.IOException;import java.io.PrintWriter;import java.util.Date;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 CookieTest1 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //服务器向浏览器发送数据 编码以utf-8格式        response.setCharacterEncoding("utf-8");        //通知浏览器以utf-8打开数据        response.setContentType("text/html charset=utf-8");        PrintWriter out = response.getWriter();        out.print("<a href='/JavaWeb_CookieSession/servlet/CookieTest2'>清除Cookie</a><br>");        out.print("您上次访问时间是:");        //获得用户的时间cookie        Cookie []cookies = request.getCookies();        for(int i=0;cookies!=null && i<cookies.length;i++){            if(cookies[i].getName().equals("lastAccessTime")){                //得到用户上次访问时间                long cookieValue = Long.parseLong(cookies[i].getValue());                Date date = new Date(cookieValue);                out.print(date.toLocaleString());            }        }        //给用户回送最新的访问时间        //创建名为 lastAccessTime,值为系统当前时间的Cookie        Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");        cookie.setMaxAge(30*24*3600);//cookies有效期 30天        cookie.setPath("/JavaWeb_CookieSession");//设置cookie的有效路径:当前工程        response.addCookie(cookie);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {    }}

后台处理servlet:

package com.xuda27.cookie;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/** * 后台清除Cookie  * @author eden * */public class CookieTest2 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        //Cookie与前面的要长得一样        Cookie cookie = new Cookie("lastAccessTime",System.currentTimeMillis()+"");        cookie.setMaxAge(0);//清除        cookie.setPath("/JavaWeb_CookieSession");//路径要设置一样        response.addCookie(cookie);//浏览器增加空的cookie    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

测试结果:
这里写图片描述

我们打开firebug可以看到Cookie信息。
这里写图片描述

当我第一次访问CookieTest1(代表网站首页)时,没有带有Cookie信息所以就没有显示上一次访问的时间,然后Servlet才创建Cookie信息,然后在当我刷新页面时,Servlet就会发现有Cookie信息,这时就把上一次访问的时间给显示出来。当点击清除Cookie时,跳转到cookieTest2(代表后台处理),此时Servlet创建一个空的Cookie将原来Cookie信息覆盖,所以当我再一次访问CookieTest1时,上一次访问时间就没有了。

Cookie的一些细节

  1. 一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置(VALUE)。
  2. 一个Web站点可以给一个web浏览器发送多个Cookie,一个Web浏览器可以存储多个web站点提供的Cookie。
  3. 浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
  4. 如果创建了一个cookie,并将它发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要是要maxAge,并给出一个以秒为单位的时间。将最大时间设为0则是命令浏览器删除该cookie。
  5. 注意,删除Cookie时,path必须一致,否则不会删除

Session

Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,用户可以在访问服务器的web资源时,可以把各自的数据放在各自的session中,所以session跟ServletContext和Request一样也是域对象。当用户再去访问服务器中的其它web资源时,其它web资源就可以从用户各自的session中取出数据为用户服务。

Session的生命周期

Session域的作用范围是:默认情况下是在一个会话期间,当然这个范围我们是可以设置的,设置之后可以在多个会话之间。那么Session的生命周期是:
1. Session什么时候创建:
Servlet调用HttpServletRequest.getSession(true)这样的语句时才会被创建。
2. Session什么时候销毁:
Session在下列情况下被删除:

  • 程序调用HttpSession.invalidate()
  • 距离上一次收到客户端发送的session id时间间隔超过了session的最大有效时间
  • 服务器进程被停止

再次注意关闭浏览器只会使存储在客户端浏览器内存中的session的cookie失效,不会使服务器端的session对象失效。

Session实现原理

服务器创建session出来后,会把session的id号,以cookie的形式回写给浏览器,这样,只要浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现浏览器带session id过来了,就会使用内存中与之对应的session为之服务。

图解:

Session实现原理

浏览器访问Servlet1时,通过调用request.getSession()方法判断服务器中是否含有该session,如果没有则创建,如果有直接调用。因为第一次调用则创建session,并获取session的id,将这个id以Cookie形式会写给浏览器。当浏览器带着Cookie访问servlet2时,调用request.getsession 服务器发现服务器端的session id与cookie的值是否相同,相同直接为它服务。

内部原理,用代码实现 类似这样:

//获取session的IdString sessionId = session.getId();//将session的Id存储到名字为JSESSIONID的cookie中Cookie cookie = new Cookie("JSESSIONID", sessionId);//设置cookie的有效路径cookie.setPath(request.getContextPath());response.addCookie(cookie);

Session的相关API

  • getAttribute(String name)/getAttributeNames()/setAttribute(String
    name)/removeAttribute(String name) 这些方法都是和Session域中的值有关的方法,和ServletContext,Request域的是一样
  • getCreationTime():获取Session的创建时间
  • getId():获取session的id
  • getServletContext():获取ServletContext对象,即jsp中的application
  • invalidate():删除session,然后取消对任何绑定到它的对象的绑定。
  • setMaxInactiveInterval(int interval):这个方法设置session的最大有效时间,以秒为单位。负数时间指示session永远不会超时。

修改session默认生命周期:

        HttpSession session = request.getSession();        String sessionId = session.getId();        Cookie cookie = new Cookie("JSESSIONID", sessionId);        cookie.setPath("/JavaWeb_CookieSession");//设置session的有效路径,覆盖默认的session的路径        cookie.setMaxAge(30*60);//设置时长为30分钟        response.addCookie(cookie);        session.setAttribute("name", "你好!世界!");

取出session中的值:

        resp.addHeader("content-type", "text/html;charset=utf-8");        resp.setCharacterEncoding("utf-8");        PrintWriter out = resp.getWriter();        String name = (String) req.getSession().getAttribute("name");        out.print(name);

如果浏览器禁用Cookie中就无法使用上面的代码来取得存在Cookie中的session id,无法与服务器中的session id匹配。

所以在浏览器禁用Cookie时,怎么来解决session的数据共享问题呢?

  • response.encodeRedirectURL(java.lang.String url)
    用于对sendRedirect方法后的url地址进行重写。
  • response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
        response.addHeader("content-type", "text/html;charset=utf-8");        response.setCharacterEncoding("utf-8");        PrintWriter out = response.getWriter();        //创建session        request.getSession();        //会在原有的url后面加上 JSESSIONID 地址重写        String url1 = response.encodeURL("/JavaWeb_CookieSession/servlet/SessionTest1");        String url2 = response.encodeURL("/JavaWeb_CookieSession/servlet/SessionTest2");        out.print("<a href='"+url1+"'>说</a><br>");        out.print("<a href='"+url2+"'>看</a>");

在禁用Cookie之后,这两个方法会给地址重写。

这里写图片描述

它会在原有的地址后面加上 session id号。而如果不禁用Cookie则超链接的地址则不会重写。

Session和Cookie的主要区别

  • cookie是把用户的数据写给用户的浏览器。
  • session把用户的数据写到用户独占的session中。
  • session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

三个域对象的总结

  1. 产生数据之后,显示完了就没用了,就用request。
  2. 产生数据之后,除了显示等一会还有用,就用session。
  3. 产生数据之后,除了显示等一会还要给别人用,就用servletContext。
0 0
原创粉丝点击