【简记】Java Web 内幕——Cookie与Session简介和使用

来源:互联网 发布:俊知地产 编辑:程序博客网 时间:2024/06/06 02:47

本文内容:

  • 会话场景
  • Cookie类
  • HttpSession类
  • 使用Demo

会话场景

登录场景:
小张: 输入“张三” (保存数据: context.setAttribute(“name”,”张三”)) -> 用户主页(显示“张三”)
小李: 输入“李四”(保存数据:context.setAttribute(“name”,”李四”)) -> 用户主页(显示“李四”)

问题: context是所有用户公有的资源,会覆盖数据。

小张: 输入“张三”(保存数据: request.setAttribute(“name”,”张三”))- > 用户主页(显示“张三”)

问题: 一定要使用转发技术来跳转页面!

※解决办法: 可以使用session域对象来保存会话数据!


会话技术

Cookie技术:会话数据保存在浏览器客户端。
Session技术:会话数据保存在服务器端。


Cookie技术

Cookie类:用于存储会话数据

1)构造Cookie对象
Cookie(java.lang.String name, java.lang.String value)
2)设置cookie
void setPath(java.lang.String uri) :设置cookie的有效访问路径
void setMaxAge(int expiry) : 设置cookie的有效时间(本地)(注意这里与Session不同)
void setValue(java.lang.String newValue) :设置cookie的值

3)发送cookie到浏览器端保存
void response.addCookie(Cookie cookie) : 发送cookie

4)服务器接收cookie
Cookie[] request.getCookies() : 接收cookie


Cookie原理

1)服务器创建cookie对象,把会话数据存储到cookie对象中。
new Cookie(“name”,”value”);

2) 服务器发送cookie信息到浏览器
response.addCookie(cookie);
举例: set-cookie: name=eric (隐藏发送了一个set-cookie名称的响应头)

3)浏览器得到服务器发送的cookie,然后保存在浏览器端。

4)浏览器在下次访问服务器时,会带着cookie信息
举例: cookie: name=eric (隐藏带着一个叫cookie名称的请求头)

5)服务器接收到浏览器带来的cookie信息
request.getCookies();


Cookie的细节

1)void setPath(java.lang.String uri) :设置cookie的有效访问路径。有效路径指的是cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着cookie信息,否则不带cookie信息。

2)void setMaxAge(int expiry) : 设置cookie的有效时间。
正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。
负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!
零:表示删除同名的cookie数据

3)Cookie数据类型只能保存非中文字符串类型的。可以保存多个cookie,但是每个域名最多存放50个Cookie(Chrome浏览器),每个Cookie的大小限制为4KB(Chrome可以更大)。

public class CookieDemo1 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        System.out.println(Charset.defaultCharset());        //1.创建Cookie对象        Cookie cookie1 = new Cookie("name","eric");        Cookie cookie2 = new Cookie("email","jacky@qq.com");        /**         * 1)设置cookie的有效路径。默认情况:有效路径在当前web应用下。         * 默认情况下,当符合有效路径,浏览器就会把cookie又发回到服务器端         */        cookie1.setPath("");        cookie2.setPath("");        /**         * 2)设置cookie的有效时间         * 正整数:表示cookie数据保存浏览器的缓存目录(硬盘中),数值表示保存的时间。         负整数:表示cookie数据保存浏览器的内存中。浏览器关闭cookie就丢失了!!         零:表示删除同名的cookie数据         */        //cookie1.setMaxAge(20); //20秒,从最后不调用cookie开始计算        cookie1.setMaxAge(-1); //cookie保存在浏览器内存(会话cookie)        //cookie1.setMaxAge(0); // 会删除名为name的Cookie        //2.把cookie数据发送到浏览器(通过响应头发送: set-cookie名称)        //response.setHeader("set-cookie", cookie1.getName()+"="+cookie1.getValue());        //推荐使用这种方法,避免手动发送cookie信息        response.addCookie(cookie1);        response.addCookie(cookie2);        //3.接收浏览器发送的cookie信息        /*String name = request.getHeader("cookie");        System.out.println(name);*/        Cookie[] cookies = request.getCookies();        //注意:判断null,否则空指针        if(cookies!=null){            //遍历            for(Cookie c:cookies){                String name = c.getName();                String value = c.getValue();                System.out.println(name+"="+value);            }        }else{            System.out.println("没有接收cookie数据");        }    }}

