Cookie:
cookie 是 servlet 发送到 Web 浏览器的少量信息,这些信息由浏览器保存,然后发送回服务器。cookie 的值可以唯一地标识客户端,因此 cookie 常用于会话管理。
一个 cookie 拥有一个名称、一个值和一些可选属性,比如注释、路径和域限定符、最大生存时间和版本号。一些 Web 浏览器在处理可选属性方面存在 bug,因此有节制地使用这些属性可提高 servlet 的互操作性。
浏览器应该支持每台 Web 服务器有 20 个 cookie,总共有 300 个 cookie,并且可能将每个 cookie 的大小限定为 4 KB。
应用场景
自动登录、浏览记录、购物车。
为什么要有这个Cookie
http的请求是无状态。 客户端与服务器在通讯的时候,是无状态的,其实就是客户端在第二次来访的时候,服务器根本就不知道这个客户端以前有没有来访问过。 为了更好的用户体验,更好的交互 [自动登录],其实从公司层面讲,就是为了更好的收集用户习惯[大数据]
Cookie怎么用
简单使用:CookieDemo01/src/it/cast/cookie/demo/CookieDemo01.java
/**
* cookie的简单使用
*/
public class CookieDemo01 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//在服务器响应的时候,添加cookie
Cookie cookie=new Cookie("aa", "bb");
response.addCookie(cookie);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("访问成功");
//获取浏览器发过来的cookie
Cookie[] cookies = request.getCookies();
if(cookies!=null) {
for (Cookie c : cookies) {
String cookieName = c.getName();
String cookieValue = c.getValue();
System.out.println(cookieName+"="+cookieValue);
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Cookie 分类
会话Cookie: 关闭浏览器,就失效
持久cookie:存放在客户端上。 在指定的期限内有效。
setMaxAge();
cookie常用的api
实例:CookieDemo01/src/it/cast/cookie/demo/CookieDemo02.java
/**
* cookie常用的api
*/
public class CookieDemo02 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取客户端发过来的cookie
Cookie[] cookies = request.getCookies();
if(cookies!=null) {
for (Cookie ck : cookies) {
System.out.println(ck.getName()+"="+ck.getValue());
}
}
//1.添加cookie,可以写多个cookie
Cookie cookie=new Cookie("name", "zhangsan");
/*
2.这个cookie的有效期,默认如下
关闭浏览器后,cookie就没有了-->>针对没有设置cookie的有效期
expiry:有效以秒计算,
正值:表示这个数值过后,这个cookie将会失效;
负值:关闭浏览器后,这个cookie就会失效,默认是-1;
*/
cookie.setMaxAge(20);
//给cookie幅新值
//cookie.setValue(newValue);
//用于指定,只有请求了特定的域名,才会带上cookie
cookie.setDomain("www.foo.com");
//默认只有访问该域名下的cookiedemo这个路径才会带cookie
cookie.setPath("CookieDemo01");
response.addCookie(cookie);
Cookie cookie2=new Cookie("age", "18");
response.addCookie(cookie2);
response.getWriter().write("hellow cookies");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
news.baidu.com/
music.baidu.com
sport.baidu.com
...
cookie.setDomain(".itheima.com"); ---> 浏览器在访问这个域名的时候,才会带上这个cookie
cookie.setPath("/aa"); ---> 访问上面这个域名下的这个aa的路径才会带cookie 这个路径其实就是一个项目
http://www.ithiam.com:80/aa
http://localhost:8080/aa
Cookie实例1: 获取上次登录的时间
获取上次登录的时间
通过获取cookie对象判断是不是null来判断是不是第一次登录
1.若是第一次登录,则输出登录成功,并且给客户端增加保存时间的cookie;
2.若是第二次登录,先获取cookie,获取上次登录的时间,再输出上次登录的时间,并且更新时间,增加到原来的cookie里面。
Servlet: CookieDemo01/src/it/cast/cookie/demo/CookieDemo02.java
/**
* 获取上次登录的时间
* 通过获取cookie对象判断是不是null来判断是不是第一次登录
* 1.若是第一次登录,则输出登录成功,并且给客户端增加保存时间的cookie
* 2.若是第二次登录,先获取cookie,获取上次登录的时间,再输出上次登录的时间,并且更新时间,增加到原来的cookie里面。
*/
public class CookieLogin extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password=request.getParameter("password");
response.setContentType("text/html;charset=utf-8");
if ("admin".equals(username)&&"123".equals(password)) {
//登录成功
//获取cookie
Cookie[] cookies = request.getCookies();
Cookie getcookie = CookieUtil.getcookie(cookies, "last");
if (getcookie==null) {
//第一次登录,设置cookie
Cookie cookie=new Cookie("last", System.currentTimeMillis()+"");
cookie.setMaxAge(60*60);//设置生存时间
response.addCookie(cookie);//添加cookie
response.getWriter().write("登录成功"+username);
} else {
//不是第一次登录
Long lastime = Long.parseLong(getcookie.getValue());//获取上次登录时间
response.getWriter().write("登录成功"+username+"上次来访的时间是"+new Date(lastime));
getcookie.setValue(System.currentTimeMillis()+"");//设置新的时间
response.addCookie(getcookie);
}
} else {
//登录失败
response.getWriter().write("登录失败");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
cookie的工具类:CookieDemo01/src/it/cast/cookie/util/CookieUtil.java
/**
* 在cookie数组中获取指定的cookie
*/
public class CookieUtil {
public static Cookie getcookie(Cookie[] cookies,String str ) {
if (cookies!=null) {
for (Cookie c : cookies) {
if(str.equals(c.getName()))
return c;
}
}
return null;
}
}
登录页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>登录页面</h1>
<form action="CookieLogin"><br>
账号:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
Cookie实例2: 显示商品浏览记录。CookieDemo02
准备工作
1. 拷贝基础课第一天的 htmll原型文件,到工程的WebContent里面。
2. 在WebContent目录下新建一个jsp文件, product_list.jsp, 然后拷贝原来product_list.html的内容到jsp里面。 建好之后,jsp里面的所有ISO-8859-1 改成 UTF-8
拷贝html标签的所有内容。 替换jsp的html标签即可
3. 修改product_info.htm里面的手机数码超链接地址
<li class="active"><a href="product_list.jsp">手机数码<span class="sr-only">(current)</span></a></li>
4. 修改首页(index.html)顶部的手机数码跳转的位置为 product_list.jsp
<li class="active"><a href="product_list.jsp">手机数码<span class="sr-only">(current)</span></a></li>
设置浏览记录:CookieDemo02/src/it/cast/product/demo01/ProductInfoServlet.java
package it.cast.product.demo01;
import java.io.IOException;
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 it.cast.cookie.util.CookieUtil;
/**
* 设置浏览记录
*/
public class ProductInfoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取传过来的数据
String id = request.getParameter("id");
//获取cookie
Cookie[] cookies = request.getCookies();
Cookie cookie = CookieUtil.getcookie(cookies, "history");
//第一次点击
if (cookie==null) {
//增加cookie
Cookie c=new Cookie("history", id);
//设置时间
c.setMaxAge(60*60*24*7);
//设置只有在访问这个工程是才会带cookie
c.setPath("/CookieDemo02");
response.addCookie(c);
} else {
//不是第一次点击,先获取上一次访问的id
String sid = cookie.getValue();
cookie.setValue(id+"#"+sid);
//设置时间
cookie.setMaxAge(60*60*24*7);
//设置只有在访问这个工程是才会带cookie
cookie.setPath("/CookieDemo02");
response.addCookie(cookie);
}
//页面跳转
response.sendRedirect("product_info.htm");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
清除cookie:CookieDemo02/src/it/cast/product/demo01/ProductInfoServlet.java
package it.cast.product.demo01;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 清除cookie
*/
public class ClearCookie extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//演示清除cookie
Cookie cookie=new Cookie("history", "");
//设置立即删除
cookie.setMaxAge(0);
cookie.setPath("/CookieDemo02");
response.addCookie(cookie);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
商品列表页面:product_list.jsp
<ul style="list-style: none;">
<%
Cookie[]cookies=request.getCookies();
Cookie cookie=CookieUtil.getcookie(cookies, "history");
//如果是cookie空,说明是没有浏览任何商品
if(cookie==null){
%>
<h1>您还没有浏览任何商品</h1>
<%
}else{
//如果不是空,说明有浏览过其他商品,要显示出来
String[] ids=cookie.getValue().split("#");
for(String id : ids){
%>
<li style="width: 150px;height: 216;float: left;margin: 0 8px 0 0;padding: 0 18px 15px;text-align: center;"><img src="products/1/cs1000<%=id%>>.jpg" width="130px" height="130px" /></li>
<%
}
}
%>
</ul>
移除Cookie
官方没有提供delete方法。 也没有什么remove方法。
Cookie cookie = new Cookie("aa","bb");
cookie.setMaxAge(60*60*24);
reponse.addCookie(cookie);
删除cookie:
方法 一:
得到以前的cookie,然后重新设置有效期
Cookie [] cookies = request.getCookies();
Cookie cookie = CookieUtil.findCookie(cookies , "aa");
cookie.setMaxAge(0);
reponse.addCookie(cookie);
方法二:
创建一个新的cookie
Cookie cookie = new Cookie("aa","xx");
cookie.setMaxAge(0);
reponse.addCookie(cookie);
Cookie总结:
1. 服务器给客户端发送过来的一小份数据,并且存放在客户端上。
2. 获取cookie, 添加cookie
request.getCookie();
response.addCookie();
3. Cookie分类
会话Cookie
默认情况下,关闭了浏览器,那么cookie就会消失。
持久Cookie
在一定时间内,都有效,并且会保存在客户端上。
cookie.setMaxAge(0); //设置立即删除
cookie.setMaxAge(100); //100 秒
Cookie的安全问题:
由于Cookie会保存在客户端上,所以有安全隐患问题。 还有一个问题, Cookie的大小与个数有限制。 为了解决这个问题 ---> Session 。
Session
是什么?
也是一种会话技术, 基于cookie的一种会话技术。
cookie 是可以把数据存放在客户端, 下一次来访的时候,带上那个数据,服务器就知道客户端是谁了。 ---》 安全隐患。
Session : 数据存放在服务器端。 并且把这个session对应的sessionID ,传递给客户端, 是通过Cookie去传递的。会在cookie里面添加一个字段 JSESSIONID ,是tomcat服务器生成。 下一次客户端在来访的时候,带上那个sessionID ,就可以取到以前的数据了。
session的常用方法
//获取session
HttpSession session = request.getSession();
//得到会话的id
String id = session.getId();
//存值
session.setAttribute("name", "value");
//取值
session.getAttribute("name");
//删除值
session.removeAttribute("name");
//强制让会话失效
session.invalidate() ;
Session何时创建 , 何时销毁?
创建:
如果有在servlet里面调用了 request.getSession()就会创建;
销毁:
session 是存放在服务器的内存中的一份数据。 当然可以持久化. Redis . 即使关了浏览器,session也不会销毁。
1. 关闭服务器
2. session会话时间过期。 有效期过了,默认有效期: 30分钟。
关闭浏览器, session会销毁嘛?
不会,为什么? ---> 因为这个session 数据是存放在服务器的内存中的。
那么为什么再一次开启浏览器访问的时候,无法取到以前的数据。
因为sessionid是通过cookie来传递的。 但是这个cookie并没有设置有效期。 所以关闭浏览器之后, cookie就删除了。
表明里面的那个sessionID 也就没有了。下一次再来访问。 如果还想在下一次访问的时候,取到以前的数据。
1. 在服务器端手动设置cookie
String id = request.getSession().getId();
Cookie cookie = new Cookie("JSESSIONID",id);
cookie.setMaxAge(60*60*24*7);//7天
reponse.addCookie(cookie);
Session实例:简单购物车
SessionDemo02
商品列表:product_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="CarServlet?id=0"><h3>iphone1</h3></a><br>
<a href="CarServlet?id=1"><h3>小米8</h3></a><br>
<a href="CarServlet?id=2"><h3>华为9</h3></a><br>
<a href="CarServlet?id=3"><h3>锤子5</h3></a><br>
<a href="CarServlet?id=4"><h3>三星node2</h3></a><br>
</body>
</html>
添加购物车的servlet:SessionDemo02/src/it/cast/session/demo/CarServlet.java
package it.cast.session.demo;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
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.servlet.http.HttpSession;
/**
* 添加到购物车
* map集合是购物车数据,map集合在session里边
* map集合里边string是商品名,Integer是商品数量
*/
public class CarServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//获取客户端传来的商品id
int id = Integer.parseInt(request.getParameter("id"));
String[]names= {"iphone1","小米8","华为9","锤子5","三星node2"};
//获取商品id对应的商品名称
String name=names[id];
/**
* 正常情况下,关闭浏览器,再次访问时,这个session就会失效,就无法获取以前的数据,
* 因为他是通过coookie并来传递的这个cookie并没有设置生存期限。
* 解决方法:手动设置cookie的生存期限。
*/
String jsid = request.getSession().getId();
Cookie jscookie=new Cookie("JSESSIONID", jsid);
jscookie.setMaxAge(60*60*24*7);
response.addCookie(jscookie);
//把一个map对象放到session里边,保证只存放一次
Map<String, Integer>map=(Map<String, Integer>) request.getSession().getAttribute("car");
//如果是空,说明session里面没有存东西
if (map==null) {
//新建map集合,添加到session里边
map=new LinkedHashMap<String, Integer>();
request.getSession().setAttribute("car", map);
}
//判断购物车里面有没有这个商品
if(map.containsKey(name)) {
//若有,则原来的数量+1
map.put(name, map.get(name)+1);
}else {
//要是没有则数量是1
map.put(name, 1);
}
//页面跳转
response.getWriter().write("<a href='product_list.jsp'><h3>继续购物</h3></a>");
response.getWriter().write("<a href='cart.jsp'><h3>购物车结算</h3></a>");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
购物车页面:cart.jsp
<%@page import="java.util.Map"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--购物车页面 -->
<h2>你的购物车页面 </h2>
<%
//获取map集合
Map<String,Integer>map=(Map<String,Integer>)session.getAttribute("car");
if(map!=null){
for(String key:map.keySet()){
int value=map.get(key);
//key是商品名称,value是商品数量
%>
<h3><%=key %>的数量是<%=value %>个</h3>
<%
}
}
%>
<a href="ClearCart">清除购物车</a>
<a href="product_list.jsp"><h3>返回继续购物</h3></a>
</body>
</html>
清空购物车:ClearCart.java
package it.cast.session.demo;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 清楚购物车的servlet
*/
public class ClearCart extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
//清楚session里面的数据
session.removeAttribute("car");
//直接删除session
//session.invalidate();
//页面跳转
response.sendRedirect("cart.jsp");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
Session只是一块在服务器中的存储区域,和cookie一样,以key和value的方式存储数据。