1.Cookie基础知识:
- Cookie是浏览器在本地持久化保存数据的一种方案。
- 一个典型的使用场景:存储登录信息
- Cookie:是浏览器在本地存储数据(存放到硬盘上)的一种机制,cookie是请求头中的一个重要字段。每个Cookie都是一个键值对。
- cookie和query string一样都是程序员自定制的。Cookie是按照域名维度来组织的,不同的域名下有不同的Cookie,一个网站发起的http请求可能是来自于多个域名的。
- Cookie不是缓存,是持久化存储数据的手段,浏览器自动帮你存储,这个存储是保存到硬盘上的;而缓存的数据不一定是持久化的(也可以在内存里缓存);缓存的数据是用来提高访问速度的!
- Cookie这里的键值对都是简单的字符串,只能存放一些简单的信息,例如:上次访问页面的时间,当前网页的访问次数,当前访问页面的身份信息(身份标识,id)等。
- Cookie从哪里来?Cookie是存在浏览器的本地,来源是服务器。上图中的这些Cookie都是浏览器访问了服务器之后由服务器返回的,在服务器返回的响应报文中,可以在响应header中包含一个或多个Set-Cookie这样的字段,浏览器看到这些Set-Cookie就会把这样的数据保存在浏览器本地。
- Cookie到哪里去?来自于服务器,存储于浏览器,还要再返回到服务器。当浏览器保存了Cookie之后下次浏览器访问同一个网站,就会把之前本地存储的cookie再通过http请求header中的cookie给带回去。如果达到了过期时间,Cookie也会自动的被清除掉。
- 为什么要有这个一来一回,绕圈的过程呢?服务器要服务的客户端是很多的,这些不同的客户端应该要有不同的数据、只有返回了,服务器才知道客户端的详细情况。
2.Session基础知识:
- 服务器同一时刻收到的请求有很多,服务器需要清楚的区分每个请求属于哪个客户端,就需要先在服务器这里记录每个用户的身份标识和所对应的用户信息。
- 会话的本质就是一个哈希表,存储着一些键值对。其中key就是身份标识(sessionId),value就是用户信息(session)。
- sessionId是由服务器生成的一个唯一性字符串;和token是同一个东西的不同叫法。
- Cookie是在客户端的机制;Session是服务器的机制。
- Servlet中的session默认是存储在内存上的,如果重启服务器则session数据就会丢失。
3.相关API:
在servlet中专门提供了相关的api,来操作Cookie和Session。
3.1.HttpServletRequest类:
- 核心方法:
方法 | 说明 |
HttpSession getSession(false/true) | 在服务器中获取会话,注意返回值 |
Cookie[ ] getCookies() | 返回一个包含客户端发送请求的所有Cookie对象的数组,注意类型 |
- getSession方法的使用方式有俩种。第一种参数填写为false,判断当前的会话是否存在,如果不存在直接返回null;如果存在则返回对应的HttpSession对象。第二种参数填写为true,判断当前会话是否存在,如果不存在就会创建一个新的键值对保存到哈希表中并把生成的sessionId返回到浏览器这里;如果存在则直接返回对应的HttpSession对象。
- 判断当前会话是否存在是根据请求中的Cookie里的sessionId来查询哈希表。
- getCookies方法直接把请求中的Cookie都获取到,Cookie本身也是键值对的结构。返回一个Cookie类型的数组。
3.2.HttpServletResponse类:
- 核心方法:
方法 | 说明 |
void addCookie(Cookie cookie) | 把指定的cookie添加到响应中 |
- addCookie是返回响应,想给浏览器返回哪些Cookie都可以通过这个方法来添加,在这里添加的键值对都会体现在HTTP响应报文的Set-Cookie字段上。
3.3.HttpSession类:
- 核心方法:
方法 | 说明 |
Object getAttribute() | 返回指定名称的对象,如果没有指定名称的对象则返回null |
void setAttribute() | 使用指定的名称绑定一个对象到该会话中 |
boolean isNew() | 判断当前对象是不是新创建出来的会话 |
- 一个HttpSession对象里面包含了多个键值对,我们可以往HttpSession中存任何我们需要的信息。
3.4.Cookie类:
- 核心方法:
方法 | 说明 |
String getName() | 返回cookie的名称 |
String getValue() | 获取于cookie关联的值 |
void setValue(String newValue) | 设置于cookie关联的值 |
- 每个Cookie对象都是一个键值对。
- Http的Cookie字段中存储的是多组键值对,每个键值对在Servlet中都对应一个Cookie对象。
3.5.模拟实现登录页面
- 在登陆页面上用户可以填写用户名和密码;使用一个servlet来处理登录请求;使用另外一个servlet来生成登陆成功后跳转的页面。
- setAttribute可以灵活根据需求存储想要的东西(键值对)。
- 此处的会话是根据sessionId来查哈希表的。如果把浏览器存储的cookie删了并且不登陆直接访问index页面,会触发这个if,导致不能访问。如果没有登陆过直接访问主页也会提示!
- 登陆成功跳转的抓包情况:
- 登录页面创建会话和主页判断session存在:
处理登录请求的servlet:login
package login; 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("/login") public class LoginServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf8"); //1.获取用户名和密码 String username = req.getParameter("username"); String password = req.getParameter("password"); //2.验证密码是否正确 //这里如果写成是user.equals("王大锤"),如果user是null,就会触发空指针异常 //equals()在方法内部对参数为null做了特别处理,因此可以写成user.equals("王大锤") if("王大锤".equals(username) && "666".equals(password)){ //登陆成功 // a) 创建一个会话,用户刚登陆成功之前没有回话 //getSession // 、创建session和一个Httpsession对象 // 、把这俩个内容以键值对的形式插入到哈希表里 // 、再把sessionId通过set-cookie发送给客户端 HttpSession session = req.getSession(true); //随意设置键值对 session.setAttribute("username","王大锤"); // b) 让响应重定向到主页 resp.sendRedirect("index"); }else{ //登陆失败 resp.setStatus(403); resp.setContentType("text/html; charset=utf8"); resp.getWriter().write("登陆失败!用户名或密码输入错误!!!"); } } }
生成登陆成功跳转主页的servlet:index
package login; 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("/index") public class IndexServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //首页中先获取了session,此处的session是刚才登录成功创建出来的 //这里的参数是false,表示不新建,如果不存在返回null就行 HttpSession session = req.getSession(false); if(session == null){ resp.setStatus(403); resp.setContentType("text/html; charset=utf8"); resp.getWriter().write("您尚未登录,不能访问主页!"); return; } String username = (String) session.getAttribute("username"); resp.setContentType("text/html;charset=utf8"); resp.getWriter().write("欢迎来到主页," + username + "大哥请喝茶~"); } }
4.上传文件:
- 前端搭配form表单,form input type = ‘file”,允许通过浏览器选中一个文件上传给服务器。
- Servlet支持处理这种上传文件的请求,把这个请求的文件在后端获取到。
- 每个文件就是一个Part对象。
- 核心方法:
方法 | 说明 |
Part getPart(String name) | 获取请求中给定name的文件,和input标签的name属性一样(和getParameter类似) |
Collection<Part> getParts() | 获取所有的文件 |
- Part类方法:
方法 | 说明 |
String getSubmittedFileName() | 获取提交的真实文件名 |
String getContentType() | 获取提交文件的类型 |
long getSize() | 获取文件的大小 |
void write(String path) | 保存到指定路径 |
上传一个图片:
package upload; 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; @WebServlet("/upload") @MultipartConfig public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Part part = req.getPart("myfile"); System.out.println(part.getSubmittedFileName()); System.out.println(part.getSize()); System.out.println(part.getContentType()); part.write("d:/idea/dada/result.jpg"); } }
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹
如果对您有帮助的话,
不要忘记点赞+关注哦,蟹蟹