显示用户上次登陆的时间

public class HisServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html; charset=utf-8");        Cookie[] cookies = request.getCookies();        String time = null;        if(cookies!=null){            for (Cookie e: cookies) {                if(e.getName().equals("time")){                    response.getWriter().print("您上次的登录时间是"+e.getValue());                    e.setValue(getTime());                    response.addCookie(e);                    break;                }            }        }        if(cookies==null || time==null){             Cookie cookie = new Cookie("time", getTime());            cookie.setMaxAge(1*30*24*60*60);//保存一个月            response.addCookie(cookie);        }    }    public String getTime(){        Date date=new Date();        DateFormat format=new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss");        String time=format.format(date);        return time;    }}

error:
An invalid character [32] was present in the Cookie value

ASCII中,第32是空格,这句话的意思是Cookie value不能有空格,高版本的tomcat不允许有空格。


购物车简单实现

部分代码(利用cookie保存用户浏览记录)

        /**         * 创建cookie,并发送         */        //1.创建cookie        Cookie cookie = new Cookie("prodHist",createValue(request,id));        cookie.setMaxAge(1*30*24*60*60);//一个月        //2.发送cookie        response.addCookie(cookie);    }    /**     * 生成cookie的值     * 分析:     *          当前cookie值                     传入商品id               最终cookie值     *      null或没有prodHist          1                     1    (算法: 直接返回传入的id )     *             1                  2                     2,1 (没有重复且小于3个。算法:直接把传入的id放最前面 )     *             2,1                1                     1,2(有重复且小于3个。算法:去除重复id,把传入的id放最前面 )     *             3,2,1              2                     2,3,1(有重复且3个。算法:去除重复id,把传入的id放最前面)     *             3,2,1              4                     4,3,2(没有重复且3个。算法:去最后的id,把传入的id放最前面)     * @return     */    private String createValue(HttpServletRequest request,String id) {        Cookie[] cookies = request.getCookies();        String prodHist = null;        if(cookies!=null){            for (Cookie cookie : cookies) {                if(cookie.getName().equals("prodHist")){                    prodHist = cookie.getValue();                    break;                }            }        }        // null或没有prodHist        if(cookies==null || prodHist==null){            //直接返回传入的id            return id;        }        // 3,21          2        //String -> String[] ->  Collection :为了方便判断重复id        String[] ids = prodHist.split(",");        Collection colls = Arrays.asList(ids); //<3,21>        // LinkedList 方便地操作(增删改元素)集合        // Collection -> LinkedList        LinkedList list = new LinkedList(colls);        //不超过3个        if(list.size()<3){            //id重复            if(list.contains(id)){                //去除重复id,把传入的id放最前面                list.remove(id);                list.addFirst(id);            }else{                //直接把传入的id放最前面                list.addFirst(id);            }        }else{            //等于3个            //id重复            if(list.contains(id)){                //去除重复id,把传入的id放最前面                list.remove(id);                list.addFirst(id);            }else{                //去最后的id,把传入的id放最前面                list.removeLast();                list.addFirst(id);            }        }        // LinedList -> String        StringBuffer sb = new StringBuffer();        for (Object object : list) {            sb.append(object+",");        }        //去掉最后的逗号        String result = sb.toString();        result = result.substring(0, result.length()-1);        return result;    }

Session

Cookie的局限:
1)Cookie只能存字符串类型。不能保存对象
2)只能存非中文。
3)1个Cookie的容量不超过4KB。

如果要保存非字符串,超过4kb内容(大部分浏览器的最大值),只能使用session技术。

Session特点:
会话数据保存在服务器端。(内存中)


Session技术核心

HttpSession类:用于保存会话数据

1)创建或得到session对象
HttpSession getSession()
HttpSession getSession(boolean create)

