一、Cookie概述
Cookie是由服务器端生成并储存在浏览器客户端上的数据。在javaweb开发中Cookie被当做java对象在web服务器端创建,并由web服务器发送给特定浏览器客户端,并且WEB服务器可以向同一个浏览器客户端上同时发送多个Cookie,每一个Cookie对象都由name和value组成,name和value只能是字符串类型,浏览器接收到来自服务器的Cookie数据之后默认将其保存在浏览器缓存中(如果浏览器关闭,缓存消失,Cookie数据消失),只要浏览器不关闭,当我们下一次发送“特定”请求的时候,浏览器负责将Cookie数据发送给WEB服务器。我们还可以使用特殊的方法,将Cookie保存在客户端的硬盘上,永久性保存。这样关闭浏览器Cookie还是存在的,不会消失,比如:实现十天内自动登录。

1、Cookie是什么? Cookie作用? Cookie保存在哪里?
翻译过来:曲奇饼干
Cookie可以保存会话状态,但是这个会话状态是保留在客户端上。
只要Cookie清除,或者Cookie失效,这个会话状态就没有了。
Cookie可以保存在浏览器的缓存中,浏览器关闭Cookie消失。
Cookie也可以保存在客户端的硬盘文件中,浏览器关闭Cookie还在,除非Cookie失效。

2、Cookie只有在javaweb中有吗?
Cookie不止是在javaweb中存在。
只要是web开发,只要是B/S架构的系统,只要是基于HTTP协议,就有Cookie的存在。
Cookie这种机制是HTTP协议规定的。
3、 Cookie实现的功能,常见的有哪些?
保留购物车商品的状态在客户端上
十天内免登录
等等…

5、在java程序中怎么创建Cookie
Cookie cookie = new Cookie(String cookieName,String cookieValue);
6、Cookie在客户端的保存形式和有效时间
服务器端默认创建的Cookie,发送到浏览器之后,浏览器默认将其保存在缓存中,当浏览器关闭之后Cookie消失。 可以通过设置Cookie的有效时长,以保证Cookie保存在硬盘文件当中。但是这个有效时长必须是>0的。换句话说,只要设置Cookie的有效时长大于0,则该Cookie会被保存在客户端硬盘文件当中。有效时长过去之后,则硬盘文件当中的Cookie失效。 服务器创建Cookie对象之后,调用setMaxAge方法设置Cookie的有效时间。

 
cookie.setMaxAge(60 * 60 * 24 * 10);  //10天内有效
如果这个有效时间 >0,则该Cookie对象发送给浏览器之后浏览器将其保存到硬盘文件中。
如果这个有效时间 <0,则该Cookie对象也是被保存在浏览器缓存中,待浏览器关闭Cookie消失。
如果这个有效时间 =0,则该Cookie从服务器端发过来的时候就已经是一个已过时的Cookie。

7、在浏览器客户端无论是硬盘文件中还是缓存中保存的Cookie,什么时候会再次发送给服务器呢?
浏览器会不会提交发送这些Cookie给服务器,是和请求路径有关系的。
请求路径和Cookie是紧密关联的。
不同的请求路径会发送提交不同的Cookie
8、Cookie和请求路径之间的关系
每一个Cookie和请求路径是绑定在一起的,只有特定的路径才可以发送特定的Cookie。实际上浏览器是这样做的:浏览器在向web服务器发送请求的时候先去对应的请求路径下搜索是否有对应的Cookie,如果有Cookie,并且Cookie没有失效,则发送该Cookie或者多个Cookie到服务器端。请求路径和Cookie的关系是这样对应的: 假如获取Cookie时的路径是 :
http://127.0.0.1:8080/hcz/getCookie

这时浏览器请求服务器,服务器生成Cookie,并将Cookie发送给浏览器客户端。这个浏览器中的Cookie会默认和“hcz/”这个路径绑定在一起。也就是说,以后只要发送“hcz/”请求,Cookie一定会提交给服务器。
将来发送Cookie的路径包括如下路径 :
http://127.0.0.1:8080/hcz/getCookie(相同路径)
http://127.0.0.1:8080/hcz/xxxx(同目录)
http://127.0.0.1:8080/hcz/xxxx/xxxx/xxx(子目录)

假如获取Cookie时的路径是 :
http://127.0.0.1:8080/hcz/servlet/getCookie

这时浏览器请求服务器,服务器生成Cookie,并将Cookie发送给浏览器客户端。这个浏览器中的Cookie会默认和“servlet/”这个路径绑定在一起。也就是说,以后只要发送“servlet/”请求,Cookie一定会提交给服务器。
将来发送Cookie的路径包括如下路径 :
http://127.0.0.1:8080/hcz/servlet/getCookie(相同路径)
http://127.0.0.1:8080/hcz/servlet/xxxxx(同目录)
http://127.0.0.1:8080/hcz/servlet/xxxxx/xxxx(子目录)

其实路径是可以指定的,可以通过java程序进行设置,保证Cookie和某个特定的路径绑定在一起,例如: cookie.setPath(“/hcz/king”);
那么Cookie将和 “/hcz/king” 路径绑定在一起,只有发送 “http://127.0.0.1:8080/hcz/king” 请求路径,浏览器才会提交Cookie给服务器。
9、浏览器是可以禁用Cookie,什么意思?
当浏览器禁用Cookie之后,服务器还是仍然会将Cookie发送给浏览器,只不过这次浏览器选择了不接收

10、浏览器提交Cookie给服务器,服务器怎么接收Cookie?

 
//从request对象中获取所有提交的Cookie
Cookie[] cookies = request.getCookies();
//遍历cookie数组取出所有的cookie对象
if(cookies != null){
    for(Cookie cookie : cookies){
        String cookieName = cookie.getName();
        String cookieValue = cookie.getValue();
        System.out.println(cookieName + "=" + cookieValue);
    }
}
 

session概述:

Session表示会话,不止是在javaweb中存在,只要是web开发,都有会话这种机制。

在java中会话对应的类型是:javax.servlet.http.HttpSession,简称session/会话

在java web中session是一个存储在WEB服务器端的java对象,该对象代表用户和WEB服务器的一次会话。 那什么才叫一次会话呢?

一般多数情况下,是这样描述的:用户打开浏览器,在浏览器上进行一些操作,然后将浏览器关闭,表示一次会话结束。

本质上的描述:从session对象的创建,到最终session对象超时之后销毁,这个才是真正意义的一次完整会话

Cookie可以将会话状态保存在浏览器客户端,HttpSession可以将会话状态保存在WEB服务器端。

在会话进行过程中,web服务器一直为当前这个用户维护者一个会话对象/HttpSession(重要!!!)

在WEB容器中,WEB容器维护者大量的HttpSession对象,换句话说,在WEB容器中应该有一个“session列表”

也就是说张三访问WEB服务器,服务器会生成一个张三的session对象,李四去访问WEB服务器,服务器会生成一个李四的session对象。

系统为每一个访问者都设立了独立的session对象,用以存取数据,并且各个访问者的session对象互不干扰。 session与cookie是紧密相关的

Cookie可以将会话状态保存在客户端,HttpSession可以将会话状态保存在服务器端。 session的使用

session的工作原理:

  1. 打开浏览器,在浏览器上发送首次请求
  2. 服务器会创建一个HttpSession对象,该对象代表一次会话
  3. 同时生成HttpSession对象对应的Cookie对象,并且Cookie对象的name是jsessionidCookie的value是32位长度的字符串(jsessionid=xxxx)
  4. 服务器将Cookie的value和HttpSession对象绑定到session列表
  5. 服务器将Cookie完整发送给浏览器客户端
  6. 浏览器客户端将Cookie保存到缓存
  7. 只要浏览器不关闭,Cookie就不会消失
  8. 再次发送请求的时候,会自动提交缓存中当的Cookie
  9. 服务器接收到Cookie,验证该Cookie的name是否是jsessionid,然后获取该Cookie的value
  10. 通过Cookie的value去session列表中检索对应的HttpSession对象

要注意的是:
当浏览器关闭之后,缓存中的cookie消失,这样客户端下次再访问服务器的时候就无法获取到服务器端的session对象了。这就意味着会话已经结束,但是并不代表服务器端的session对象马上被回收session对象仍然在session列表中存储当长时间没有用户访问这个session对象了,我们称作session超时,此时web服务器才会回收session对象
1、浏览器关闭之后,服务器对应的session对象会被销毁吗?

