您的位置:首页 > 其它

保存会话数据的两种技术之Cookie

2018-03-09 23:03 295 查看
* 两个会话的技术
* 会话概念:打开浏览器,可以访问WEB资源,多次访问WEB资源,关闭浏览器,整个过程一次会话。
* 购买商品
用户点击超链接通过一个servlet购买了一个商品,程序应该保存用户购买的商品,
以便于用户点结帐servlet时,结帐servlet可以得到用户商品为用户结帐。
* 把商品存入到ServletContext获取request域中呢?
* cookie和seesion的原理
看图02
保存会话数据的两种技术:
Cookie
•Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。Session•Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
Cookie的响应头set-cookie:product=1,浏览器的内存会保存cookie的内容,再发送请求时,会带着头cookie:product=1去访问。之后累加。
Session在服务器端开辟一块空间,分配一个唯一的标识,每次请求响应都带着唯一的标识,最终结算通过标识找到空间。
* cookie
* 显示上次的访问时间(案例)
* 第一次访问,输出欢迎,在服务器端,记录当前的时间,把当前的时间通过cookie回写到浏览器。
* 第二次访问,会带着上次的时间,获取时间,可以把时间显示到页面上,记录当前的时间,再把回写浏览器。
输出上次的访问时间。
Cookie翻译成中文是小甜点,小饼干的意思。在HTTP中它表示服务器送给客户端浏览器的小甜点。其实Cookie就是一个键和一个值构成的,随着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cookie再发送给服务器。
2 Cookie规范你大可以放心,Cookie不会占满你的硬盘。因为一个Cookie最多只有4KB,一个服务器最多只能发送到客户端20个Cookie,并且浏览器最多可以保存300个Cookie。当然,在浏览器大战的今天,一些浏览器为了打败对手,可能对Cookie规范“扩展”了一些,例如每个Cookie的大小为8KB,最多可保存500个Cookie等!但也不会出现把你硬盘占满的可能!
不同的浏览器之间不能共享Cookie!!!
3 Cookie的作用Cookie的作用可大了,但无论怎么夸大Cookie的作用都离不开“跟踪客户端状态”这句话。我们知道Cookie是服务器保存在客户端的信息,然后客户端会在下次请求时把Cookie在还给服务器,这样服务器就可以通过信息来识别客户端了。
就好比你去医院看病,第一次去需要买卡片,然后你去任何科室都需要你出示卡片。只要你出示卡片,医生就会知道你去过哪些科室,看了哪些病!卡片上只有一个ID,它就是Cooke,而你本人就是客户端,而医生就是服务器了。 
4 Cookie的属性Cookie最重要的4个属性:
  名字(name);
  值(value);
  路径(path);
  域(domain)。
* Cookie的API
* cookie的构造方式 Cookie(String name, String value) 
* String getName()  获取cookie的名称
* String getValue() 获取cookie的值

* void setMaxAge(int expiry)   :设置有效时间
* 失效cookie setMaxAge(0); 前提条件:设置有效路径(和之前设置过相同)

* void setPath(String uri)   :设置有效路径
* 默认的有效路径()
* 配置 /last 默认路径 /day11
* 配置 /servlet/last 默认路径 /day11/servlet

* void setDomain(String pattern)   :设置有效域名
* www.sina.com.cn
* sports.sina.com.cn
* xxx.sina.com.cn
* 设置有效域名 setDomain(".sian.com.cn");

* 会话级别的cookie:默认保存到浏览器的内存中。
* 持久的cookie:把cookie保存到磁盘上。通过setMaxAge(int a)进行设置。

* 显示用户上次访问过的商品信息(需求)
 *  1.获取请求参数
 *  2.获取cookie数组,通过指定的名称(自己指定)查找cookie
 *  3.如果cookie==null,第一次访问
 *  * 如果是第一次访问,创建cookie,回写浏览器
 *  4.如果cookie!=null,不是第一次访问
 *  * 如果不是第一次访问,说明我的cookie中已经存在id
 *  * 判断,当前的id是否已经存在cookie的中value
 *  * 如果存在,不用操作
 *  * 如果不存在,在后面追加(product=1,2)
 *  5.重定向到商品页面
5 保存Cookie到客户端保存Cookie到客户端,这是响应工作的一部分,所以这个方法是response对象的。并且Cookie是HTTP协议中的内容,所以保存Cookie是HttpServletResponse类的方法。
void addCookie(Cookie c):添加Cookie对象到当前response对象中,这个方法可以被调用多次,从而完成添加多个Cookie对象到response中。
public class AServlet extends HttpServlet {    public void doGet(HttpServletRequest request,            HttpServletResponse response)            throws ServletException, IOException {        Cookie c = new Cookie("id", "itcast")[涛1] ;        response.addCookie(c)[涛2] ;    }
}
创建名为id,值为itcast的Cookie对象。
把Cookie对象添加到response对象中去。



6 Cookie的生命
Cookie会在客户端存活多久呢?这就是Cookie的生命了。默认情况下,Cookie只在浏览器的内存中存活,也就是说,当你关闭浏览器后,Cookie就会消失!
可以使用Cookie#setMaxAge(int expiry)来设置Cookie的存活时间。参数expiry表示Cookie存活的秒数。
  cookie.setMaxAge(60*60):表示cookie对象可存活1小时。就算关闭浏览器,就算重启客户端电脑,cookie也会存活1小时。因为当maxAge大于0时,浏览器不仅会把cookie保存在浏览器内存中,还会把cookie保存到硬盘上。
  cookie.setMaxAge(-1):cookie的maxAge属性的默认值就是-1(其实只要是负数都是一个意思),表示只在浏览器内存中存活。一旦关闭浏览器窗口,那么cookie就会消失。
  cookie.setMaxAge(0):cookie被作废!表示cookie即不在内存中存活,也不在硬盘上存活,这样的cookie设置只有一个目的,那就是覆盖客户端原来的这个cookie,使其作废。
7 服务器端读取Cookie我们现在已经可以保存Cookie到客户端了,但还没有学习让服务器如何读取Cookie。
如果浏览器保存了Cookie,那么会在下一次请求时把Cookie放到请求头中发送给服务器,这时服务器需要在请求中读取Cookie。既然是在请求中读取,那么当然是使用request对象来读取了。
HttpServletRequest:Cookie[] getCookies()
注意,它返回的是Cookie数组,而不是一个Cookie对象。如果请求中没有Cookie,那么该方法返回null。
        Cookie[] cs = request.getCookies()[涛1] ;        if (cs != null[涛2] ) {            for (Cookie c : cs) [涛3] {                String str = c.getName() + ": " + c.getValue()[涛4]  + "<br/>";                response.getWriter().print(str);            }        }
获取当前请求中所有Cookie对象
如果返回的数组不是null
循环遍历所有Cookie对象
获取当前Cookie对象的名字与值
7 Cookie的路径Cookie路径会影响请求中是否包含Cookie,次要。
Cookie还有一个path属性,可以通过Cookie#setPath(String)方法来设置。你可以使用HttpWatch查看响应中的Set-Cookie中是否存在路径。

也就是说,就算你不设置Cookie的path,Cookie也是有路径的。这个路径就是请求的路径。例如在请求http://localhost/day07_03/AServlet时,服务器响应了一个Cookie,那么这个Cookie的默认路径就是/day07_03/。
例如请求的路径是http://localhost/day07_03/servlet/BServlet时,服务器响应了一个Cookie,那么这个Cookie的默认路径就是/day07_03/servlet/。
到现在我们还没说过Cookie的path有什么用,现在我们来聊聊path的作用。首先声明一点,path不是指Cookie在客户端存放的路径!!!不同的浏览器存放Cookie的路径是不同的!!!你不能通过Cookie的path来指定Cookie文件的存放路径!!!
那么Cookie的path是干什么的呢?假设你的浏览器当前已经有了两个Cookie:
  c1:name=id; value=itcast;path=/day07_03/;
  c2:name=name;value=qdmmy6; path=/day07_03/servlet/。
