Cookie和Session以及相关的方法
作者:~小明学编程
文章专栏:JavaEE
格言:热爱编程的,终将被编程所厚爱。
目录
Cookie
什么是Cookie?
为什么要用Cookie?
Cookie的原理
Session
什么是Session?
为什么要用Session?
Session原理
核心方法
实现用户登录
LoginServlet 类
IndexServlet 类
前端代码
效果演示
上传文件
核心方法
实战演示
Cookie
什么是Cookie?
Cookie,有时也用其复数形式Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。
为什么要用Cookie?
因为http协议是一种无状态的协议也就是我们的客户端和服务端互相不认识,也就是对事务的处理缺少记忆力,当我们后续处理数据的时候想要前面的数据的时候,就需要客户端再次的去传输前面的数据,这样一来我们每次传输的数据量就比较的大了,同时也降低了服务端响应的速度。
Cookie的原理
就是当客户端访问服务器的时候(服务器运用了cookie),服务器会生成一份cookie传输给客户端,客户端会自动把cookie保存起来,以后客户端每次访问服务器,都会自动的携带着这份cookie,这样就避免了不必要的传输。
缺点:保存在客户端容易被篡改,本身最大4kb.
Session
什么是Session?
Session是另一种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,而Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了session是一种特殊的cookie。cookie是保存在客户端的,而session是保存在服务端。
为什么要用Session?
由于cookie 是存在用户端,而且它本身存储的尺寸大小也有限,最关键是用户可以是可见的,并可以随意的修改,很不安全。那如何又要安全,又可以方便的全局读取信息呢?于是,这个时候,一种新的存储会话机制:session 诞生了。
Session原理
当客户端第一次请求服务器的时候,服务器生成一份session保存在服务端,将该数据(session)的id以cookie的形式传递给客户端;以后的每次请求,浏览器都会自动的携带cookie来访问服务器(session数据id)。
核心方法
HttpServletRequest 类
方法 | 描述 |
HttpSession getSession() | 在服务器中获取会话. 参数如果为 true, 则当不存在会话时新建会话; 参数如果 为 false, 则当不存在会话时返回 null |
Cookie[] getCookies() | 返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把 Cookie 中的格式解析成键值对 |
在调用getSession的时候我们服务器首先会获取请求中的Cookie里面的SessionId字段通过这个字段来查找服务器中是否存在相应的HttpSession,如果不存在就创建会话。
创建会话
的时候会创建一个 HttpSession 对象,并且生成一个 sessionld (是一个很长的数字,通常是用十六进制来表示,能够保证唯一性~)接下来就会把 这个 sesionld 作为 key,把这个 HttpSession 对象,作为 value,把这个键值对,给保存到 服务器内存 的一个"哈希表“这样的结构中~~
再然后, 服务器就会返回一个 HTTP 响应,把 sessionld 通过 Set-Cookie 字段返回给浏览器浏览器就可以保存这个 sessionld 到 Cookie 中了。
获取会话
先获取到请求中的 cookie 里面的 sessionld 字段~(也就是会话的身份标识)判定这个 sessionld 是否在当前服务器上存在~~(也就是在这个 哈表 中是否有)如果有,就直接查询出这个 HttpSession 对象 并且通过返回值返回回去。
HttpServletResponse
方法 | 描述 |
void addCookie(Cookie cookie) | 把指定的 cookie 添加到响应中 |
HttpSession
一个 HttpSession 对象里面包含多个键值对. 我们可以往 HttpSession 中存任何我们需要的信息。
方法 | 描述 |
Object getAttribute(String name) | 该方法返回在该 session 会话中具有指定名称的对象,如果没 有指定名称的对象,则返回 null. |
void setAttribute(String name, Object value) | 该方法使用指定的名称绑定一个对象到该 session 会话 |
boolean isNew() | 判定当前是否是新创建出的会话 |
Cookie 类
方法 | 描述 |
String getName() | 该方法返回 cookie 的名称。名称在创建后不能改变。(这个值是 Set Cooke 字段设置给浏览器的) |
String getValue() | 该方法获取与 cookie 关联的值 |
void setValue(String newValue) | 该方法设置与 cookie 关联的值 |
实现用户登录
LoginServlet 类
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理用户请求
String username = req.getParameter("username");
String password = req.getParameter("password");
//判定用户名和密码,这里我们就简单的用123456,666666当作用户名和密码
if ("123456".equals(username) && "666666".equals(password)) {
//登录成功
//创建会话
HttpSession httpSession = req.getSession(true);
//向会话中存入键值对
httpSession.setAttribute("username",username);
resp.sendRedirect("index");//重定向
} else {
//登录失败
resp.getWriter().write("login failed!");
}
}
}
此处的 getSession 参数为 true, 表示查找不到 HttpSession 时会创建新的 HttpSession 对象, 并
生成一个 sessionId, 插入到 哈希表 中, 并且把 sessionId 通过 Set-Cookie 返回给浏览器。
IndexServlet 类
@WebServlet("/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//返回简单的主页
HttpSession session = req.getSession(false);
String username = (String) session.getAttribute("username");
resp.setContentType("text/html;charset=utf8");
resp.getWriter().write("<h3>欢迎用户"+username+"</h3>");
}
}
在这个代码中是看不到 "哈希表", 也看不到 sessionId 这样的概念的. getSession 操作内部提取到
请求中的 Cookie 里的 sessionId, 然后查找哈希表, 获取到对应的 HttpSession 对象。
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录</title>
</head>
<body>
<form action="login" method="post">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="登录">
</form>
</body>
</html>
这里我们前端只是做个和简单的页面。
效果演示
上传文件
核心方法
HttpServletRequest 类方法
方法 | 描述 |
Part getPart(String name) | 获取请求中给定 name 的文件 |
Collection<Part> getParts() | 获取所有的文件 |
Part 类方法
方法 | 描述 |
String getSubmittedFileName() | 获取提交的文件名 |
String getContentType() | 获取提交的文件类型 |
long getSize() | 获取文件的大小 |
void write(String path) | 把提交的文件数据写入磁盘文件 |
实战演示
提交一张图片到服务器中。
@MultipartConfig
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part part = req.getPart("MyImage");
System.out.println(part.getSubmittedFileName());
System.out.println(part.getContentType());
System.out.println(part.getSize());
part.write("D:\\.1学习资料\\JAVA\\aaa.jpg");
resp.setContentType("text/html; charset=utf8");
resp.getWriter().write("上传成功!");
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>上传图片</title>
</head>
<body>
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="MyImage">
<input type="submit" value="提交">
</form>
</body>
</html>
请求: