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); } }
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); } }
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); } }
在浏览器查看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); } }
如上:好像并不需要重写所有的URl,只需要将session所在的servlet的URl重写即可。
重写后的地址栏显示如下,多加了;jsessionid=XXX
http://url--->http://url;jsessionid=xxxx.......

浙公网安备 33010602011771号