关于Cookie 和 Session 介绍
- HTTP 协议自身是属于 "无状态" 协议
- "无状态" 的含义指的是默认情况下 HTTP 协议的客户端和服务器之间的这次通信, 和下次通信之间没有直接的联系
- 但是实际开发中, 我们很多时候是需要知道请求之间的关联关系的
- 例如登陆网站成功后, 第二次访问的时候服务器就需要知道该请求是否是已经登陆过了
- 这个时候我们就需要有一个标记来判断登录状态
- 这个标记在用户端就存放在Cookie中
- 用户端发送请求的时候就会携带相应的Cookie信息
- 服务端接收到数据可以根据标记来判断是否登陆过
- 由于服务器同一时刻收到的请求是很多的. 服务器需要区分每个请求是属于哪个用户, 就需要在服务器这边记录每个用户标记和用户信息的对应关系
- 这些信息在服务端就存放在Session(会话)中
- 会话的本质就是一个 "哈希表", 存储了一些键值对结构. key 就是标记的ID(token/sessionId), value 就是用户信息(用户信息可以根据需求灵活设计).
- 服务端就可以使用标记(Cookie)中的信息通过会话(Session)找到相应的通信信息
Cookie 和 Session 的区别
- Cookie 是客户端的机制
- Session 是服务器端的机制
- Cookie 和 Session 经常会在一起配合使用. 但并不是必须配合
- 完全可以用 Cookie 来保存一些数据在客户端. 这些数据不一定是用户身份信息, 也不一定是 token / sessionId
- Session 中的 token / sessionId 也不是非得通过 Cookie / Set-Cookie 传递
关于Cookie 和 Session的方法
HttpServletRequest
方法 | 描述 |
---|---|
HttpSession getSession() | 在服务器中获取会话. 参数如果为 true, 则不存在会话时新建会话; 参数如果为 false, 则不存在会话时返回 null |
Cookie[] getCookies() | 返回一个数组, 包含客户端发送该请求的所有的 Cookie 对象. 会自动把Cookie 中的格式解析成键值对 |
HttpServletResponse
方法 | 描述 |
---|---|
void addCookie(Cookie cookie) | 把指定的 cookie 添加到响应中 |
关于HttpSession类
方法 | 描述 |
---|---|
Object getAttribute(String name) | 返回在该 session 会话中具有指定名称的对象, 如果没有指定名称的对象,则返回 null |
void setAttribute(String name, Object value) | 使用指定的名称绑定一个对象到session 会话中 |
boolean isNew() | 判定当前会话是否为新创建出的会话 |
关于Cookie类--每个 Cookie 对象就是一个键值对
方法 | 描述 |
---|---|
String getName() | 返回 cookie 的名称. 名称在创建后不能改变(这个值是 SetCooke 字段设置给浏览器的) |
String getValue() | 获取与 cookie 关联的值 |
void setValue(String newValue) | 设置与 cookie 关联的值 |
关于上传文件
HttpServletRequest
方法 | 描述 |
---|---|
Part getPart(String name) | 获取请求中给定 name 的文件 |
Collection getParts() | 获取请求中传输的所有的文件 |
关于Part类
方法 | 描述 |
---|---|
String getSubmittedFileName() | 获取提交的文件名 |
String getContentType() | 获取提交的文件类型 |
long getSize() | 获取文件的大小 |
void write(String path) | 把提交的文件数据写入磁盘文件 |
编写代码理解
用户登录,存取Session
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>login</title>
</head>
<body>
<form action="login" method="post">
<input type="text" name="username">
<br/>
<input type="password" name="password">
<br/>
<input type="submit" value="登录">
<br/>
</form>
</body>
</html>
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 java.io.IOException;
@WebServlet(name = "LoginServlet", value = "/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=uft8");
//处理用户请求,先获取传入的参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//判定用户名和密码是否正确
if ("admin".equals(username) && "admin".equals(password)) {
//登录成功
//创建会话,并保存必要的身份信息
HttpSession httpSession = request.getSession(true);
//往会话中存储键值对
httpSession.setAttribute("username", username);
response.sendRedirect("index");
} else {
//登陆失败
response.getWriter().write("login failed");
}
}
}
@WebServlet(name = "IndexServlet", value = "/index")
public class IndexServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//false:如果没有会话不会创建新的
HttpSession session = request.getSession(false);
String username = (String) session.getAttribute("username");
response.setContentType("text/html;charset=utf8");
response.getWriter().write("<h3>恭喜用户" + username + "登录成功" + "</h3>");
}
}
上传文件
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>upload</title>
</head>
<body>
<!--enctype="multipart/form-data"传输数据类型:上传文件-->
<form action="upload" method="post" enctype="multipart/form-data">
<input type="file" name="MyImage">
<br/>
<input type="submit" value="提交">
<br/>
</form>
</body>
</html>
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
//上传文件必须要带这个注解
@MultipartConfig
@WebServlet(name = "UploadServlet", value = "/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html; charset=utf8");
//获取传输的文件
Part part = request.getPart("MyImage");
//输出文件信息
System.out.println(part.getSubmittedFileName());
System.out.println(part.getContentType());
System.out.println(part.getSize());
part.write("D:\mixed\background\test.jpg");
response.getWriter().write("上传成功!");
}
}