一、什么是会话
用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称为会话
二、 会话流程
Web服务器在一段时间内通常会接收到多个客户端浏览器的访问请求,Web服务器首先要从大量的请求消息中区分出哪些请求消息属于同一个会话,即识别出来自同一个浏览器的访问请求。为了区分请求,需要浏览器对其自身发出的每个请求消息进行标识,属于同一个会话中的请求消息均附带同样的标识ID,而不同的会话请求消息则附带不同的标识ID,这个标识ID通常被称为会话ID(SessionID)。会话跟踪技术就是通过SessionlD来唯一标识客户端,其工作流程如下:
(1)客户端第一次访问Web服务器时,服务器为该客户端创建一个会话,并产生唯一的 SessionIDa
(2)服务器响应客户端,将SessionID回传给客户端。
(3)客户端再次向Web服务器发出请求时,附带SessionID。服务器根据SessionID来唯一标识客户端,如图
servlet如下
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/web")
public class http extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应内容的类型是可以文本或HTML类型,编码是utf-8
resp.setContentType("text/html;charset=utf-8");
//获取sessionID
String id = req.getSession().getId();
resp.getWriter().print("产生了一次会话,sessionID为:"+id);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
运行如下
三、保存会话的二种技术
3.1 cookie 客户端技术 (响应,请求)
3.1.1 cookie 常用方法
Cookie[] cookies = req.getCookies();//获取Cookie
cookie.getName(); //获取cookie中的key
cookie.getValue(); //获取cookie中的value
new Cookie("name","张三"); //新建一个cookie
cookie.setMaxAge(24*60*60); //设置Cookie的有效期,单位秒
cookie.getMaxAge(); //获取Cookie的有效期,单位秒
resp.addCookie(cookie); //响应给客户端一个cookie
3.1.2 cookie的有效期
maxAge() 方法参数值为正数,表示cookie会在多少秒之后,无论用户关闭浏览器或是电脑,
只要在cookie失效前登录网站,cookie还是有效的.
下述代码片段中的Cookie有效期一个月。
Cookie cookie = new Cookie("username", "admin");
cookie.setMaxAge(30*24*60*60);
resp.addCookie(cookie);
maxAge() 方法参数值为负数,关闭浏览器后,cookie失效,cookie默认的maxAge值为-1。
下述代码片段关闭浏览器后cookie失效
Cookie cookie = new Cookie("username", "admin");
resp.addCookie(cookie);
- 一个Cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
- Cookie大小有限制4kb;
- 300个cookie浏览器上限
3.1.3 代码演示
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应内容的类型是可以文本或HTML类型,编码是utf-8
resp.setContentType("text/html;charset=utf-8");
//创建一个cookie
Cookie cookie = new Cookie("cookName", "cookieServlet");
//设置Cookie的有效期为一分钟
cookie.setMaxAge(60);
//向响应中添加 cookie
resp.addCookie(cookie);
//获取Cookie数组
Cookie[] cookies = req.getCookies();
//cookies是否存在
if(cookies == null) {
resp.getWriter().print("<html><h2>这是您第一次访问</h2></html>");
}else {
for(int i=0;i<cookies.length;i++) {
resp.getWriter().print("Cookie名称:"+cookies[i].getName()+",Cookie值:"+cookies[i].getValue());
resp.getWriter().print("<html><br></html>");
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}
第一次访问如下
第二次访问如下
3.2 session 服务器技术
3.2.1 session简介
session是另一中记录客户状态的机制,与cookie不同的是 session数据保存在服务器中,而不是保存在客户端浏览器中。
session运行在服务器端,当客户端第一次访问服务器时,可以将客户的登录信息保存在服务器端。
当客户端第一次请求服务器时,服务器会为每个客户端创建一个独享的session对象,用于跟踪用户的状态。
同时,为session对象分配一个唯一标识sessionId。
3.2.2 session常用方法
方法名 | 说明 |
---|---|
public void setAttribute(String name,Object value) | 根据指定名称将对象保存至会话 |
public Object getAttribute(String name) | 根据指定名称从会话中获取某个属性的值 |
public void removeAttribute(String name) | 从会话中移除指定名称的属性 |
public String getid() | 返回Sessoin的ID。该ID由服务器创建,不会重复 |
public boolean isNew() | 判断当前会话是否是新建的会话 |
public void invalidate() | 使当前Session失效 |
public void setMaxInactiveInterval(int seconds) | 设置Session的有效时间,单位 为秒 |
pulbic int getMaxInactiveInterval() | 返回Session的有效时间,单位 为秒 |
方法名 | 说明 |
---|---|
public HttpSession getSession() | 调用此方法时,容器会先检查客户端先前发送的请求是否建立过HTTP会话,如果没有,容器会创建一个新会话,并赋予一个唯一的会话ID;如果有,则容器会根据客户请求中的会话ID找到相匹配的会话 |
pulbic HttpSession getSession(boolean flag) | 此方法的flag用于指定是否有必要创建一个会话。调用getSession(false)时,如果客户端先前没有建立会话,则此方法返回null |
3.2.3 代码示范
index.jsp如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
#app {
/* background: pink; */
width: 400px;
margin:auto;
}
h2 {
text-align:center;
}
</style>
</head>
<%@ page import="java.io.*,java.util.*" %>
<body>
<%
//返回session创建时间
Date createTime = new Date(session.getCreationTime());
Date lastAccessTime = new Date(session.getLastAccessedTime());
/* String title = "Welcone Back to my website"; */
//访问次数
Integer visitCount = 0;
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("ABCD");
//检查是否为一个新的会话
if(session.isNew()) {
/* title = "Welcome to my website"; */
//用户ID
session.setAttribute(userIDKey,userID);
//
session.setAttribute(visitCountKey,visitCount);
}
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount = visitCount+1;
userID = (String)session.getAttribute(userIDKey);
session.setAttribute(visitCountKey,visitCount);
%>
<div id="app">
<h2>Session会话跟踪技术</h2>
<table border=1>
<tr>
<th>会话信息</th>
<th>值</th>
</tr>
<tr>
<td>sessionID</td>
<td><% out.print(session.getId()); %></td>
</tr>
<tr>
<td>创建时间</td>
<td><% out.print(createTime); %></td>
</tr>
<tr>
<td>最近一次访问时间</td>
<td><% out.print(lastAccessTime); %></td>
</tr>
<tr>
<td>用户ID</td>
<td><% out.print(userID); %></td>
</tr>
<tr>
<td>访问次数</td>
<td><% out.print(visitCount); %></td>
</tr>
</table>
</div>
</body>
</html>
运行如下
3.3 Session与Cookie的区别
1.从存取方式上比较
Cookie 中只能保存字符串。而 Sessim中可以存取任何类型的数据。
2.从有效期上比较
Session 无法实现信息永久有效保存的效果。使用URL重写也无法实现。而Cookie可以,设置Cookie的MaxAge 属性为一个很大的数字或设置Integer.MAX_VALUE即可。
3.从服务器负担上比较
Session 保存在服务器上,每个用户都会产生一个Session。如果并发访问的用户非常多,则会产生多个Session,消耗大量的服务器内存,严重影响服务器的性能。而Cookie保存在客户端,不占用服务器端资源。如果并发浏览器的用户非常多,则Cookie 是很好的选择。
4.从浏览器支持上比较
Cookie 是需要客户端浏览器支持的。如果客户端禁用了Cookie 或不支持Cookie,则会话跟踪会失效。
Cookie可以设置为所有浏览器(心须为同一浏览器)窗口有效, Session只能在本浏览器窗口及其子窗口有效。如果两个浏览器窗口互不干涉,或为同一浏览器的两个不同的进程,它们将使用不同的 Session。
5.从安全性上比较
Cookie 是服务器保存在客户端的一组数据,如果这些数据未经加密处理,则都是以明文保存的,且这些数据可以在客户机上查找到。如果 Cookie 中存放了一些重要的数据,且这些数据没有进行加密处理,那么一旦客户机被恶意攻击,则Cookie中的数据会很容易被窃取,从而带来严重的安全隐患。而Session的信息保存在服务器端,在安全性上要比Cookie高很多。