当访问http://localhost/day07_03/*时,请求头中会包含c1,而不会包含c2。
当访问http://localhost/day07_03/servlet/*时,请求头中会包含c1和c2。
也就是说,在访问子路径时,会包含其父路径的Cookie,而在访问父路径时,不包含子路径的Cookie。



如果你想在BServlet中设置的Cookie,在客户端访问AServlet时也包含在请求头中,那么就需要设置BServlet中的Cookie的path:
  c2.setPath(“/day07_03/”):硬编码
  c2.setPath(request.getContextpath() + “/”):活编码。
   这样就可以设置Cookie的路径,保存在访问AServlet时,也会包含BServlet中添加的Cookie。

8 Cookie的域
Cookie的domain属性可以让网站中二级域共享Cookie,次要!
百度你是了解的对吧! http://www.baidu.com http://zhidao.baidu.com http://news.baidu.com http://tieba.baidu.com
现在我希望在这些主机之间共享Cookie(例如在www.baidu.com中响应的cookie,可以在news.baidu.com请求中包含)。很明显,现在不是路径的问题了,而是主机的问题,即域名的问题。处理这一问题其实很简单,只需要下面两步:
  设置Cookie的path为“/”:c.setPath(“/”);
设置Cookie的domain为“.baidu.com”:c.setDomain(“.baidu.com”)。 
当domain为“.baidu.com”时,无论前缀是什么,都会共享Cookie的。但是现在我们需要设置两个虚拟主机:www.baidu.com和news.baidu.com。 
第一步:设置windows的DNS路径解析
找到C:\WINDOWS\system32\drivers\etc\hosts文件,添加如下内容
127.0.0.1       localhost
127.0.0.1       www.baidu.com
127.0.0.1       news.baidu.com
第二步:设置Tomcat虚拟主机
找到server.xml文件,添加<Host>元素,内容如下:
      <Host name="www.baidu.com"  appBase="F:\webapps\www"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false"/>
      <Host name="news.baidu.com"  appBase="F:\webapps\news"
            unpackWARs="true" autoDeploy="true"
            xmlValidation="false" xmlNamespaceAware="false"/>
第三步:创建A项目,创建AServlet,设置Cookie。
        Cookie c = new Cookie("id", "baidu");        c.setPath("/");        c.setDomain(".baidu.com");        c.setMaxAge(60*60);        response.addCookie(c);        response.getWriter().print("OK");
把A项目的WebRoot目录复制到F:\webapps\www目录下,并把WebRoot目录的名字修改为ROOT。
第四步:创建B项目,创建BServlet,获取Cookie,并打印出来。
        Cookie[] cs = request.getCookies();        if(cs != null) {            for(Cookie c : cs) {                String s = c.getName() + ": " + c.getValue() + "<br/>";                response.getWriter().print(s);            }        }
把B项目的WebRoot目录复制到F:\webapps\news目录下,并把WebRoot目录的名字修改为ROOT。
第五步:访问www.baidu.com\AServlet,然后再访问news.baidu.com\BServlet。
9 Cookie中保存中文
  Cookie中保存中文,次要。
Cookie中是不可以设置中文的,但可以使用URLEncoder.encode()方法编码后在存放到Cookie中。在获取Cookie时,需要先使用URLDecoder.decode()方法解码,再使用。
向客户端响应中添加Cookie
        String name = URLEncoder.encode("姓名", "UTF-8");        String value = URLEncoder.encode("张三", "UTF-8");        Cookie c = new Cookie(name, value);        c.setMaxAge(3600);        response.addCookie(c);
从客户端请求中获取Cookie
        response.setContentType("text/html;charset=utf-8");        Cookie[] cs = request.getCookies();        if(cs != null) {            for(Cookie c : cs) {                String name = URLDecoder.decode(c.getName(), "UTF-8");                String value = URLDecoder.decode(c.getValue(), "UTF-8");                String s = name + ": " + value + "<br/>";                response.getWriter().print(s);            }        }
