javaee|Servlet基础知识(三)


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)无连接:无连接指的是,每次连接只处理一个请求。服务器处理完客户的的请求后,会立即断开连接。
(3)无状态:HTTP不会记录每次请求的身份信息,因此前一次请求和后一次请求相互"不认识"。
(4)可传递任意数据类型:HTTP允许传输任意数据类型,只需要在请求头中表示数据类型Content-Type即可。
(5)一对一通讯:每次HTTP请求,都是一个客户端对应一个服务器端。
2.HTTP协议自身是无状态协议,无状态指定是HTTP协议的客户端和服务器端之间的这次通信,和下次通信之间没有直接的联系。但是在实际开发中,我们很多时候是需要知道请求之间的关联关系的。
例如登录网站成功之后,第二次访问的时候服务器就能知道该请求是已经登录过了。
javaee|Servlet基础知识(三)
文章图片

图中的令牌就存储在Cookie字段中。
cookie就相当于一个令牌,记录请求的用户信息,拥有了这个令牌以后就可以去访问该网站下面的任意页面。但是cookie是客户端机制,可以伪造用户身份,所以是不安全的。
此时在服务器这边就需要记录令牌信息,以及令牌对应的用户信息,这个就是session机制所做的工作。
1. 2 会话机制session 1.服务器同一时刻收到的请求是很多的,服务器需要清楚的区分每个请求是从属哪个用户,就需要在服务器这边记录每个用户令牌以及用户的信息的对应关系。
会话(登录状态,即是否登录)即就是用户输入正确的用户名和密码时创建会话。
2.会话的本质就是一个哈希表,存储了一些键值对结构,key就是令牌的ID(token/sessionid),value就是用户信息。
javaee|Servlet基础知识(三)
文章图片

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类中的相关方法
javaee|Servlet基础知识(三)
文章图片

2.HttpServletResponse类中的相关方法:
javaee|Servlet基础知识(三)
文章图片

3.HttpSession 类中的相关方法:
一个HttpSession对象里面包含多个键值对,我们可以往HttpSession中存人和我们需要的信息。
javaee|Servlet基础知识(三)
文章图片

(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基础知识(三)】javaee|Servlet基础知识(三)
文章图片

使用postman
javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

(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); } } }

javaee|Servlet基础知识(三)
文章图片
javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

4.Cookie 类中的相关?法
每个 Cookie 对象就是?个键值对.
javaee|Servlet基础知识(三)
文章图片

●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 { /** * 写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 添加成功"); } }

javaee|Servlet基础知识(三)
文章图片

使用postman查看是否添加cookie成功:
javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

(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()); } }

javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

使用postman查看cookie:
javaee|Servlet基础知识(三)
文章图片

F12打开开发者工具,模拟添加cookie:
javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

2.上传文件 上传文件也是日常开发中一类常见的需求。
核心方法 1.HttpServletRequest 类?法
javaee|Servlet基础知识(三)
文章图片

2.part类方法
javaee|Servlet基础知识(三)
文章图片

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上传文件:
javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片
javaee|Servlet基础知识(三)
文章图片

D盘有a.jpg说明文件上传服务器端成功。
javaee|Servlet基础知识(三)
文章图片

上面的图片提交存在一个问题,就是当再次提交一个图片时会将前者覆盖。
(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|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

javaee|Servlet基础知识(三)
文章图片

后面提交的图片不会覆盖后者:
javaee|Servlet基础知识(三)
文章图片

    推荐阅读