2)设置session对象
void setMaxInactiveInterval(int interval) : 设置session的有效时间
void invalidate() : 销毁session对象
java.lang.String getId() : 得到session编号

3)保存会话数据到session对象
void setAttribute(java.lang.String name, java.lang.Object value) : 保存数据
java.lang.Object getAttribute(java.lang.String name) : 获取数据
void removeAttribute(java.lang.String name) : 清除数据

session也是域对象,和request还有servletContext一样

相较于Cookie,session中的数据可以直接在servlet中传递(域对象的特点),而Cookie必须要先传给浏览器,再从浏览器拿到


Session原理

现象:

s1:session对象

浏览器1:
1)创建session对象,保存会话数据
HttpSession session = request.getSession(); –保存会话数据
浏览器1的新标签页
1)得到session对象的会话数据
HttpSession session = request.getSession(); –可以取出

新的浏览器1(必须是完全关闭后再重启):
1)得到session对象的会话数据
HttpSession session = request.getSession(); –不可以取出

浏览器2:(没有带s001,不能返回s1)
1)得到session对象的会话数据
HttpSession session = request.getSession(); –不可以取出

原理:

代码解读:HttpSession session = request.getSession();(既可以用来创建对象,也可以得到session对象)

1)第一次访问创建session对象,给session对象分配一个唯一的ID,叫JSESSIONID
2)把“JSESSIONID”作为Cookie的Name,value为一个字符串,发送给浏览器保存
3)第二次访问的时候,浏览器带着JSESSIONID的cookie访问服务器
4)服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象。
5)如果找到对应编号的session对象,直接返回该对象
6)如果找不到对应编号的session对象,创建新的session对象,继续走1的流程

JSESSIONID在每个客户端是唯一的,因此会出现上面的现象。


Session细节

1)java.lang.String getId() : 得到session编号
2)两个getSession方法:
getSession(true) / getSession() : 创建或得到session对象。没有匹配的session编号,自动创 建新的session对象。
getSession(false): 得到session对象。没有匹配的session编号,返回null
3)void setMaxInactiveInterval(int interval) : 设置session的有效时间(是指在服务器端的最大时间)
session对象销毁时间:
3.1 默认情况30分服务器自动回收
3.2 修改session回收时间
3.3 全局修改session有效时间

<!-- 修改session全局有效时间:分钟 -->    <session-config>        <session-timeout>1</session-timeout>    </session-config>

3.4.手动销毁session对象
void invalidate() : 销毁session对象

4)如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题(那就把Session的ID )

/**         * 手动发送一个硬盘保存的cookie给浏览器         */        Cookie c = new Cookie("JSESSIONID",session.getId());        c.setMaxAge(60*60);        response.addCookie(c);

阅读全文
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 晨勃消失了怎么办戒色 赌时时彩一直输怎么办 车停小区被砸了怎么办 车停在小区被砸怎么办 地板拖过有腥味怎么办 网联成立支付宝怎么办 微信号站街不了怎么办 苹果照片全没了怎么办 没给员工交社保怎么办 淘宝图片超过3m怎么办 亚马逊被跟卖了怎么办 刚开饭店没生意怎么办 趣店诈骗注册了怎么办 乐动力步数不准怎么办 乐动力计步为零怎么办 净网大师ios下架怎么办 探探手机号换了怎么办 大象册被和谐后怎么办 试客联盟不退款怎么办 比邻号被禁用了怎么办 被手机分期骗了怎么办 分期乐登录不上怎么办 拼多多绑定微信怎么办 狗吃了鸭骨头怎么办 在趣购上当了怎么办 加不了别人微信怎么办 微信号加不上人怎么办 微信无法加好友怎么办 失眠的时候怎么办才好 贵宾狗不吃饭该怎么办 玩时时彩输钱了怎么办 白色衣物被染色了怎么办 白衬衣漂白变黄怎么办 白衬衣被染红了怎么办 染色了的白衣服怎么办 洗白衣服染色了怎么办 白衣服染上色了怎么办 白色衣服被染色了怎么办 白色的衣服被染色了怎么办 被毒蜜蜂咬了怎么办 被黑黄蜂咬了怎么办