HTTP是一种基于请求与响应的无状态协议。
无状态的意思是:
- 协议对于事物处理没有记忆能力,服务器不能自动维护用户的上下文信息,无法保存用户状态;
- 每次请求都是独立的,不会受到前面请求的影响,也不会影响后面的请求。
通常情况下,用户通过浏览器访问Web应用时,服务器都需要保存和跟踪用户的状态。而无状态协议HTTP是无法满足这一需求的。
**会话技术(Cookie和Session)**就用于解决此问题。
1、会话技术简介
从打开浏览器访问某个网站,到关闭浏览器的过程,称为一次会话。会话技术是指在会话中,帮助服务器记录用户状态和数据的技术。
常用会话技术就是Cookie和Session,其中Cookie是客户端会话技术,Session是服务器会话技术。
2、Cookie
Cookie,本意是“饼干“,它实际上是服务器发送给浏览器的小段文本信息,存储在客户端浏览器的内存中或硬盘上。当浏览器保存了Cookie后,每次访问服务器,都会在HTTP请求头中将这个Cookie回传给服务器。
Cookie的创建
javax.servlet.http包中定义了一个Cookie类,利用它的带参构造方法,可以创建Cookie对象。
Cookie c = new Cookie("url","www.baidu.com");
“url”是Cookie的名称,参数name;“www.baidu.com”是Cookie的值参数value。
Cookie的分类:
- 会话级别Cookie(默认):Cookie保存在浏览器的内存中,浏览器关闭则Cookie失效。
- 持久的Cookie:Cookie以文本文件的形式保存在硬盘上。
因为Cookie默认情况下是浏览器一旦关闭,Cookie就失效。但是正如我们关闭浏览器后再次打开浏览器进入b站,我们仍然是已登录状态,有很多地方需要用到持久的Cookie。设定持久Cookie的方法是:调用setMaxAge(int maxAge)方法设置最大有效时间,以秒为单位。
Cookie的工作流程:
- 客户端浏览器访问服务器,服务器通过在HTTP响应中增加Set-Cookie字段,将数据信息发送给浏览器;
- 浏览器将Cookie保存在内存中或硬盘上;
- 当浏览器再次访问服务器时,浏览器通过在HTTP请求消息中增加Cookie请求头字段,将Cookie回传给Web服务器。服务器根据Cookie信息跟踪客户端的状态。
Cookie入门实例
实例预计要实现的效果是,当用户第一次访问时,输出:这是您第一次访问本站;当用户不是第一次访问时,输出:您上一次访问的时间是:(上一次访问的具体时间)。
package com.chen.servlet;
import javax.servlet.ServletException;
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;
import java.util.Date;
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器,告诉你,你来的时间,把这个时间,封装成为一个信件,你下次带来,我就知道你来了
//解决中文乱码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
//Cookie 服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个
//判断Cookie是否存在
if (cookies != null){
//如果存在怎么办
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("lastLoginTime")){
//获取cookie的值
long l = Long.parseLong(cookie.getValue());
Date date = new Date(l);
out.write(date.toString());
}
if (cookie.getName().equals("name")){
out.write(cookie.getValue());
}
}
}else{
out.write("这是您第一次访问本站");
}
//服务端给客户端一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//cookie有效期为1天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3、Session
当浏览器访问Web服务器的资源时,服务器可以为每个用户浏览器创建一个Session对象,每个浏览器独占一个Session对象。独占的方法是服务器给每个浏览器一个唯一仅有的SessionID,就这好比是大学学校给每一位学生的学号一样。
由于每个浏览器独占一个Session,所以用户在访问服务器的资源时,可以把数据保存在各自的Session中,当用户再次访问该服务器中的其他资源时,其它资源可以从Session中取出数据,为用户服务。
Session的工作原理:
Session的实现离不开客户端浏览器和Cookie的支持。我们已经知道Cookie技术是服务器把数据以name-value的形式发给浏览器,让浏览器来保存,而Session则是使用了Cookie技术,只不过留给浏览器保存的只有SessionID,其他的数据都是服务器负责保存了。
Session和Cookie技术之间的区别,也可以看出两者间安全性的区别:Cookie是明文传递的,容易泄露用户信息,安全性不高;而Session则安全性较高。尽管如此,Cookie仍然应用广泛,因为Cookie效率更高,对于一些不是很重要的信息数据,用Cookie也无妨。
Session的工作原理如下:
- 当客户端第一次请求会话时,服务器会创建一个Session对象,并为这个Session对象分配一个唯一的SessionID;
- 服务器将SessionID以Cookie(name=“JSESSONID”,value为SessionID的值)技术的形式发送给客户端浏览器;
- 当客户端浏览器再次发送HTTP请求时,会将携带SessionID的Cookie一起发送给服务器;
- 服务器从请求中读取SessionID,然后根据SessionID找到对应的Session对象。
Session的创建
Session对象由服务器创建,通过HttpServletRequest.getSession()方法获得HttpSession对象,例如:
HttpSession session = req.getSession();
Session入门实例
package com.chen.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name","秦疆");
//获取Session的ID
String id = session.getId();
//判断Session是否是新创建
if(session.isNew()){
resp.getWriter().write("session创建成功,ID:"+id);
}else{
resp.getWriter().write("session已经在服务器中存在了,ID:"+id);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Session对象何时创建?
Session对象在容器第一次调用req.getSession()方法时创建。值得注意的是,当客户端访问的是静态资源时,服务器不会创建Session对象。
Session对象被销毁的3种情况:
- Session过期了;
- 调用session.invalidate()方法,手动销毁Session;
- 服务器关闭或者应用被卸载了。
Session的默认过期时间是30分钟,指的是Session从没有被使用的时间算起。我们可以通过以下两种方式设置过期时间。
第一种方法:在web.xml文件中使用< session-config >元素:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!--设置session的过期时间,单位是分钟-->
<session-config>
<session-timeout>10</session-timeout>
</session-config>
</web-app>
如果设置的值为零或者负数,意思是永久不会过期
第二种方法:调用setMaxInactiveInterval()方法
通过调用 session.setMaxInactiveInterval(int interval) 设置过期时间,以秒为单位,零和负数表示会话永远不会过期,代码如下。
req.getSession().setMaxInactiveInterval(100);
4、Cookie vs Session
Cookie和Session都是会话技术,都能帮助服务器保存和跟踪用户状态,但两者也存在差异:
- 存储位置不同。Cookie将数据存放在客户端浏览器的内存中或硬盘上;Session将数据存储在服务器端。
- 大小和数量限制不同。Cookie的大小和数量是有限制的。
- 存放数据的类型不同。Cookie中保存的是字符串;Session保存的是对象。
- 安全性不同。Session更安全。
- 对服务器造成的压力不同。Session会占用服务器大量资源