cookie&session

>Cookie
Cookie数据是由客户端来保存和携带的,所以称之为客户端技术

cookie容量:一个浏览器最多保存300个cookie。每个站点做多保存20个cookie,每个cookie的大小限制是4kb。
cookie默认存活时间:浏览器关闭的时候结束。
cookie持久化:若希望浏览器将cookie存储到磁盘上就需要用到maxAge(),以秒为单位的时间。
cookie删除:删除cookie时,path必须一致,否则不会被删除。

属性:
name:名称不能唯一确定一个Cookie。路径可能不同。
value:不能存中文。
path:默认值是写Cookie的那个程序的访问路径
比如:http://localhost:8080/day10_00_cookie/servlet/login写的Cookie
path就是:/day10_00_cookie看当前创建cookie的资源(servlet)文件路径 也可以是reuest.getContextPath();获取当前应用的路径 
客户端在访问服务器另外资源时,根据访问的路径来决定是否带着Cookie到服务器
当前访问的路径如果是以cookie的path开头的路径,浏览器就带。否则不带。
maxAge(有效存活时间):cookie的缓存时间。默认是-1(默认存在浏览器的内存中)。单位是秒。
负数:cookie的数据存在浏览器缓存中
0:删除。路径要保持一致,否则可能删错人。
正数:缓存(持久化到磁盘上)的时间

cookie在磁盘上持久化的文本形式:


cookie的存储

public class CookieDemo1 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = resp.getWriter();
        Cookie[] cookies = req.getCookies();
        for (int i = 0;cookies!=null&& i < cookies.length; i++) {
            if("lastAccessTime".equals(cookies[i].getName())) {
                long l = Long.parseLong(cookies[i].getValue());
                pw.write("您上次的登陆时间为:"+new Date(l).toLocaleString());
            }
        }
        
        //删除cookie跳转的servlet
        pw.print("<a href='"+req.getContextPath()+"/servlet/clear'>clear cookie</a>");
        
        //创建cookie
        Cookie ck = new Cookie("lastAccessTime", System.currentTimeMillis()+"");
        //设置cookie的有效时间,单位是秒
//        ck.setMaxAge(5*60);
        //设置cookie的path
//        ck.setPath("/day10_00_cookie/servlet");
//        ck.setPath(req.getContextPath());  //建议这两种写法   表示当前的应用/day10_00_cookie
        ck.setPath("/");  //表示 /day10_00_cookie   ck.setPath("http://www.taobao.com");==>也可以将cookie带到该网站
        
        resp.addCookie(ck);  //需要将cookie添加给响应报文==>设置好了cookie的相关属性再进行添加
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
View Code

cookie的取出

public class CookieDemo2 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = resp.getWriter();
        Cookie[] cookies = req.getCookies();
        for (int i = 0;cookies!=null&& i < cookies.length; i++) {
            if("lastAccessTime".equals(cookies[i].getName())) {
                long l = Long.parseLong(cookies[i].getValue());
                pw.write("您上次的登陆时间为:"+new Date(l).toLocaleString());
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req, resp);
    }
}
View Code

cookie的清除

public class ClearServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建一个cookie对象
        Cookie ck = new Cookie("lastAccessTime", "");
        //和创建cookie时候的路径path对应起来,不然可能会删除对象
        ck.setPath("/");
        ck.setMaxAge(0);
        resp.addCookie(ck);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}
View Code


在浏览器查看cookie方式


>Session

也是一个域对象: session(多servlet可以共享一个session数据)   servletContext(整个应用的范围)  request(servlet执行之前创建,结束的时候销毁。)
session默认存活时间:30min。
同一个会话下,可以使一个应用的多个资源共享数据。
cookie客户端技术,只能存字符串。HttpSession服务器端的技术,可存储对象。
在WEB开发中,服务器为每一个客户端(请求你创建且没有session才创建)创建一个会话对象(session对象)。注意一个浏览器独占一个session对象

