Cookie
Cookie 翻译过来是饼干的意思
Cookie 是服务器通知客户端保存键值对的一种技术
客户端有了 Cookie 后,每次请求都发送给服务器
每个 Cookie 的大小不能超过 4kb
Cookie 的创建
Cookie cookie = new Cookie("key1", "value1");
resp.addCookie(cookie);
resp.getWriter().write("Cookie 创建成功");
通过浏览器访问此 Servlet 程序:
获取 Cookie
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
resp.getWriter().write(cookie.getName() + " = " + cookie.getValue() + "<br/>");
}
在浏览器中访问此 Servlet 程序:
Cookie 的修改
// 修改 Cookie 方案一:
Cookie cookie = new Cookie("key1", "newValue2");
resp.addCookie(cookie);
resp.getWriter().write("修改 " + cookie.getName() + " = " + cookie.getValue() + " 成功 <br/>");
// 修改 Cookie 方案二:
cookie = CookieUtils.findCookie("key2", req.getCookies());
cookie.setValue("newValue2");
resp.addCookie(cookie);
resp.getWriter().write("修改 " + cookie.getName() + " = " + cookie.getValue() + " 成功 <br/>");
在浏览器中访问此 Servlet 程序:
Cookie 存活时间
Cookie 的生命控制指的是如何管理 Cookie 什么时候被销毁(删除)
void setMaxAge(int expiry)
- 正数:表示多少秒后销毁
- 0:表示立即销毁
- 负数:表示会话结束后销毁(默认值,-1)
关闭浏览器后重新打开:
Cookie 的 path 属性
Cookie 的 path 属性可以有效的过滤哪些 Cookie 可以发送给服务器 哪些不发
path 属性是通过请求的地址来进行有效的过滤。
CookieA:path = /工程路径
CookieB:path = /工程路径/geekfx
请求地址如下:
http://ip:port/工程路径/a.html
- CookieA:发送
- CookieB:不发送
http://ip:port/工程路径/geekfx/b.html
- CookieA:发送
- CookieB:发送
Cookie cookieA = new Cookie("CookieA", "geekfx");
cookieA.setPath(req.getContextPath());
Cookie cookieB = new Cookie("CookieB", "geekfx");
cookieB.setPath(req.getContextPath() + "/geekfx");
resp.addCookie(cookieA);
resp.addCookie(cookieB);
执行 Servlet 程序后:
在 http://ip:port/工程路径
下查看 cookie:
将浏览器地址栏地址还为 http://ip:port/工程路径/geekfx/b.html
(实际没有此目录和页面):
查看 cookie 信息和请求头信息:
Cookie 免用户名登录
<body>
<form action="cookieLoginServlet" method="get">
用户名:<input type="text" name="username" value="${cookie.username.value}"> <br>
密码:<input type="password" name="password" value="${cookie.password.value}"> <br>
<input type="submit">
</form>
</body>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println("进入 doGet() 方法");
// 模拟登录 写死了用户名和密码
if("geekfx".equals(username) && "123".equals(password)) {
System.out.println("登陆成功");
Cookie cookie = new Cookie("username", username);
cookie.setMaxAge(60 * 60 * 24 * 7);
resp.addCookie(cookie);
cookie = new Cookie("password", password);
cookie.setMaxAge(60 * 60 * 24 * 7);
resp.addCookie(cookie);
} else {
System.out.println("登陆失败");
req.getRequestDispatcher("/login.jsp").forward(req, resp);
}
}
在浏览器输入正确的用户名和密码
关闭浏览器,再次打开登录页面:
Session 会话
Session 就一个接口(HttpSession)
Session 就是会话。它是用来维护一个客户端和服务器之间关联的一种技术
每个客户端都有自己的一个 Session 会话
Session 会话中,我们经常用来保存用户登录之后的信息
创建/获取 Session 对象
HttpSession request.getSession();
第一次调用是创建 Session 会话
之后调用都是获取前面创建好的 Session 会话对象
boolean isNew();
判断当前 Session 会话对象是否是新创建的
返回 true 表示新创建的
返回 false 表示不是新创建的
String getId();
每个会话都有一个唯一标识的 id 号
HttpSession session = req.getSession();
resp.getWriter().write("当前 Session 对象:" + session + "<br/>");
resp.getWriter().write("是否新创建:" + session.isNew() + "<br/>");
resp.getWriter().write("Session id:" + session.getId() + "<br/>");
第一次访问此 Servlet 程序时:
在不关闭浏览器的情况下重新访问:
Session 域
Session 也是 JSP 四大域对象之一,可以存取数据
// Session 域数据的存储
req.getSession().setAttribute("key1", "value1");
resp.getWriter().write("Session 域数据存放成功");
// Session 域数据读取
String attribute = (String) req.getSession().getAttribute("key1");
resp.getWriter().write("当前 Session 域数据:" + "key1 = " + attribute);
Session 生命周期
int getMaxInactiveInterval();
获取当前 Session 对象的超时时间,单位为秒,默认 30 分钟(Tomcat)void setMaxInactiveInterval(int interval);
设置当前 Session 对象的超时时间,单位为秒
正数:Session 对话超时的秒数
负数:永不超时void invalidate();
使当前 Session 会话立即无效
为什么说 Session 的默认超时时长是 30 分钟,因为在 IDEA 整合的 Tomcat 服务器中的配置文件,配置了所有 Session 会话的超时时长默认为 30 分钟:
如果想修改某个 web 工程下的所有 Session 会话时长默认时长,可以在 web 工程下的 web.xml 配置文件中配置:
protected void invalidate(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.invalidate();
resp.getWriter().write("当前 Session 会话已被销毁");
}
protected void setMaxInactiveInterval(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
int interval = CookieUtils.parseInt(req.getParameter("interval"), 3600);
HttpSession session = req.getSession();
session.setMaxInactiveInterval(interval);
resp.getWriter().write("当前 Session 会话超时时长设置为:" + interval + " 秒");
}
protected void defaultLife(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
int maxInactiveInterval = session.getMaxInactiveInterval();
resp.getWriter().write("当前 Session 会话的超时时长:" + maxInactiveInterval + " 秒");
}
浏览器和 Session 关联
在浏览器没有任何 cookie 的情况下访问服务器:
访问之后,查看浏览器的响应头和 cookie 信息:
后面再次访问服务器并试图获取 session 对象,浏览器会将 cookie 信息发送给服务器,包括 JSESSIONID 的 cookie 信息: