7.Session、Cookie
7.1、会话
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话
你能怎么证明你在Qunar上班?
你 Qunar
1.工牌 Qunar给你工牌
2.Qunar登记 Qunar标记你是Qunar员工
一个网站怎么证明你来过?
客户端 服务端
1.服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了。Cookie
2.服务器登记你来过了,下次你来的时候,我来匹配你。Session
7.2、保存会话的两种技术
Cookie
- 客户端技术(服务端响应,客户端请求)
Session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在Session中
常见场景:
网站登录之后,你下次不用再登录了,第二次发访问直接就上去了(例如:哔哩哔哩,csdn等,即使你关闭了浏览器,下次还是不用登录)
7.3、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的有效期【思考:如果这里参数传0会怎样?】
resp.addCookie(cookie);//响应给客户端一个cookie
Cookie:一般会保存在本地的用户目录下AppData下
一个网站cookie是否存在上限?聊聊细节问题
- 一个Cookie最能保存一个信息
- 一个web站点,可以给浏览器发送多个Cookie,最多存放20个Cookie
- Cookie大小有限制:4KB
- 300个cookie,浏览器上限
删除Cookie
- 不设置有效期,关闭浏览器,自动失效
- 设置有效期为0
编码&解码:
URLEncoder.encode("工一","utf-8")
URLDecoder.decode(value,"UTF-8");
代码show
CookieDemo01.java
package com.gongyi.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;
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器,告诉你,你来的时间,把这个时间封装为一个信件,我就知道你来了
//解决中文乱码
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
System.out.println("哈哈,我进入了这个方法");
PrintWriter out = resp.getWriter();
//Cookie,服务端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断Cookie是否存在
if (cookies != null) {
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取Cookie的名字
if (cookie.getName().equals("lastLoginTime")) {
//获取Cookie中的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
} else {
out.write("这是您第一次访问本站!");
}
//服务器给客户端相应一个Cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
//Cookie有效期为1天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
CookieDemo02.java
package com.gongyi.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;
//保存用户上一次访问的时间
public class CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个cookie,名字必须要和删除的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);
}
}
CookieDemo03.java
package com.gongyi.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;
//中文数据传递
public class CookieDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
//Cookie,服务端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明cookie可能存在多个
//判断Cookie是否存在
if (cookies != null) {
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取Cookie的名字
if (cookie.getName().equals("name")) {
//获取Cookie中的值
String value = cookie.getValue();
System.out.println(value);
out.write(URLDecoder.decode(value,"UTF-8"));//解码
}
}
} else {
out.write("这是您第一次访问本站!");
}
Cookie cookie = new Cookie("name", URLEncoder.encode("工一","utf-8"));//编码,防止中文乱码
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
<servlet>
<servlet-name>CookieDemo01</servlet-name>
<servlet-class>com.gongyi.servlet.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo01</servlet-name>
<url-pattern>/c1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo02</servlet-name>
<servlet-class>com.gongyi.servlet.CookieDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo02</servlet-name>
<url-pattern>/c2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>CookieDemo03</servlet-name>
<servlet-class>com.gongyi.servlet.CookieDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CookieDemo03</servlet-name>
<url-pattern>/c3</url-pattern>
</servlet-mapping>
</web-app>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gongyi</groupId>
<artifactId>javaweb-session-cookie</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
</project>
彩蛋
1.idea创建java web项目方式
1)添加web支持
2)通过maven创建
通过maven模板创建
非模板创建
2.maven的artifactId与ProjectName命名问题
最好后者和前者保持一致,更规范,美观
3.idea右边的maven依赖与左侧不一致,以左侧为准,重启IDea就行了。应该是idea的缓存的一个bug
4.idea 用maven模板创建web项目步骤
1)以模板新建项目,projectName要与artifactId一致
2)补全包,在main下新建java和resources包,分别标记为源码根目录和资源根目录
3)替换web.xml,和tomcat demo中的一致,使用4.0约束
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true">
</web-app>
只保留web-app根标签
4)pom中删除不必要东西,只保留gav坐标及打包方式
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.gongyi</groupId>
<artifactId>javaweb-session-cookie</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
</project>
5)pom中引入依赖,一般在artifactId中输入,回车就会自动识别
servlet和jsp核心包
servlet-api
jsp-api
5.在java中万物皆对象,万物皆有API
从源码中看API
6.没有IO做不了的东西(存储:本地,数据库等)
7.idea BUG
在写servlet时,继承HttpServlet找不到问题
场景:
pom中先是依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0.1</version>
</dependency>
然后Servlet继承HttpServlet找不到,
后改为:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
还是找不到,idea右侧更新maven(依赖都变成最新的了)还是不行
然后关闭idea重启好了
8.servlet设置了编码还是浏览器响应乱码:
原来:
resp.setCharacterEncoding("utf-8");
现在:
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
9.idea System.out.println(“哈哈,我进入了这个方法”);乱码
1)文件右键设置文件编码为UTF-8,不管用
解决:
在idea的vmoptions和tomcat的vm option中添加:
-Dfile.encoding=utf-8
10.浏览器查看Cookie与删除Cookie
查看Cookie
删除Cookie
11.Cookie是如何传递到服务端的?
第一次:
请求:
响应:
第二次:
请求:
响应:
设置过期时间:【正常有效期从打开浏览器开始到关闭浏览器结束,setMaxAge()可以自定义cookie有效期】
//Cookie有效期为1天
cookie.setMaxAge(24*60*60);
12.查看本机的cookie文件