浏览器关闭之后,服务器不会销毁session对象
因为B/S架构的系统基于HTTP协议,而HTTP协议是一种无连接/无状态的协议
那什么是无连接/无状态呢?
请求的瞬间浏览器和服务器之间的通道是打开的,请求响应结束之后,通道关闭
这样做的目的是降低服务器的压力

2、session对象在什么时候被销毁?

当很长一段时间(这个时间可以配置)没有用户再访问session对象,此时session对象超时,web服务器会自动回收session对象
可以配置这个超时时间,在web.xml文件中,其默认是30分钟

 
<session-config> <session-timeout>120</session-timeout> </session-config>

3、那什么情况下才是一次会话结束呢?

  1. 浏览器关闭,缓存中的Cookie消失,会话不一定结束,因为服务器端session对象还没有被销毁。这时我们可以通过URL重写机制继承访问session对象。
  2. 浏览器没关闭,但是由于长时间没有访问web服务器,服务器判定session超时,将session对象销毁。此时浏览器虽然没有关闭,但是这次会话已经结束。
  3. session对象所关联的这个Cookie的name有点特殊,这个name必须是jsessionid全部小写,这时HTTP协议规定的
  4. 浏览器禁用了Cookie,可以采用URL重写机制(这样编码的代价比较大,所以一般网站都是不允许禁用Cookie的)
  5. 怎么重写URL:http://ip:port/webapp/servlet/accessSys;jsessionid=xxxxxx

关于javax.servlet.http.HttpSession接口中常用方法:
获取session对象,如果获取不到则新建

request.getSession(true); request.getSession();

获取session对象,如果获取不到则返回null

request.getSession(false);

向session中存储一个数据

void setAttribute(String name, Object value);

从session范围中取出数据

Object getAttribute(String name);

从session范围中删除数据

void removeAttribute(String name);

销毁session

void invalidate();

ServletContext、HttpSession、HttpServletRequest接口的对比:
1、以上都是范围对象:
ServletContext application; 是应用范围
HttpSession session; 是会话范围
HttpServletRequest request; 是请求范围
2、三个范围的排序:
application > session > request
相同点:都可以用来传递数据,都有相同的存取数据方法

存:session.setAttribute(“name”,ObjectValue);
取:Object value = session.getAttribute(“name”);
删: session.removeAttribute(“name”);
不同点:

ServletContext(application) 是Servlet上下文对象,在服务器启动阶段解析web.xml文件创建ServletContext对象,在同一个webabb中所有的Servlet对象共享同一个ServletContext对象。该对象一旦创建不会被销毁,除非服务器停掉。 所以尽量不要往这个对象中存放大数据,因为这是一个所有用户共享的空间,往该对象中存储的数据在多线程环境下涉及到修改操作的话注意线程安全问题。一般存储在该对象中的数据首先是所有用户共享的,不会被修改的,少量数据。ServletContext对象传递数据可以跨Servlet、跨请求、跨用户(跨会话)传递数据。

HttpSession(session) 是会话对象,每一个用户都有一个这样的对象,存储在该对象中的数据一般都是该用户专属的数据,例如购物车对象可以存储在session中,HttpSession对象传递数据可以跨Servlet、跨请求(这些请求必须属于同一个会话)、但是不能跨用户传递数据。

HttpServletRequest(request) 是请求对象,一次请求一个对象,每一次请求都会新建一个请求对象,是一个请求级别的对象,存储该对象中的数据一般都是请求级别的数据,一次请求之后这个数据就不再使用的数据可以存储在该对象中,HttpServletRequest对象传递数据可以跨Servlet,但是不能跨请求,更不能跨用户传递数据。

3、使用原则:由小到大尝试,优先使用小范围(考虑原则:request< session < application)

例如:登录成功之后,已经登录的状态需要保存起来,可以将登录成功的这个状态保存到session对象中。登录成功状态不能保存到request范围中,因为一次请求对应一个新的request对象登录成功状态也不能保存到application范围中,因为登录成功状态是属于会话级别的,不能所有用户共享。