原理详解:
session机制是一种服务器端的机制
用来在无状态的HTTp协议下越过多个请求页面来维持和识别用户。
当程序需要为某个客户端的请求创建一个session的时候,
服务器首先检查这个客户端的请求里是是否包含一个session id标识。

如果包含一个session id则说明以前为此客户端创建过session
服务器就按照session id把这个session检索出来使用,
若没有创建过,则创建一个新的Session。

创建时机:
HttpSession session = request.getSession();
如果当前没有session,则会立刻建立一个session;
如果有session则返回当前session。
这句话和
HttpSession session = request.getSession(true);
的效果是一样的。

HttpSession session = request.getSession(false);
则不会自动建立session。
若当前没有session,你所得到的seesion只会是一个null。

总结:
session不是一打开网站就会立刻建立。
它的建立需要基于下面两个条件中的任意一个:
1:在servlet中手动调用
HttpSession session = request.getSession();
或者
HttpSession session = request.getSession(true);
2:jsp中没有写<%@ page session="false"%>
(默认情况下它是<%@ page session="true"%>的)
如果两个条件同时都不满足,那么你建立的只是一个无seesion的连接。
session格式:


30min后服务端的session和客户端的JSESSIONID=xxx,才会被删除掉。重新调用HttpSession session = request.getSession();重新创建此两个对象。

常用方法
把数据保存在HttpSession对象中,该对象也是一个域对象。
void setAttribute(String name,Object value);
Object getAttribute(String name);
void removeAttribute(String name);
HttpSession.getId():
setMaxInactiveInterval(int interval)  设置session的存活时间  单位s
或者使用配置文件的方式

<session-config>
        <!-- 设置session的有效时间,单位是分钟 -->
        <session-timeout>10</session-timeout>
</session-config>

invalidate() 使此会话无效。

getSession():内部执行原理
1、获取名称为JSESSIONID的cookie的值。
2、没有这样的cookie,服务端创建一个新的HttpSession对象,分配一个唯一的SessionID。并且在浏览器中写一个名字为JSESSIONID=sessionID(dbe22defb...)的cookie
3、有这样的Cookie,获取cookie的值(dbe22defb...),从服务器的内存中找到对应的HttpSession对象。
HttpSession request.getSession(boolean create):
true:和getSession()功能一样。
false:根据客户端JSESSIONID的cookie的值,找对应的HttpSession对象,找不到返回null(不会创建新的,只是查询)。

客户端禁用cookie后的会话数据保存问题
客户端禁用cookie:浏览器永远不会向服务器发送cookie的请求消息头。
或者存在浏览器不支持cookie技术。==>看浏览器有没有发送cookie请求消息头,没有就重写URL,有就不重写。
解决方案:
方案一:在主页上给出提示:请不要禁用您的cookie
方案二:URL重写。必须对网站的所有地址都重写。

public class AddCart extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out =resp.getWriter();
        
        String id = req.getParameter("id");
        Book book = DBUtil.getBookById(id);
        HttpSession session = req.getSession();  //这时候是带JSESSIONID来找session
        ArrayList<Book> list = (ArrayList<Book>) session.getAttribute("cart");
        if(null==list) {
            list =new ArrayList<Book>();
        }
        list.add(book);
        session.setAttribute("cart", list);
        out.write("购买成功:"+book.getName());
        String url  = req.getContextPath()+"/servlet/showAll";
        resp.setHeader("refresh", "2;url="+resp.encodeURL(url));
//        resp.setHeader("refresh", "2;url="+req.getContextPath()+"/servlet/showAll");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
View Code

如上:好像并不需要重写所有的URl,只需要将session所在的servlet的URl重写即可。
重写后的地址栏显示如下,多加了;jsessionid=XXX

http://url--->http://url;jsessionid=xxxx.......

 

posted @ 2018-12-02 11:26  payn  阅读(178)  评论(0)    收藏  举报