当用户通过浏览器访问 web 应用时,通常情况下,服务器需要对用户的状态进行跟踪。例 如,用户在网站结算商品时,Web 服务器必须根据请求用户的身份,找到该用户所购买的 商品。在 Web 开发中,服务器跟踪用户信息的技术称为会话技术
从打开一个浏览器访问某个站点,到关闭这个浏览器的整个过程,成为一次会话
- 会话技术分为 Cookie 和 Session
Cookie:数据存储在客户端本地,减少服务器端的存储的压力,安全性不好,客户 端可以清除 cookie
Session:将数据存储到服务器端,安全性相对好,但是会增加服务器的压力
Cookie 技术是将用户的数据存储到客户端的技术,其存储格式是一个键和一个值构成的,随 着服务器端的响应发送给客户端浏览器。然后客户端浏览器会把 Cookie 保存起来,当下一 次再访问服务器时把 Cookie 再发送给服务器。
我们主要学习的是
1. 服务器端怎样将一个 Cookie 发送到客户端
2. 服务器端怎样接受客户端携带的 Cookie
为了封装 Cookie 信息,在 Servlet API 中提供了一个 Javax. servlet.ht. Cookie 类,该类包含生成 Cookie 信息和提取 Cookie 信息各个属性的方法
Cookie 类只有一个构造方法
public Cookie(String name, String value)
参数 name 指定 Cookie 名称,value 指定 Cookie 的值
注意:名称不能更改,值可以为任何值。
上面的数据只是 HTTP 的 Cookie 规范,但在浏览器大战的今天,一些浏览器为了打败对手, 为了展现自己的能力,可能对 Cookie 规范“扩展”了一些,例如每个 Cookie 的大小为 8KB, 最多可保存 500 个 Cookie 等
Cookie 是通过 HTTP 请求和响应头在客户端和服务器端传递的
Cookie:请求头,客户端发送给服务器端
Cookie: a=A; b=B; c=C。即多个 Cookie 用分号离开;
Set-Cookie:响应头,服务器端发送给客户端;一个 Cookie 对象一个 Set-Cookie:
Set-Cookie: a=A
Set-Cookie: b=B
Set-Cookie: c=C
如果服务器端发送重复的 Cookie 那么会覆盖原有的 Cookie, 例如客户端的第一个请求服务器端发送的 Cookie 是:Set-Cookie: a=A;第二请求服务器端发 送的是:Set-Cookie:a=AA,那么客户端只留下一个 Cookie,即:a=AA。
设置 Cookie 的有效路径(携带路径)
cookie.setPath(String path);
注意:如果不设置携带路径,那么该 cookie 信息会在访问产生该 cookie 的 web 资 源所在的路径都携带 cookie 信息
示例: cookie.setPath(“/Cookie”);
表示访问 Cookie 应用中的任何资源都携带 cookie
cookie.setPath(“/Cookie/helloCookieServlet”);
表示访问 Cookie 中的 helloCookieServlet 时才携带 cookie 信息
向客户端发送 cookie:
response.addCookie(Cookie cookie);
删除客户端的 cookie
如果想删除客户端的已经存储的 cookie 信息,那么就使用同名同路径的持久化时间为 0 的 cookie 进行覆盖即可
cookie 信息是以请求头的方式发送到服务器端的:
1. 通过 request 获得所有的
Cookie Cookie[] cookies = request.getCookies();
Cookie 技术可以将用户的信息保存在各自的浏览器中,并且可以在多次请求下实现数据的共 享。但是,如果传递的信息比较多,使用 Cookie 技术显然会增大服务器端程序处理的难度 这时,可以使用 Session 实现, Session 是一种将会话数据保存到服务器端的技术。
为了区分不同用户的 Session 数据,客户端每次向服务器请求时都会带着一个 SessionID 的标 记,通常情况下,SessionID 是借助 Cookie 技术来传递值的。
Session 是与每一个请求消息紧密相关的,为此,HttpServletRequest 定义了用于获取 Session 对象的 getSession()方法,有两个重载
public HttpSession getSession(boolean create);
public HttpSession getSession();
区别是根据传入的参数来判断是否创建新的 HttpSession 对象,如果为 true,则在相关的 HttpSession对象不存在时创建并返回新的HttpSession对象,负责不创建新的 HttpSession 对 象
获得 Session 对象
HttpSession session = request.getSession();
此方法会获得专属于当前会话的 Session 对象,如果服务器端没有该会话的 Session 对象会 创建一个新的 Session 返回,如果已经有了属于该会话的 Session 直接将已有的 Session 返 回(实质就是根据 JSESSIONID 判断该客户端是否在服务器上已经存在 session 了)
向 session 中存取数据(session 也是一个域对象)
session.setAttribute(“username”, “wangwu”);
public class SessionOne extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
HttpSession session = request.getSession();
session.setAttribute("username", "wangwu");
String id = session.getId();
Cookie cookie = new Cookie("JSESSIONID", id);
cookie.setPath("/");
cookie.setMaxAge(60*10);
response.addCookie(cookie);
response.getWriter().write("JSESIONID:"+id);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
public class SessionTwo extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
HttpSession session = request.getSession();
Object attribute = session.getAttribute("username");
response.getWriter().write(attribute+"");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
Session 对象的生命周期(面试题/笔试题)
创建:第一次执行 request.getSession()时创建
销毁:
- 服务器(非正常)关闭时
- session 过期/失效(默认 30 分钟)
- 手动销毁 session session.invalidate();
时间的起算点,从何时开始计算 30 分钟?
从不操作服务器端的资源开始计时 也可以在工程的 web.xml 中进行配置
30
Session 作用范围 默认在一次会话中,也就是说在,一次会话中任何资源公用一个 session 对象