Servlet 中的 Cookie 、 Session 和 ServletContext

时间:2022-07-30 17:06:33

1、Cookie

核心业务逻辑应该使用更加稳靠的 Session,而使用 Cookie 是不可靠的,因为 Cookie 是可以被禁用的,也可以被清除,但我们可以依靠 Cookie 实现某些不是很重要的业务逻辑。

Cookie 分为两种,一种是依赖于窗口的和子窗口,一旦浏览器窗口退出(进程退出),则 Cookie 被清除。另一种 Cookie 是有生命周期的,在规定的时间后才会被清除。若不规定 Cookie 的最大生命周期,则属于前种依赖于窗口的 Cookie。


setMaxAge

 
public void setMaxAge(int expiry)
Sets the maximum age of the cookie in seconds.

A positive value indicates that the cookie will expire after that many seconds have passed. Note that the value is the maximum age when the cookie will expire, not the cookie's current age.

A negative value means that the cookie is not stored persistently and will be deleted when the Web browser exits. A zero value causes the cookie to be deleted.

 

Parameters:
expiry - an integer specifying the maximum age of the cookie in seconds; if negative, means the cookie is not stored; if zero, deletes the cookie
See Also:
getMaxAge()

创建 Cookie 的代码如下:

   1:  protected void doPost(HttpServletRequest req, HttpServletResponse resp)
   2:          throws ServletException, IOException {
   3:      req.setCharacterEncoding("gb2312");
   4:      resp.setContentType("text/html;charset=gb2312");
   5:      for(int i=0;i<3;i++){
   6:          Cookie cookie=new Cookie("SessionCookie"+i, "SessionCookieValue"+i);//依赖窗口的 Cookie
   7:          resp.addCookie(cookie);
   8:          cookie=new Cookie("Cookie"+i, "CookieValue"+i);//有生命周期的 Cookie
   9:          cookie.setMaxAge(120);
  10:          resp.addCookie(cookie);
  11:      }
  12:  }

创建的第一个 Cookie 会在浏览器进程结束后立即被清除,而第二个 Cookie 被清除的时间则是浏览器结束进程与2分钟之间的一个较大值。

从浏览器读取 Cookie 的代码如下:

   1:  Cookie[] cookies = req.getCookies();
   2:  for(Cookie cookie:cookies){
   3:      resp.getWriter().println(cookie.getName()+"
"
);
   4:      resp.getWriter().println(cookie.getValue()+"
"
);
   5:  }
注意到,由一个 Servlet 设置的 Cookie 是可以被其同路径或子路径读取的。

2、Session

Session 与 Cookie 的最大不同时 Session 将信息存储在服务器了,所以 Session 的大小、类型都将不受限制,而且同一个 Session 可以被不论子路径或父路径访问。

获取和创建 Session 的代码如下:

 
   1:  HttpSession hs = req.getSession(true);//获取 Session ,参数 true 表示如果没有 Session 则创建一个 Session
   2:  hs.setAttribute("name", new Date(System.currentTimeMillis()));//给 Session 赋值
   3:  resp.getWriter().println(hs.getId() + "
"
);//获得此 Session 的 ID
   4:  resp.getWriter().println(new Date(hs.getCreationTime()) + "
"
);//获取 Session 的创建日期
   5:  resp.getWriter().println(new Date(hs.getLastAccessedTime()) + "
"
);//获取 Session 的最后一次访问日期
   6:  resp.getWriter().println(hs.getAttribute("name") + "
"
);//获取 Session 的值

以上代码会将 Session 的 ID 存储在浏览器的 Cookie 中,这个也是不安全的,因为 Cookie 是可以被禁止和清除的。对此我们可以使用 URL 重写来解决问题,是的不论 Cookie 是否可用,Session 都是可用的:

   1:  HttpSession hs = req.getSession(true);//获取 Session ,参数 true 表示如果没有 Session 则创建一个 Session
   2:  resp.getWriter().println("">Click me
"
);//重写 Session ID 到 URL
   3:  hs.setAttribute("name", new Date(System.currentTimeMillis()));//给 Session 赋值
   4:  resp.getWriter().println(hs.getId() + "
"
);//获得此 Session 的 ID
   5:  resp.getWriter().println(new Date(hs.getCreationTime()) + "
"
);//获取 Session 的创建日期
   6:  resp.getWriter().println(new Date(hs.getLastAccessedTime()) + "
"
);//获取 Session 的最后一次访问日期
   7:  resp.getWriter().println(hs.getAttribute("name") + "
"
);//获取 Session 的值

但是 Session 也是有生命周期的,以减少服务器资源消耗,这个生命周期可以在服务器中配置,在 Tomcat 中使用 conf/web.xml 配置,修改下面代码即可:

   1:  
   
   
   2:  
   
   
   3:  
   
   
   4:   
   5:  <session-config>
   6:      <session-timeout>30
   
   session-timeout>
   7:  
   
   session-config>

3、ServletContext

ServletContext 是指 Servlet 运行容器,可以参见如下 API :


getServletContext

 
public ServletContext getServletContext()
Returns a reference to the ServletContext in which this servlet is running. See ServletConfig.getServletContext().

This method is supplied for convenience. It gets the context from the servlet's ServletConfig object.

Specified by:
getServletContext in interface ServletConfig
Returns:
ServletContext the ServletContext object passed to this servlet by the init method
See Also:
ServletContext

我们可以在 ServletContext 中放入一写全局参数。参加如下代码实现了计算访问量的功能:

 
   1:  PrintWriter out = resp.getWriter();
   2:  out.println("");
   3:  ServletContext sc = this.getServletContext();
   4:  Integer count = (Integer)sc.getAttribute("count");
   5:  if(count==null){
   6:      count = new Integer(1);
   7:      out.println("");
   8:      out.println("");
   9:      out.println(");
  10:      out.println("alert('恭喜!您是我站的第一个访问者!');");
  11:      out.println("");
  12:      out.println("恭喜!你是我站第"+count+"个访问者!!豪礼相送!!详情免费咨询 10086.");
  13:  }else{
  14:      count++;
  15:      out.println("你是第"+count+"个访问者。");
  16:  }
  17:  sc.setAttribute("count", count);
  18:  out.println("");
  19:  out.close();