首先我们先创建一个Maven,然后补齐main里面的包,之后我们将web.xml里面的进行复制过来,之后将大项目里面的pom.xml里面复制过来。如下所示:
untitled2
org.example
1.0-SNAPSHOT
4.0.0
Cookie
war
javax.servlet.jsp
javax.servlet.jsp-api
2.3.3
javax.servlet
javax.servlet-api
4.0.1
provided
我们将里面没有用的东西删除掉即可,相关详细步骤我们再之前的博客里面已经提过了。
我们进行刷新之后,发现全部导入进去了。
这就是我们准备工作完成了。
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过。称之为有状态会话。
你能怎么能证明自己是哪所大学的学生:
在你和你的大学之间作为两个对象:我们可以通过以下两种方法
1.交学费的发票凭证 你的大学给你发票
2.学校登记 你的大学标记你来过了
同样的,我们借此来思考一个网站怎么证明你来过:
客户端 服务端(怎么让服务端证明客户端已经来过呢):以下方法:
1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;(服务端给客户端发了一个Cookie)客户端访问的时候带的Cookie.
2.服务器登记你来过了,下次你来的时候我来匹配你;session(session就是在服务器端)
无状态会话:打开浏览器并关闭
cookie:客户端技术(响应:服务器将Cookie发给客户端,请求:客户端将Cookie带到服务器)客户端携带的
session:服务器技术,利用这个技术可以保存用户的会话信息,我们可以把信息或者数据放在Session中!
我们之前学到的能把信息或者东西放到一个东西里面让别人去取是ServletContext。用了setAttribute。ServletContext详解_蕾峰的博客-CSDN博客
常见场景:网站登录之后,下次可以不用再登录了第二次访问直接就登录进去了。
比如我们再登录CSDN的时候,首次登录需要密码,当我们让网站记住密码,下次再次重新点开CSDN的界面的时候,我们发现直接登录上去了。
我们先要学习一个东西,要首先看他的源码。
我们创建一个新的类之后,写入Cookie,如下所示:
我们按住ctrl键,进入源码界面:
这个类可以被克隆(实现了可以克隆的接口):
public class Cookie implements Cloneable, Serializable {
我们点击进行下载它的源码:
我们来进行查看源码如下所示:
设置一些文件:
private static final String LSTRING_FILE =
设置一些键值对一样的东西:
private String name; // NAME= ... "$Name" style is reserved
private String value; // value of NAME
设置一些守护:(设置他的有效域)
private String domain; // ;Domain=VALUE ... domain that sees cookie
设置保存的时间(即为过期时间)
private int maxAge = -1; // ;Max-Age=VALUE ... cookies auto-expire
设置注册一些版本:
private int version = 0; // ;Version=1 ... means RFC 2109++ style
得到一些方法:
private String path; // ;Path=VALUE ... URLs that see the cookie
我们打开Structure可以发现在这些属性有对应的get和set方法。有了get和set方法可以对属性进行一些操作。说白了就是在操作Cookie这个类。
我们要实现保存用户上一次访问的时间,我们的思维逻辑如下所示:
首先我们先解决中文乱码问题:
req.setCharacterEncoding("utf-8");
//响应
resp.setCharacterEncoding("utf-8");
之后我们来设置获取输入与输出的信息:
//想要客户端返回一些字符串,需要返回一个输出对象。(响应)用Response.
PrintWriter out = resp.getWriter();
// 请求是客户端拿着cookie到服务器。服务器获取Cookie。
//Cookie,服务器给了客户端,客户端带来的时候是服务器端需要从客户端获取,是Request。
Cookie[] cookies = req.getCookies(); //这里返回数组,说明cookie可能存在多个(多个标志)。
之后我们利用if--else语句进行判断是否有Cookie:
/判断cookie是否存在
if (cookies!=null){ //不等于null,说明cookie有值
//如果存在cookie怎么办:
out.write("你上一次访问的时间是:");
//第一次访问一定是没有值的
}else{
out.write("这是您第一次访问本站");
}
当我们判断没有值的时候,我们需要传递一个Cookie,我们设置Cookie如下所示:
/客户端第一次访问服务器的时候,服务器需要给客户端发一个Cookie。
//服务器给客户端响应一个cookie:
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
resp.addCookie(cookie); //添加一个Cookie,他的参数是cookie这样子一个对象
}
我们查看Cookie里面发现如下所示:
Cookie只能存String,存在局限性,说明存的东西比较少
接下来我们进行设计如果Cookie存在的话代码如何设计:
if (cookies!=null){ //不等于null,说明cookie有值
//如果存在cookie怎么办
//如果存在我们要取出我们想取出的数据
out.write("你上一次访问的时间是:");
//进行遍历数据
//两种for循环:
//for(Cookie cookie:cookies){}
//我们更倾向于使用下一种for循环(更加的灵活)
for (int i=0;i
我们完成代码的设计之后,我们进行在web.xml里面进行注册:
CookieDemo01
com.rgf.servlet.CookieDemo01
CookieDemo01
/c1
之后我们进行配置Tomcat:
配置完毕之后,点击OK。我们点击运行之后,发现出现如下所示:
出现了乱码问题,我们在进行UTF-8地方加入这行代码:
resp.setContentType("text/html");
我们重新运行之后如下所示:
我们发现成功运行出来了。
我们进入浏览器,点击开发者工具,点击Application,我们发现Cookies,进入之后,我们发现lastLoginTime,除了这个以外,我们还发现其他的cookie,
我们将cookie进行删除后,
服务器再次给客户端发送了一个新的cookie。
我们发现除了我们设置的Cookie之外,我们还有一个Cookie:
JSESSIONID,这是服务器端,只要一连上浏览器就会开启一次会话。我们将浏览器关了之后就没有啦。我们每次刷新都会出现一个不同的时间,都会发送一个新的Cookie。
我们为什么会获取这个时间,我们通过分析网站请求来看:
我们重新进入刷新,点开Network,点开Headers,我们发现 Response(响应)里面的:
Set-Cookie:lastLoginTime=1662384316731
Cookie是一个键值对的形式
我们发现这里面也有一个Cookie:
Cookie:JSESSIONID=837B90BDAA8682E02EB26870323F909A; lastLoginTime=1662366474311
我们发现这个Cookie里面有两组键值对。
其中Request里面的lastLoginTime=1662366474311是我们上一次登录的时间,而Response里面的lastLoginTime=1662384316731为响应回来的新的登录时间。
我们将浏览器关掉Cookie还会存在么:
我们进行访问发现出现如下所示:
发现Cookie不见了,这个会话就是浏览器关了,这个会话就结束了。
我们将浏览器里面的Cookie进行清除之后,才发现第一次进入了我们所编写的这是您第一次访问本站。而我们在第一次访问的时候出现的是你上一次访问的时间是:,原因是浏览器会默认在Cookie中存放一些数据,所以不可能判断Cookie为空,所以我们直接按存有东西进行响应。即会出现你上一次访问的时间是。
如何将Cookie进行多层会话呢?我们进入Cookie的源码界面进行查看:
我们发现Cookie里面的源码如下所示:
其中的代码:
可以设置存活的时间:setMaxAge(int expiry)。
expiry为有效期的意思
我们在设置Cookie里面的代码进行设计如下所示:
//服务器给客户端响应一个cookie:
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//设置Cookie有效期为一天。
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie); //添加一个Cookie,他的参数是cookie这样子一个对象
我们进行刷新发现出现如下所示:
我们发现此时Cookie为lastLogintime的值为:1662448381522
之后我们关闭浏览器,然后再重新打开浏览器。
我们发现浏览器关掉之后仍然能再次拿到Cookie,
我们点击Network进行查看:
我们发现Set-Cookie里面出现的时间cookie到2022年9月7日才结束。里面多了一个Max-Age(多了一个最大的时间)刚开始的时候,我们只有一个lastLoginTime。
我们在Request里面进行查看Cookie,发现他的值为:lastLoginTime=1662448267811
我们所编写的代码为获取上一次访问的时间,所以lastLoginTime一直在发生变化。
浏览器关闭之后Cookie仍然存在,这种行为是非常不安全的。
我们对实现上一次的访问时间的完整代码如下所示:
package com.rgf.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
//保存用户上一次访问的时间(我们也可以使用IO进行实现,
// 就是他过来的时候你把东西保存在本地,写一个文件,下次过来的时候再去读他,把那个所写的文件带上,把里面的东西读出来,这种方法比较低级一点)
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器告诉你你来的时间,把这个时间封装成为一个信件,然后给了你,你下次来的时候带来,服务器就知道你来了。
//首先解决中文乱码问题:
//请求
req.setCharacterEncoding("utf-8");
//响应
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
//想要客户端返回一些字符串,需要返回一个输出对象。(响应)用Response.
PrintWriter out = resp.getWriter();
// 请求是客户端拿着cookie到服务器。服务器获取Cookie。
//Cookie,服务器给了客户端,客户端带来的时候是服务器端需要从客户端获取,是Request。
Cookie[] cookies = req.getCookies(); //这里返回数组,说明cookie可能存在多个(多个标志)。
//我们为了要获取Cookie,首先要判断Cookie是否存在,这是一个正常的程序逻辑。
//判断cookie是否存在
if (cookies!=null){ //不等于null,说明cookie有值
//如果存在cookie怎么办
//如果存在我们要取出我们想取出的数据
out.write("你上一次访问的时间是:");
//进行遍历数据
//两种for循环:
//for(Cookie cookie:cookies){}
//我们更倾向于使用下一种for循环(更加的灵活)
for (int i=0;i
我们对Cookie的总结如下所示:
1.从请求中拿到Cookie信息
2.服务器响应给客户端Cookie。
我们所使用的方法有:
Cookie[] cookies = req.getCookies(); //获得Cookie
cookie.getName() //获得cookie中的key
cookie.getValue(); //获得cookie中的value
new Cookie("lastLoginTime", System.currentTimeMillis()+""); //新建一个cookie
cookie.setMaxAge(24*60*60) //设置cookie的有效期
resp.addCookie(cookie) //响应给客户端一个cookie
我们自身电脑也有好多cookie,我们可以打开C盘进行查看:
cookie:一般会保存在本地的用户目录下 Appdata文件夹里面
这是本机保存的部分Cookies。
cookie为什么会保存,就是因为cookie在本地中会有个缓存文件。
我们进行思考:一个网站cookie是否存在上限?我们进行查看细节问题:
(1)一个Cookie只能保存一个信息;
(2)一个web站点可以给浏览器发送多个cookie。浏览器上限大概为300个cookie,每个站点最多存放20个cookie。
(3)cookie有大小限制,限制为4KB.1KB=1024B,4KB=4096B。
删除cookie:
(1)不设置有效期,关闭浏览器,自动失效;
(2)设置有效期时间为0;
我们进行设置做到删除cookie的代码:
package com.rgf.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.crypto.Data;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
public class CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个Cookie,名字必须要和删除的名字一致
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//将cookie有效期设置为0,立马过期
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
之后我们进行编写web.xml。如下所示:
CookieDemo02
com.rgf.servlet.CookieDemo02
CookieDemo02
/c2
我们进行运行之后如下所示:
我们发现Cookie没有了。这是因为此时的Cookie已经过时了。
此时又有了cookie。
然后再请求c2的时候,cookie如下所示:
此时cookie已经又过期了。这就达到了删除cookie的目的。
我们该如何做到中文数据的传递:
我们设计的代码如下所示:
package com.rgf.servlet;
import javax.servlet.ServletException;
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.io.PrintWriter;
import java.util.Date;
import static java.lang.System.out;
//中文数据怎么传递
public class CookieDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//首先解决中文乱码问题:
//请求
req.setCharacterEncoding("utf-8");
//响应
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
Cookie[] cookies = req.getCookies(); //这里返回数组,说明cookie可能存在多个(多个标志)。
PrintWriter out = resp.getWriter();
//我们为了要获取Cookie,首先要判断Cookie是否存在,这是一个正常的程序逻辑。
//判断cookie是否存在
if (cookies!=null){ //不等于null,说明cookie有值
//如果存在cookie怎么办
//如果存在我们要取出我们想取出的数据
out.write("你上一次访问的时间是:");
//进行遍历数据
//两种for循环:
//for(Cookie cookie:cookies){}
//我们更倾向于使用下一种for循环(更加的灵活)
for (int i=0;i
之后我们编辑web.xml的文件:
CookieDemo03
com.rgf.servlet.CookieDemo03
CookieDemo03
/c3
我们运行之后如下所示:
Tomcat8之后cookie就可以存放中文啦
如果我们再编程中遇到无法去传送中文,我们可以利用:
编码解码进行解决:
编码:URLEncoder.encode("蕾峰编程","utf-8")
有编码,我们后台进行获取的时候就需要有解码:
URLDecoder.decode(cookie.getValue(),"UTF-8")。
代码如下所示:
package com.rgf.servlet;
import javax.servlet.ServletException;
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.io.PrintWriter;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import static java.lang.System.out;
//中文数据怎么传递
public class CookieDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//首先解决中文乱码问题:
//请求
req.setCharacterEncoding("utf-8");
//响应
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
Cookie[] cookies = req.getCookies(); //这里返回数组,说明cookie可能存在多个(多个标志)。
PrintWriter out = resp.getWriter();
//我们为了要获取Cookie,首先要判断Cookie是否存在,这是一个正常的程序逻辑。
//判断cookie是否存在
if (cookies!=null){ //不等于null,说明cookie有值
//如果存在cookie怎么办
//如果存在我们要取出我们想取出的数据
out.write("你上一次访问的时间是:");
//进行遍历数据
//两种for循环:
//for(Cookie cookie:cookies){}
//我们更倾向于使用下一种for循环(更加的灵活)
for (int i=0;i
我们运行之后如下所示:
发现成功进行了输出。