一、介绍:
1、定义:
(1)session是服务端存储的一个对象,主要用来存储所有访问过该服务端的客户端的用户信息(也可以存储其他信息),从而实现保持用户会话状态。但是服务器重启时,内存会被销毁,存储的用户信息也就消失了。
(2)session是浏览器和服务器建立起来的,且浏览器和服务器之间的一次对话只有一个session对象。关闭浏览器或者手动关闭session也会销毁session,且换一个浏览器session和之前也是不一样的。
2、实现不同的用户访问服务端的时候会在session对象中存储键值对,“键”用来存储开启这个用户信息的“钥匙”,在登录成功后,“钥匙”通过cookie返回给客户端,客户端存储为sessionId记录在cookie中。当客户端再次访问时,会默认携带cookie中的sessionId来实现会话机制。
(1)session是基于cookie的。
cookie的数据4k左右;
cookie存储数据的格式:字符串key=value
cookie存储有效期:可以自行通过expires进行具体的日期设置,如果没设置,默认是关闭浏览器时失效。
cookie有效范围:当前域名下有效。所以session这种会话存储方式方式只适用于客户端代码和服务端代码运行在同一台服务器上(前后端项目协议、域名、端口号都一致,即在一个项目下)
(2)session持久化
用于解决重启服务器后session消失的问题。在数据库中存储session,而不是存储在内存中。通过包:express-mysql-session。
当客户端存储的cookie失效后,服务端的session不会立即销毁,会有一个延时,服务端会定期清理无效session,不会造成无效数据占用存储空间的问题。
3、原理
session 的工作原理是客户端登录完成之后,服务器会创建对应的 session,session 创建完之后,会把 session 的 id 发送给客户端,客户端再存储到浏览器中。这样客户端每次访问服务器时,都会带着 sessionid,服务器拿到 sessionid 之后,在内存找到与之对应的 session 这样就可以正常工作了。
2、存取demo:session在request对象中,session的存与取:
import java.io.IOException;
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 javax.servlet.http.HttpSession;
import com.login.dao.UserDao;
@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("post");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//resp.setContentType("application/json;charset=utf-8");
String username = req.getParameter("username");
String pwd = req.getParameter("pwd");
// System.out.println(username+pwd);
UserDao dao = new UserDao();
int a = dao.login(username, pwd);
if (a > 0) {
String str = "\"code\":" + "\"" + "登录成功" + "\"";
System.out.println(str);
HttpSession httpSession=req.getSession();//获取session
httpSession.setAttribute("username", username);
resp.getWriter().write("登录成功");
} else {
String str = "\"code\":" + "\"" + "登录失败" + "\"";
System.out.println(str);
resp.getWriter().write("登录失败");
}
}
}
HttpSession httpSession=req.getSession();//获取session
httpSession.setAttribute("username", username);
resp.getWriter().write("登录成功");
} else {
String str = "\"code\":" + "\"" + "登录失败" + "\"";
System.out.println(str);
resp.getWriter().write("登录失败");
}
}
}
import java.io.IOException;
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 javax.servlet.http.HttpSession;
@WebServlet(name="MainServlet",urlPatterns="/main")
public class MainServlet extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
HttpSession httpSession=req.getSession();
String name=(String) httpSession.getAttribute("username");//取
resp.getWriter().write(name);
}
}
HttpSession httpSession=req.getSession();
String name=(String) httpSession.getAttribute("username");//取
resp.getWriter().write(name);
}
}
二、session和cookie:
1、区别:
(1)存储位置不同:cookie在客户端浏览器;session在服务器;
(2)存储容量不同:cookie<=4K,一个站点最多保留20个cookie;session没有上线,出于对服务器的保护,session内不可存过多东西,并且要设置session删除机制;
(3)存储方式不同:
cookie只能保存ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据;
session中能存储任何类型的数据,包括并不局限于String、integer、list、map等;
(4)隐私策略不同:cookie对客户端是可见的,不安全;session存储在服务器上,安全;
(5)有效期不同:
开发可以通过设置cookie的属性,达到使cookie长期有效的效果;
session依赖于名为JESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session达不到长期有效的效果;
(6)跨域支持上不同:cookie支持跨域;session不支持跨域;
2、关联:一般默认情况下,在会话中,服务器存储 session 的 sessionid 是通过 cookie 存到浏览器里。如果浏览器禁用了 cookie,浏览器请求服务器无法携带 sessionid,服务器无法识别请求中的用户身份,session失效。但是可以通过其他方法在禁用 cookie 的情况下,可以继续使用session:
(1)通过url重写,把 sessionid 作为参数追加的原 url 中,后续的浏览器与服务器交互中携带 sessionid 参数。
(2)服务器的返回数据中包含 sessionid,浏览器发送请求时,携带 sessionid 参数。
(3)通过 Http 协议其他 header 字段,服务器每次返回时设置该 header 字段信息,浏览器中 js 读取该 header 字段,请求服务器时,js设置携带该 header 字段。
三、session与token机制:token适用于前后端分离的项目(前后端代码运行在不同的服务器下)。