1.Cookie和Session
1.1Cookie
1.http协议五个特点:
(1)简单快速:客户端向服务器端发送请求时,只需传递请求方法,路径和请求参数,因为http协议简单,所以使得HTTP服务器的程序规模小,因而通信速度很快。 (2)无连接:无连接指的是,每次连接只处理一个请求。服务器处理完客户的的请求后,会立即断开连接。 (3)无状态:HTTP不会记录每次请求的身份信息,因此前一次请求和后一次请求相互"不认识"。 (4)可传递任意数据类型:HTTP允许传输任意数据类型,只需要在请求头中表示数据类型Content-Type即可。 (5)一对一通讯:每次HTTP请求,都是一个客户端对应一个服务器端。
2.HTTP协议自身是无状态协议,无状态指定是HTTP协议的客户端和服务器端之间的这次通信,和下次通信之间没有直接的联系。但是在实际开发中,我们很多时候是需要知道请求之间的关联关系的。
例如登录网站成功之后,第二次访问的时候服务器就能知道该请求是已经登录过了。 图中的令牌就存储在Cookie字段中。
cookie就相当于一个令牌,记录请求的用户信息,拥有了这个令牌以后就可以去访问该网站下面的任意页面。但是cookie是客户端机制,可以伪造用户身份,所以是不安全的。 此时在服务器这边就需要记录令牌信息,以及令牌对应的用户信息,这个就是session机制所做的工作。
1. 2 会话机制session
1.服务器同一时刻收到的请求是很多的,服务器需要清楚的区分每个请求是从属哪个用户,就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系。 会话(登录状态,即是否登录)即就是用户输入正确的用户名和密码时创建会话。 2.会话的本质就是一个哈希表,存储了一些键值对结构,key就是令牌的ID(token/sessionid),value就是用户信息。
sessionId 是由服务器生成的?个 “唯?性字符串”, 从 session 机制的?度来看, 这个唯?性字符串称为 “sessionId”. 但是站在整个登录流程中看待, 也可以把这个唯?性字符串称为 “token” sessionId 和 token 就可以理解成是同?个东?的不同叫法(不同视?的叫法).
(1)当用户登录的时候,服务器在Session中新增一个新记录,并把sessionid/token返回给客户端(通过HTTP响应中的Set-Cookie字段返回)。 (2)客户端后续再给服务器端发送请求的时候,需要在请求中带上sessionId/token(通过HTTP请求中的Cookie字段带上)。 (3)服务器收到请求之后,根据请求中的sessionid/token在Session信息中获取到对应的用户信息,再进行后续操作。 Servlet的session是默认保存在内存中的,如果重启服务器则session数据就会丢失。
1.3 Cookie和Session的区别
1.Cookie是客户端的机制,Session是服务器端的机制。 2.Cookie和Session经常在一起配合使用,但是不是必须配合。 (1)完全可以? Cookie 来保存?些数据在客户端. 这些数据不?定是?户身份信息, 也不?定是 token / sessionId. (2)Session 中的 token / sessionId 也不需要?得通过 Cookie / Set-Cookie 传递.
1.4核心方法
1.HttpServletRequest类中的相关方法 2.HttpServletResponse类中的相关方法: 3.HttpSession 类中的相关方法: 一个HttpSession对象里面包含多个键值对,我们可以往HttpSession中存人和我们需要的信息。 (1)写session:
import model.User;
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("/sess")
public class SessionServlet extends HttpServlet {
private static final String SESSION_USER_KEY="SESSION_USER_KEY";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
HttpSession session=req.getSession(false);
if(null==session){
resp.getWriter().println("抱歉,尚未登录!");
}else{
User user= (User) session.getAttribute("SESSION_USER_KEY");
resp.getWriter().println("登录成功|"+user);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String result="操作失败";
HttpSession session=req.getSession(true);
if(session !=null){
User user=new User();
user.setName("admin");
user.setPassword("admin");
session.setAttribute("SESSION_USER_KEY",user);
result="Session写入成功";
}
resp.getWriter().println(result);
}
}
使用postman
(2)读session:
import model.User;
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("/sess")
public class SessionServlet extends HttpServlet {
private static final String SESSION_USER_KEY="SESSION_USER_KEY";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
HttpSession session=req.getSession(false);
if(null==session){
resp.getWriter().println("抱歉,尚未登录!");
}else{
User user= (User) session.getAttribute("SESSION_USER_KEY");
resp.getWriter().println("登录成功|"+user);
}
}
}
4.Cookie 类中的相关?法
每个 Cookie 对象就是?个键值对.
●HTTP 的 Cooke 字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了?个 Cookie 对象. ●通过 HttpServletRequest.getCookies() 获取到请求中的?系列 Cookie 键值对 ●通过 HttpServletResponse.addCookie() 可以向响应中添加新的 Cookie 键值对.
(1)写Cookie: CookieServlet.java:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.time.LocalDateTime;
@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie=new Cookie("myCookie","Hello"+ LocalDateTime.now());
resp.addCookie(cookie);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println("Cookie 添加成功");
}
}
使用postman查看是否添加cookie成功: (2)读Cookie:
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
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.time.LocalDateTime;
@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie cookie=new Cookie("myCookie","Hello"+ LocalDateTime.now());
resp.addCookie(cookie);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println("Cookie 添加成功");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies=req.getCookies();
StringBuilder builder=new StringBuilder();
if(cookies != null && cookies.length>0){
for(Cookie item:cookies){
builder.append(item.getName()+":"+item.getValue()+"<br>");
}
}
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().println(builder.toString());
}
}
使用postman查看cookie: F12打开开发者工具,模拟添加cookie:
2.上传文件
上传文件也是日常开发中一类常见的需求。
核心方法
1.HttpServletRequest 类?法 2.part类方法 3.图片上传简易版 (1)第一种基础版: 上传文件一般通过POST请求 FileServlet.java:
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("/upfile")
public class FileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part part=req.getPart("name");
part.write("D:\\a.jpg");
}
}
使用postaman上传文件: D盘有a.jpg说明文件上传服务器端成功。 上面的图片提交存在一个问题,就是当再次提交一个图片时会将前者覆盖。 (2)加强版:
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;
import java.util.UUID;
@MultipartConfig
@WebServlet("/upfile")
public class FileServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Part part=req.getPart("name");
String fileName= UUID.randomUUID().toString();
String fileType=part.getSubmittedFileName().substring(part.getSubmittedFileName().lastIndexOf("."));
part.write("D:\\"+fileName+fileType);
}
}
使用postman提交图片: 后面提交的图片不会覆盖后者:
|