Java登陆第三十天——Cookie和Session
会话
一次会话是客户端与服务端的连接建立与结束,在这次会话中可以有多次请求与响应。
HTTP是一种无状态协议
HTTP协议不对请求和响应之间的通信状态进行保存,以至于尽管是同一个客户端,但它的每次会话都会被当作一次新的会话
(简而言之就是服务端不会认识客户端)
有的时候,我们需要保存客户端的信息。
- 对于登陆功能来说,保存客户端信息,可以避免客户端每访问都需要登陆一次
至此,会话管理诞生。
会话管理
会话管理分为Cookie和Session
-
Cookie:
- Cookie是在客户端保留少量数据的技术,主要通过响应头向客户端响应一些客户端要保留的信息
-
Session:
- session是在服务端保留更多数据的技术,主要通过HttpSession对象保存一些和客户端相关的信息
Cookie
Cookie是一种客户端会话技术,数据会保存在客户端之中。
HttpServletResponse方法 | 描述 |
---|---|
void addCookie(Cookie var1) | 向客户端添加响应报文头 |
-
Cookie是键值对类型的数据。
-
可以创建若干个Cookie对象,并通过addCookie()方法响应给客户端。
- (Tomcat会自动把Cookie对象转为set-cookie响应头)
-
客户端接收到set-cookie响应头后,会在下次请求资源时,以cookie请求头的方式携带Cookie对象
Cookie类常用方法
方法 | 描述 |
---|---|
String getName() | 获取Cookie的键 |
String getValue() | 获取Cookie的值 |
void setMaxAge(int expiry) | 设置Cookie的存活时间(秒) |
void setPath(String uri) | 设置Cookie仅生效地址 |
-
仅生效地址:
- 在该地址中才有效,其他的地址,该Cookie对象不会在请求头中。
试验先访问Test5B栗子
TestServlet5
@WebServlet("/Test5")
public class TestServlet5 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//给客户端响应两个Cookie
resp.addCookie(new Cookie("keyA","valueA"));
resp.addCookie(new Cookie("keyB","valueB"));
}
}
TestServlet5B
@WebServlet("/Test5B")
public class TestServlet5B extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//cookie可能为多个,所以返回值是Cookie数组
Cookie[] cookies = req.getCookies();
if (cookies!=null){
for (Cookie cookie : cookies) {
String value = cookie.getValue();
System.out.println(value);
}
}else {
System.out.println("没有Cookie");
}
}
}
客户端请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B
//控制台输出,先以无Cookie访问
没有Cookie
试验先Test5再访问Test5B
先请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5
并查看响应头
再请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B
//控制台输出
valueA
valueB
Cookie的时效性
Cookie根据存活时间的长度被分为:会话级Cookie;持久化Cookie
会话级Cookie | 持久化Cookie |
---|---|
服务端没指定Cookie存活时间 | 服务端指定了Cookie存活时间 |
Cookie存在内存中 | Cookie存在硬盘中 |
Cookie在客户端关闭后就会自动释放 | Cookie在硬盘中存活时间由服务器指定 |
Cookie到达指定时间会被释放 |
一次会话可以包含多次请求与响应。
关闭客户端后,再重新连接服务端,会被视作一次新的会话。
Session
Session是一种服务端会话技术,数据保存在服务端之中。
HttpServletRequest方法 | 描述 |
---|---|
HttpSession getSession() | 获取Session对象 |
-
服务端会为每个请求的客户端创建一个新的Session对象
- 同时会把Session对象的id,以Cookie形式保存在JSESSIONID中
-
客户端创建完Session后,客户端会收到一个特殊的响应头set-cookie。(JSESSIONID:Session对象的id)
-
客户端下次访问服务端,携带的Cookie中就包含JSESSIONID,服务端会根据JSESSIONID的值找到对应的Session对象
-
Session是域对象(下一篇文章介绍)
Session接口常用方法
方法 | 描述 |
---|---|
String getId() | 获取Session对象的id |
boolean isNew() | Session是否是新生成的 |
void setAttribute(String var1, Object var2) | 往Session对象里存储键值对数据 |
Object getAttribute(String var1) | 获取Session对象里存储的值 |
void setMaxInactiveInterval(int var1) | 设置Session存货时间(单位秒) |
void invalidate() | 设置Session直接死亡 |
栗子
TestServlet5
@WebServlet("/Test5")
public class TestServlet5 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
System.out.println(session.getId());
System.out.println(session.isNew());//输出Session的ID和新旧 T新F旧
session.setAttribute("keyA","valueA");
}
}
TestServlet5B
@WebServlet("/Test5B")
public class TestServlet5B extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
//输出Session的ID和新旧 T新F旧
System.out.println(session.getId());
System.out.println(session.isNew());
System.out.println(session.getAttribute("keyA"));
}
}
客户端请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B
//控制台输出,先以无Session访问
84C99AA919BF34E18E3796AA3DEF807C
true
null
试验先Test5再访问Test5B
重启服务端
先请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5
//控制台输出,先以无Session访问
DEFB19BBE3D9A688F015E91B36528677
true
再请求URL:http://localhost:8080/JavaWeb_war_exploded/Test5B
//控制台输出
DEFB19BBE3D9A688F015E91B36528677
false
valueA
因为Session是在服务端内保存,重启才能保证第二次正常按预期运行。