10 Cookie练习
使用Cookie来验证用户是否已经登录。
  index.jsp:登录页面,提供登录表单提交到LoginServlet;
  LoginServlet:验证登录,获取用户名,保存到Cookie中,转发到AServlet;
  AServlet:受保护Servlet,查看Cookie是否存在;
  BServlet:受保护Servlet,查看Cookie是否存在。
 index.jsp
    <h1>XXX系统</h1>    <hr/>    <h3>请求输入你的姓名</h3>    <form action="/login/LoginServlet" method="get">    姓名:<input type="text" name="username" /><br/>    <input type="submit" value="提交"/>    </form>
LoginServlet.java
        String username = request.getParameter("username");        response.setContentType("text/html;charset=utf-8");        PrintWriter out = response.getWriter();        if(username == null || "".equals(username)) {            out.print("你瞎了!让你输入用户名,你没看见么?<br/>");            out.print("点击<a href='/login/index.jsp'>这里</a>返回登录页面!");            return;        }        CookieUtils.saveCookie(response, new Cookie("username", username));        response.sendRedirect("/login/AServlet");
 AServlet.java
        response.setContentType("text/html;charset=utf-8");        PrintWriter out = response.getWriter();        out.print("<h1>AServlet</h1>");        out.print("<hr/>");        String name = CookieUtils.getCookie(request, "username");        if(name == null) {            out.print("您还没有登录,点击<a href='/login/index.jsp'>这里</a>返回登录页面!");            return;        }        out.print("您好:" + name + ", 欢迎登录本系统<br/>");        out.print("<a href='/login/AServlet'>AServlet</a><br/>");        out.print("<a href='/login/BServlet'>BServlet</a><br/>");
 BServlet.java
        response.setContentType("text/html;charset=utf-8");        PrintWriter out = response.getWriter();        out.print("<h1>BServlet</h1>");        out.print("<hr/>");        String name = CookieUtils.getCookie(request, "username");        if(name == null) {            out.print("您还没有登录,点击<a href='/login/index.jsp'>这里</a>返回登录页面!");            return;        }        out.print("您好:" + name + ", 欢迎登录本系统<br/>");        out.print("<a href='/login/AServlet'>AServlet</a><br/>");        out.print("<a href='/login/BServlet'>BServlet</a><br/>");
 CookieUtils
publicclass CookieUtils {    publicstatic String getCookie(HttpServletRequest request, String name) {        Cookie[] cs = request.getCookies();        if(cs == null) {            returnnull;        }        for(Cookie c : cs) {            try {                String n = URLDecoder.decode(c.getName(), "utf-8");                if(n.equals(name)) {                    return URLDecoder.decode(c.getValue(), "utf-8");                }            } catch (UnsupportedEncodingException e) {                thrownew RuntimeException(e);            }        }        return"";    }      publicstaticvoid saveCookie(HttpServletResponse response, Cookie c) {        try {            String name = URLEncoder.encode(c.getName(), "utf-8");            String value = URLEncoder.encode(c.getValue(), "utf-8");            Cookie cookie = new Cookie(name, value);            cookie.setPath(c.getPath());            response.addCookie(cookie);        } catch (UnsupportedEncodingException e) {            thrownew RuntimeException(e);        }    }}
javax.servlet.http.Cookie类用于创建一个Cookie,response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法:
public Cookie(String name,Stringvalue)setValue与getValue方法setMaxAge与getMaxAge方法setPath与getPath方法setDomain与getDomain方法getName方法Cookie细节
一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。 一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。删除持久cookie,可以将cookie最大时效设为0,注意,删除cookie时,path必须一致,否则不会删除Cookie应用
显示用户上次浏览过的商品•编写商品信息列表,给每个商品起唯一的id值,通过id传值。•判断是否是第一次访问•如果是第一次访问,创建cookie,记录商品id,回写到浏览器•如果不是第一次访问,获取cookie中的商品信息,但是需要判断cookie中是否已经包含该商品,如果包含就不用处理,如果不包含,可以取出商品的id,累加操作。(可以编写一个判断是否包含的方法)•重定向到商品列表页面,把商品循环到列表页面•清除浏览记录
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: