码迷,mamicode.com
首页 > 其他好文 > 详细

讲透Session、Cookie和ServletContext

时间:2016-05-03 18:09:31      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

1. 什么是 Cookie

       1) Cookie 的机制:

            当你在初次浏览网站的时候,WEB 服务器会先送一小小资料放在你的计算机上,Cookie 会帮你在网站上所打的文字或是一些选择,都纪录下来。当下次你再光临同一个网站,WEB 服务器会先看看有没有它上次留下的 Cookie 资料,有的话,就会依据 Cookie里的内容来判断使用者,送出特定的网页内容给你。 

       2) Cookie 的应用:

            1.保存用户名、密码,在一定时间不用重新登录

            2.记录用户访问网站的喜好,比如有无背景音乐、网页的背景色是什么

            3.网站的个性化,比如定制网站的服务、内容

            4.分析用户的习惯,喜好向用户推送广告等。

            针对1,我们可以以 csdn 为例,在登录界面勾选保存密码选框,登录之后,服务器就会根据用户需要在本地磁盘创建 cookie,将加密过后的用户名和密码信息回写到本地 cookie。那么,下次需要登录时候,csdn 服务器首先会查看本地是否存在保存用户名和密码的 cookie 信息,如果存在,那么服务器就解密 cookie 中的用户名和密码信息,并将信息写入用户名和密码栏,这样就做到了“免密”登录。这些信息就像是小甜饼一样,数据量并不大,服务器端在需要的时候可以从客户端读取。


图解 Cookie

        3)Cookie 的用法:

       1.cookie有点像一张表,分两列,一个是名字,一个是值,数据类型都是String

       2.如何创建一个cookie(在服务器端创建的)

       Cookie c=new Cookie(String name,String val);

       3.如何将一个cookie添加到客户端

       response.addCookie(c);

      4.如何读取cookie(从客户端读到服务器)

       request.getCookie();
技术分享
cookie 抽象结构
       4)Cookie 的其它说明

           1.可以通过IE——工具——internet选项——隐私——高级来启用或是禁用cookie

           2.由于cookie的信息是保存在客户端的,因此安全性不高

           3.cookie信息的生命周期可以在创建时设置(比如30s),从创建那一时刻起,就开始计时,到时该cookie的信息就无效了

2.什么是 Session

        1)Session 的机制

            Session的机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。一般这个cookie的名字都是类似于SEEESIONID。但cookie可以被人为的禁止,则必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如: 

      <form name="testform" action="/xxx"> 
      <input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764"> 
      <input type="text"> 
      </form> 

           实际上这种技术可以简单的用对action应用URL重写来代替。

        2)Session 的应用

          1.网上商城中的购物车

          2.保存登陆用户的信息

          3.将某些数据放入到session中,供同一用户的各个方面使用

          4.防止用户非法登陆到某个页面

           ……

技术分享

服务器分配给A客户端的session空间

服务器分配给B客户端的session空间

服务器分配给C客户端的session空间

图解 session

                以淘宝购物车为例,当我登录,并将商品添加到购物车,此时服务器就为我的客户端创建一块独占 Session 空间(该 Session 根据本地 Cookie 进行区分),并将商品写入到 Session 空间。当我查看购物车页面,服务器就会找到我的 Session 空间,从 Session 中取出我原先存入的商品,展示在我的购物车页面。那么,另外一个人用另一个客户端登录并打开他的购物车,为什么展示的不是我的商品的内容呢?原因很简单,服务器访问某个网站时,服务器就会在服务器的内存为该浏览器分配一个空间,该空间被这个浏览器独占。这个空间就是session空间,该空间中的数据默认存在时间为30min,你也可以修改该值。

        3)Session 的用法


             和 Cookie 类似,Session 也像一张表,分两列,一个是名字,一个是值,数据类型都是String

            1.得到session

        HttpSessionhs=request.getSession(true);

            2.向session添加属性

        hs.setAttribute(Stringname,Objectval);

            3.从session得到某个属性

        Stringname=hs.getAttribute(Stringname);

            4.从session中删除掉某个属性

        hs.removeAttribute(Stringname);

            5.注销session中的内容(比较安全的一种方式)

        ht.setMaxInactiveInterval(0);

技术分享

session 抽象结构

          4)Session 的其他说明

            1.session中属性存在的默认时间是30min,你也可修改它存在的时间:(a)修改web.xml   b)在程序中修改

            2.上面说的这个30min指的是用户的发呆时间,而不是累计时间

            3.当某个浏览器访问网站时,服务器会给浏览器分配一个唯一的sessionid,并以此来区分不同的浏览器(即客户端)

            4.因为session的各个属性要占用服务器的内存,因此软件公司都是在迫不得已的情况下才使用

Cookie 和 Session 的对比

            1.存在的位置

               cookie保存在客户端,session保存在服务器端

            2.安全性

               比较而言,cookie的安全性比session要弱

            3.网络传输量

               cookie通过网络在客户端与服务器端传输,而session保存在服务器端,不需要传输

            4.建议大小

               单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie

             将登陆信息等重要信息存放为SESSION,其他信息如果需要保留,可以放在COOKIE中

3. 什么是ServletContext

         1)ServletContext 的机制

        ServletContext 是一种服务器机制,ServletContext对象实现数据共享。WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。

         2)ServletContext 的应用

           1.网站计数器

           2.网站在线用户显示

           3.简单的聊天系统,显示在线人数等

           ....

技术分享

Cookie/Session/ServletContext 对比图解

        3)ServletContext 的用法

            1.如何得到ServletContext实例

       this.getServletContext();

            2.你可以把它想象成一张表,这个和session非常相似,每一行就是一个属性:

<pre name="code" class="java">       <span style="font-family: Arial, Helvetica, sans-serif;">setAttribute(Stringname, Object ob);  //  添加属性</span>
       <span style="font-family: Arial, Helvetica, sans-serif;">getAttribute(Stringname);   // 得到值,返回Object类型  </span>
       <span style="font-family: Arial, Helvetica, sans-serif;">removeAttribute(Stringname);  //  删除属性</span>


            3.生命周期

               ServletContext中的生命周期从创建开始,到服务器关闭而结束。

         4)ServletContext 的其他说明

            因为存在ServletContext中的数据会长时间保存在服务器,会占用内存,因此我们建议不要向ServletContext中添加过大的数据,切忌。

4. 用程序解读

第一个 Servlet 是 ServletFileTest1,用于创建 ServletContext,Cookie,Session 并即时访问:

package test;

import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class ServletFileTest1 extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res) {
        res.setContentType("text/html;charset=utf-8");
        try (PrintWriter pw = res.getWriter()) {
            pw.println("----------servletcontext---------<br>");
            ServletContext sc = req.getServletContext();
            sc.setAttribute("name", "tomcat");
            pw.println("放入ServletContext 信息:" + sc.getAttribute("name") + "<br>");
            
            pw.println("----------cookie---------<br>");
            Cookie ck1 = new Cookie("weight", "5kg");
            Cookie ck2 = new Cookie("height", "17cm");
            ck1.setMaxAge(10);
            res.addCookie(ck1);
            res.addCookie(ck2);
            Cookie[] ck = req.getCookies();
            for (Cookie c : ck) {
                pw.println(c.getName() + " :" + c.getValue() + "<br>");
            }
            
            pw.println("----------session---------<br>");
            HttpSession hs = req.getSession(true);
            hs.setAttribute("love", "coding");
            hs.setMaxInactiveInterval(10);
            pw.println("love:" + hs.getAttribute("love"));
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse res) {
        this.doPost(req, res);
    }
}

第二个Servlet 是 ServletFileTest2,它用于访问 ServletFileTest1 创建的 ServletContext,Cookie,Session:

package test;

import java.io.PrintWriter;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class ServletFileTest2 extends HttpServlet {
    
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res) {
        res.setContentType("text/html;charset=utf-8");
        try (PrintWriter pw = res.getWriter()) {
            pw.println("----------servletcontext---------<br>");
            ServletContext sc = req.getServletContext();
            pw.println("放入ServletContext 信息:" + sc.getAttribute("name") + "<br>");
            
            pw.println("----------cookie---------<br>");
            Cookie[] ck = req.getCookies();
            if (ck != null) {
                for (Cookie c : ck)
                    pw.println(c.getName() + " :" + c.getValue() + "<br>");
            } else {
                pw.println("cookie is null<br>");
            }
            
            pw.println("----------session---------<br>");
            HttpSession hs = req.getSession(true);
            pw.println("love:" + hs.getAttribute("love"));
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    
    @Override
    public void doPost(HttpServletRequest req, HttpServletResponse res) {
        this.doPost(req, res);
    }
}
web.xml 容器部署:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">

  <display-name>Welcome to Tomcat</display-name>
  <description>
     Welcome to Tomcat
  </description>
  	
	<servlet>
		<servlet-name>s1</servlet-name>
		<servlet-class>test.ServletFileTest1</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>s1</servlet-name>
		<url-pattern>/s1</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<servlet-name>s2</servlet-name>
		<servlet-class>test.ServletFileTest2</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>s2</servlet-name>
		<url-pattern>/s2</url-pattern>
	</servlet-mapping>
</web-app>
步骤1. 30秒之内,依次第一次打开

  1)http://localhost:8080/myWebSite/s1,得到下列结果:

----------servletcontext---------
放入ServletContext 信息:tomcat
----------cookie---------
JSESSIONID :F76184BB9FBC5EAF97E6A7123CE73B48
weight :5kg
height :17cm
----------session---------
love:coding


  2)http://localhost:8080/myWhttp://localhost:8080/myWebSite/s2ebSite/s2  (第一个浏览器),得到下列结果:

----------servletcontext---------
放入ServletContext 信息:tomcat
----------cookie---------
JSESSIONID :F76184BB9FBC5EAF97E6A7123CE73B48
weight :5kg
height :17cm
----------session---------
love:coding

  3)http://localhost:8080/myWebSite/s2 (第二个浏览器),得到下列结果:

----------servletcontext---------
放入ServletContext 信息:tomcat
----------cookie---------
JSESSIONID :1D4B6CD33F385A88EBF4E46FBAA8C108
----------session---------
love:null

步骤2. 30秒后,依次刷新界面
 1)http://localhost:8080/myWebSite/s2 (第一个浏览器),得到下列结果:

----------servletcontext---------
放入ServletContext 信息:tomcat
----------cookie---------
JSESSIONID :F76184BB9FBC5EAF97E6A7123CE73B48
height :17cm
----------session---------
love:null

 2)http://localhost:8080/myWebSite/s2 (第二个浏览器),得到下列结果:

----------servletcontext---------
放入ServletContext 信息:tomcat
----------cookie---------
JSESSIONID :1D4B6CD33F385A88EBF4E46FBAA8C108
----------session---------
love:null

这样就简略地看出 ServletContext,Cookie,Session的区别。

当然如果要区别出 Cookie 和 Session,请读者自行尝试步骤1中的 1)和 2),并多次刷新 2),30秒后发现 Cookie 已经消失了,而 Session 依然可以被访问到,这也就是Cookie 的绝对时间和 Session 的间隔时间的区别。

讲透Session、Cookie和ServletContext

标签:

原文地址:http://blog.csdn.net/happyaaaaaaaaaaa/article/details/51303918

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!