Servlet Session 处理
- HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录;
- 一般有以下3种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:
① Cookies
一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别,但是 很多浏览器不支持 cookie,因此不建议使用这种方式来维持 session 会话。
② 隐藏的表单字段
一个 Web 服务器可以发送一个隐藏的 HTML 表单字段,以及一个唯一的 session 会话 ID,如下所示:<input type="hidden" name="sessionid" value="12345">该条目意味着,当表单被提交时,指定的名称和值会被自动包含在 GET 或 POST 数据中。每次当 Web 浏览器发送回请求时,session_id 值可以用于保持不同的 Web 浏览器的跟踪。这可能是一种保持 session 会话跟踪的有效方式,但是点击常规的超文本链接(<A href...>)不会导致表单提交,因此隐藏的表单字段也不支持常规的 session 会话跟踪。③ URL 重写
可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。例如,http://w3cschool.cc/file.htm;sessionid=12345,session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。URL 重写是一种更好的维持 session 会话的方式,它在浏览器不支持 cookie 时能够很好地工作,但是它的缺点是会动态生成每个 URL 来为页面分配一个 session 会话 ID,即使是在很简单的静态 HTML 页面中也会如此。
HttpSession 对象处理 Session
- HttpSession 接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式;
- Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求;
可以通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象:
HttpSession session = request.getSession();
HttpSession中主要的API如下:
String getId()
|
返回一个包含分配给该 session 会话的唯一标识符的字符串。
|
Object getAttribute(String name)
|
返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null
|
Enumeration getAttributeNames()
|
返回 String 对象的Enumeration,String 对象包含所有绑定到该 session 会话的对象的名称。
|
void removeAttribute(String name) |
从该 session 会话移除指定名称的对象。
|
void setAttribute(String name, Object value)
|
使用指定的名称绑定一个对象到该 session 会话
|
long getCreationTime()
| 返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。 |
long getLastAccessedTime()
|
返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
|
int getMaxInactiveInterval()
|
返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位
|
void setMaxInactiveInterval(int interval)
|
在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。
|
void invalidate()
| 指示该 session 会话无效,并解除绑定到它上面的任何对象。 |
boolean isNew()
|
如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
|
以下是一个关于Session追踪的示例:
利用Session实现同一个会话中对访问次数进行计数的功能
public class Demo extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IoException{
//创建session(参数true表示在页面不存在Session时创建该Session)
HttpSession session = request.getSession(true);
//获取一些session信息
String sessionId = session.getId();
SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String createTime = format1.format(new Date(session.getCreationTime()));
String lastAccessTime = format1.format(new Date(session.getLastAccessTime()));
//计算vistCount,并重新写入到session中
int vistCount = 0;
if(!session.isNew()) //当session不是首次产生时,开始计数
vistCount = (Integer)session.getAttribute("vistCount") + 1;
session.setAttribute("vistCount",vistCount);
//返回响应正文
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html><html><body>");
out.println("<p>session id:"+sessionId+"</p>");
out.println("<p>create time:"+createTime+"</p>");
out.println("<p>last access time:"+lastAccessTime+"</p>");
out.println("<p>vist count"+vistCount+"</p>");
out.println("</body></html>");
}
}