cookie与session是老生常谈的问题了,之前一直的认知是从测试视角,并不全面,这次通过开发的时间对cookie与session进行一个全面的挖底
什么是cookie?
cookie 是服务器通知客户端保存kv对的一种技术
- 客户端有了cookie之后,每次请求都发送给服务器
- 每个cookie的大小不能超过4kb,,简单记忆 1个饼干4kb
如何创建cookie?
```java
public class CookieServlet extends BaseServlet {
/*
* @Author shihu
* @Description //TODO 创建cookied方法
* @Date 9:22 下午 2021/9/12
* @Param [req, resp]
* @return void
**/
public void createCookie(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建cookie对象
Cookie cookie = new Cookie("key1", "value1");
// 通知客户端保存cookie
resp.addCookie(cookie);
resp.getWriter().write("cookie创建成功");
}
// baseServlet 为封装类,进行一些提前的处理,不用在意
- 创建cookie对象,同时调用有参构造进行值设定
- 通知客户端保存cookie
```java
如何创建cookie
客户端(浏览器 ) 服务器(tomcat
----》 1 创建 cookie对象
Cookie cookie = new Cookie("key1","value1");
通过响应头 set-cookie 2 通知客户端保存cookie
收到响应后,发现有 通知客户端进行保存cookie
set-cookie响应头
就去查看是否有cookie
没有则创建,有则修改 《----- response.setCookie(cookie)
注意:
一句话代码 req.getCookies();cookie[] 方法返回为一个数组
public void getCookie(HttpServletRequest request, HttpServletResponse response) throws IOException { Cookie[] cookies = request.getCookies(); // servlet 原生没有提供根据cookie name来去查砸后value的方法,所以只能通过for循环来进行查找 // 但是可以按照这个思路来进行封装 for (Cookie cookie : cookies) { // response.getWriter().write(cookie.getName()); // response.getWriter().write(cookie.getValue()); if ("key1".equals(cookie.getName())){ System.out.println("找到了自己想要的哪个cookie"); System.out.println(cookie.getValue()); } } }
需要注意的是,httpservlet没有提供像map那样根据cookie的name求获取value的方法,所以需要自行封装 ```java public class CookieUtils { /**
- 查找指定名称的Cookie对象
- @param name
- @param cookies
@return */ public static Cookie findCookie(String name , Cookie[] cookies){ if (name == null || cookies == null || cookies.length == 0) {
return null;
}
for (Cookie cookie : cookies) {
if (name.equals(cookie.getName())) { return cookie; }
}
return null; }
}
<a name="ssrDs"></a>
# Cookie的修改
- 方案一
- 1 先创建一个要修改的同名cookie对象
- 在构造器方法时同时赋新值
- 调用response.addCookie
- 方案二
- 先查到要修改的cookie对象
- 调用setVlue()方法进行修改
- response.addCookie
- 方案二需要要修改的目标cookie必须存在
```java
// 对cookie 进行修改
// 1 首先创建一个要修改的同名的cookie对象
// 2 在构造器,同时赋予新的cookie值
Cookie cookie = new Cookie("key1", "newValue1");
// 3 调用response.addCookie(cookie) // 通知客户端保存修改之后的cookie
response.addCookie(cookie);
// 方案2
// 1 先查找到需要修改的cookie对象
cookie = CookieUtils.findByCookieName("cookieName")
// 2 调用setValue 方法来赋予新的cookie值
// 3 调用response.add(cookie) 方法
// cookie 的值不能包含空格,特殊符号,中文
Cookie的生命控制
- 其实也就是cookie的持续时间控制,管理cookie什么时间被销毁(删除
- 相关方法为 setMaxAge()
```java
public void setMaxAge(int expiry) {
}this.maxAge = expiry;
- expiry 为 正数,在指定的秒数后过期
- 为负数,表示浏览器已关闭,cookie就删除,默认为-1
- 0 表示马上删除cookie
<a name="vCgF7"></a>
# Cookie有效路径path的设置
- cookie的path属性可以有效的过滤哪些cookie可以发送给服务器,哪些则不行
- path属性是通过请求的地址来进行有效的过滤的
```java
cookieA path=/工程路径
cookieB path=/工程路径/abc
请求路径如下
http://ip:port/工程路径/a.html
cookieA 发送
cookieB 不发送
http://ip:port/工程路径/abc/a.html
cookieA 发送
cookieB 发送
经过这样设计的cookie 在非对应的path下是看不到该cookie存在的
public void testPath(HttpServletRequest request,HttpServletResponse response) throws IOException {
Cookie cookie = new Cookie("key233","value233");
// getContexzpath 得到工程路径
cookie.setPath(request.getContextPath() + "/abc"); // 得到工程路径后的abc
response.addCookie(cookie);
response.getWriter().write("创建了一个带有path的cookie");
}
Session 会话
- 是什么
- session就是一个接口 httpSession
- session 就是会话, 用来维护一个客户端和服务器之间关联的一种技术
- 每个客户端都有一个session会话
- session会话中经常用来保存用户登录之后的信息
cookie 是保存在客户端-浏览器中的。session是保存在 服务器端的。
如何创建session和获取session
创建和获取session的api是一样的
- request.getSession()
- 判断是否为新创建出来的session ,isNew()
如何创建和获取session,api是一样的
request.getSession()
第一次调用是:创建session会话
之后调用都是,获取前面创建好的session会话对象
针对如何判断session是否为最新创建的。httpServlet提供了一个api
isNew() 判断到底是不是刚创建出来的(新的)
true 表示刚创建
false 表示获取之前创建的
每个会话都有一个身份号,也就是id值,且id是唯一的
getId()获取session的会话id值
public class SessionServlet extends BaseServlet {
public void createOrGetSession(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建和获取session会话对象
HttpSession session = req.getSession();
// 判断 当前session会话,是否是新创建出来的
boolean aNew = session.isNew();
String id = session.getId();
resp.getWriter().write("得到的sessionid为:"+ id);
resp.getWriter().write("得到的session是否为新创建的:"+ aNew);
}
Session 域数据存取
同servletContext,servletRequest对象一样,可以对域内变量进行数存取
# session域数据的存取 public void setAttribute(HttpServletRequest request,HttpServletResponse response) throws IOException { request.getSession().setAttribute("username","addicated"); response.getWriter().write("向session中存储数据成功ing"); } public void getAttribute(HttpServletRequest request, HttpServletResponse response) throws IOException { Object username = request.getSession().getAttribute("username"); response.getWriter().write(" 从session中取出的数据是 "+ username); } 1 通过session对象。setAttr ,getAttr即可
Session 的生命控制
void setMaxInactiveInterval(int var1);
- 设置超时时间,超过指定的时间,session就会销毁
- 单位为秒
- 正数 设置超时时间
- 负数 表示永不超时
- 单位为秒
- 设置超时时间,超过指定的时间,session就会销毁
- int getMaxInactiveInterval();
- 获取当前项目/服务器中对session超时时间的配置
void invalidate();
默认为1800秒,即30min
- 那么这个默认时间从何而来?
- 是从tomcat下的web.xml 中进行的配置,表示所有部署在tomcat服务器上的项目的默认会话超时时间
修改
区别于一般意义上的超时,session超时指的是两次请求之间间隔的最大时长 ```java session超时的概念,指的是客户端两次请求的最大间隔时长 客户端(浏览器 设置3秒超时 服务器(tomcat
-----》 session对象 开始倒计时 timeout=3 timeout=2 timeout=1 间隔1秒或者两秒 对服务器请求 timeout=0 ------》 timeout重新刷新为3 原因就是因为 session的过期机制实际上是两次请求之间的间隔超过过期时间,判定session过期 如果在session的过期时间内发生了再次请求,就会重置过期时间
浏览器和Session之间关联的技术内幕
- 如下图