Servlet基础知识三
- 1.Cookie和Session
-
- 1.1Cookie
- 1. 2 会话机制session
- 1.3 Cookie和Session的区别
- 1.4核心方法
- 2.上传文件
-
- 核心方法
1.Cookie和Session 1.1Cookie 1.http协议五个特点:
(1)简单快速:客户端向服务器端发送请求时,只需传递请求方法,路径和请求参数,因为http协议简单,所以使得HTTP服务器的程序规模小,因而通信速度很快。2.HTTP协议自身是无状态协议,无状态指定是HTTP协议的客户端和服务器端之间的这次通信,和下次通信之间没有直接的联系。但是在实际开发中,我们很多时候是需要知道请求之间的关联关系的。
(2)无连接:无连接指的是,每次连接只处理一个请求。服务器处理完客户的的请求后,会立即断开连接。
(3)无状态:HTTP不会记录每次请求的身份信息,因此前一次请求和后一次请求相互"不认识"。
(4)可传递任意数据类型:HTTP允许传输任意数据类型,只需要在请求头中表示数据类型Content-Type即可。
(5)一对一通讯:每次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 StringSESSION_USER_KEY="SESSION_USER_KEY";
/**
* 读session
* false表示有会话返回session对象,没有会话返回null
* true:有会话返回session对象,没有会话创建一个会话,会话=是否登录
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;
charset=utf-8");
//1.先得到session对象
HttpSession session=req.getSession(false);
if(null==session){
//没有登录
resp.getWriter().println("抱歉,尚未登录!");
}else{
//已登录,打印用户信息
//2.从session中得到关联的用户对象
User user= (User) session.getAttribute("SESSION_USER_KEY");
resp.getWriter().println("登录成功|"+user);
}
}/**
* 写session
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;
charset=utf-8");
String result="操作失败";
//1,得到session
HttpSession session=req.getSession(true);
if(session !=null){//得到或创建了会话
//2.将用户对象存储到session,即关联起来
User user=new User();
user.setName("admin");
user.setPassword("admin");
session.setAttribute("SESSION_USER_KEY",user);
result="Session写入成功";
}
resp.getWriter().println(result);
}
}
【javaee|Servlet基础知识(三)】
文章图片
使用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 StringSESSION_USER_KEY="SESSION_USER_KEY";
/**
* 读session
* false表示有会话返回session对象,没有会话返回null
* true:有会话返回session对象,没有会话创建一个会话,会话=是否登录
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;
charset=utf-8");
//1.先得到session对象
HttpSession session=req.getSession(false);
if(null==session){
//没有登录
resp.getWriter().println("抱歉,尚未登录!");
}else{
//已登录,打印用户信息
//2.从session中得到关联的用户对象
User user= (User) session.getAttribute("SESSION_USER_KEY");
resp.getWriter().println("登录成功|"+user);
}
}
}
文章图片
文章图片
文章图片
4.Cookie 类中的相关?法
每个 Cookie 对象就是?个键值对.
文章图片
●HTTP 的 Cooke 字段中存储的实际上是多组键值对. 每个键值对在 Servlet 中都对应了?个 Cookie 对象.(1)写Cookie:
●通过HttpServletRequest.getCookies()
获取到请求中的?系列 Cookie 键值对
●通过HttpServletResponse.addCookie()
可以向响应中添加新的 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 {
/**
* 写cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@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 {
/**
* 写cookie
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@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 添加成功");
}/**
* cookie读取
* @param req
* @param resp
* @throws ServletException
* @throws IOException
*/
@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()+"
");
}
}
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//1.不能省略,表示当前类为文件上传类
@WebServlet("/upfile")
public class FileServlet extends HttpServlet {
//文件上传一定要使用POST类型(因为GET类型有文件大小限制)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//2.得到客户端上传的文件
Part part=req.getPart("name");
//3.将文件保存到服务器端
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//1.不能省略,表示当前类为文件上传类
@WebServlet("/upfile")
public class FileServlet extends HttpServlet {
//文件上传一定要使用POST类型(因为GET类型有文件大小限制)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//2.得到客户端上传的文件
Part part=req.getPart("name");
//2.1每次得到一个唯一的文件名(一定不要用时间戳)
String fileName= UUID.randomUUID().toString();
//2.2得到文件类型(ex:.jpg)
String fileType=part.getSubmittedFileName().substring(part.getSubmittedFileName().lastIndexOf("."));
//3.将文件保存到服务器端
part.write("D:\\"+fileName+fileType);
}
}
使用postman提交图片:
文章图片
文章图片
文章图片
后面提交的图片不会覆盖后者:
文章图片
推荐阅读
- javaee|FinalShell安装和使?
- 导入Avada Demos错误-无法访问demo服务器。请在”系统状态”页面上检查wp_remote_get
- netty系列之:使用netty搭建websocket服务器
- 抓包工具|Android抓包工具——Fiddler
- 关于http的一些事
- Windows Server 2016部署MDT服务器----测试映像部署
- Windows Server 2016部署MDT服务器----新建Task任务,分区,部署日志存放
- 考取华为HICP证书能带来什么(找工作方便吗?)
- 利用原型链漏洞污染拿下服务器权限