Cookie 是由服务器发给客户端的特殊信息,客户端将这些信息以文本文件的形式存放在本地,客户端每次向服务器发送请求时都会带上这些信息。从 HTTP 协议的角度理解 Cookie 的话,它实际上是一个通行证,弥补了 HTTP 协议是无状态的不足,服务器可以通过 Cookie 确认客户的身份。
Cookie 具有不可跨域名的特性,例如访问百度时,客户端浏览器只会将百度生成的 Cookie 发送给百度服务器,访问谷歌时,客户端浏览器只会将谷歌生成的 Cookie 发送给谷歌服务器。对于同属于百度的网站,例如 www.baidu.com 和 news.baidu.com ,这两个域名的一级域名不同,因此 Cookie 是不通用的。当然,我们可以通过代码设置 Cookie 的有效域名解决 Cookie 不同用的问题,例如:
Cookie cookie = new Cookie("name","yz"); // 新建Cookie
cookie.setDomain(".baidu.com"); // 设置有效域名
cookie.setPath("/"); // 设置 Cookie 的有效路径
cookie.setMaxAge(Integer.MAX_VALUE); // 设置有效期
response.addCookie(cookie); // 输出到客户端
1、setDomain 表示的是 cookie 所在的有效域名,默认为请求的域名地址。假如我们想让域 A 生成的 Cookie 只在域 B 上有效,在域 A 的代码中设置 setDomain(“B.xxx.com”)即可
2、setPath 表示的是 cookie 的有效目录,默认为 / ,即项目的根目录。例如:/jsps/main/a.jsp、/jsps/main/list/b.jsp,
# 设置的 path 为 / ,那么 / 下的页面和 /jsps、/jsps/main/、/jsps/main/list/ 下的页面都可以使用 cookie
setPath("/")
# 设置的 path 为 /jsps/main/list/ ,那么只有 /jsps/main/list/ 下的页面可以使用 cookie,其它的路径不能使用
setPath("/jsps/main/list")
3、浏览器会将 domain 和 path 都相同的 cookie 保存在一个文件里,cookie 之间用 * 隔开
4、Cookie 用键值对存储自定义信息时,对于中文,只能存储编码后的中文,一般使用 utf-8 编码
session 是服务器端使用的一种会话跟踪技术。用户访问服务器时,如果 Session 不存在,服务器创建 Session ,同时给它生成唯一的 session id,并保存在 Cookie 中,当客户端再次请求时,会带上这个 session id 标识,服务器根据这个标识找到相应的 session;如果没有找到,服务器会创建 Session,生成 session id 并保存在 Cookie 中。需要注意的是,只有访问 JSP、Servlet 等程序时才会创建 Session,而访问 HTML 等静态资源时不会创建,当然我们可以调用 request.getSession(true) 强制生成 session。
服务器端为了提高 Session 的存取速度,session 被放在内存中,如果 session 信息过多,服务器可能出现内存溢出的情况,因此服务器会根据 Session 的超时时间删除上时间没有活跃的 session。Tomcat 的session 默认超时时间为 20m。
Session 的实现是依赖 Cookie 的,由于 HTTP 是无状态的协议,Session 不能根据 HTTP 连接来判断是否为同一个客户,因此服务器想客户端浏览器发送一个名为 JSESSIONID 的 Cookie,它的值为 Session 的 id。
Session 依赖于 Cookie 实现,如果客户端浏览器禁用了 Cookie 或者是浏览器根本不支持 Cookie 时,那么 Session 也就没什么用了。可以通过 URL 地址重写代替 Cookie,将该用户的 session id 信息重写到 URL 地址中,服务器能够解析重写后的 URL 并获取 session id。
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @ClassName: CookieUtils
* @Description: cookie
* @author
* @date 2018年3月14日 下午3:48:14
* @Copyright: 2018
*
*/
public final class CookieUtils {
/**
*
* @Title: getCookieValue
* @Description: 获取Cookie的值, 不编码
* @param request
* @param cookieName
* cookie 名称
* @return
* @date 2018年3月14日 下午3:48:44
* @author
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
*
* @Title: getCookieValue
* @Description: 获取Cookie的值
* @param request
* @param cookieName
* cookie 名称
* @param isDecoder
* 是否解码
* @return
* @date 2018年3月14日 下午3:49:06
* @author
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
if (isDecoder) {
retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
} else {
retValue = cookieList[i].getValue();
}
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
*
* @Title: getCookieValue
* @Description: 获取Cookie的值
* @param request
* @param cookieName
* cookie 名称
* @param encodeString
* 编码格式
* @return
* @date 2018年3月14日 下午3:50:13
* @author
*/
public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
Cookie[] cookieList = request.getCookies();
if (cookieList == null || cookieName == null) {
return null;
}
String retValue = null;
try {
for (int i = 0; i < cookieList.length; i++) {
if (cookieList[i].getName().equals(cookieName)) {
retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
break;
}
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retValue;
}
/**
*
* @Title: setCookie
* @Description: 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @date 2018年3月14日 下午3:51:11
* @author
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
*
* @Title: setCookie
* @Description: 设置Cookie的值 在指定时间内生效,但不编码
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @param cookieMaxage
* cookie 有效期
* @date 2018年3月14日 下午3:51:46
* @author
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
*
* @Title: setCookie
* @Description: 设置Cookie的值 不设置生效时间,但编码
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @param isEncode
* 是否编码
* @date 2018年3月14日 下午3:52:18
* @author
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
*
* @Title: setCookie
* @Description: 设置Cookie的值 在指定时间内生效, 编码参数
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @param cookieMaxage
* cookie 有效期,秒
* @param isEncode
* 是否编码
* @date 2018年3月14日 下午3:53:03
* @author
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
*
* @Title: setCookie
* @Description: 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @param cookieMaxage
* cookie 有效期,秒
* @param encodeString
* 编码格式
* @date 2018年3月14日 下午3:53:47
* @author
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
*
* @Title: deleteCookie
* @Description: 删除Cookie带cookie域名
* @param request
* @param response
* @param cookieName
* cookie 名称
* @date 2018年3月14日 下午3:55:01
* @author
*/
public static void deleteCookie(HttpServletRequest request, HttpServletResponse response, String cookieName) {
doSetCookie(request, response, cookieName, "", -1, false);
}
/**
*
* @Title: doSetCookie
* @Description: 设置Cookie的值,并使其在指定时间内生效
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @param cookieMaxage
* cookie 有效期,秒
* @param isEncode
* 是否编码
* @date 2018年3月14日 下午3:55:24
* @author
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, boolean isEncode) {
try {
if (cookieValue == null) {
cookieValue = "";
} else if (isEncode) {
cookieValue = URLEncoder.encode(cookieValue, "utf-8");
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @Title: doSetCookie
* @Description: 设置Cookie的值,并使其在指定时间内生效
* @param request
* @param response
* @param cookieName
* cookie 名称
* @param cookieValue
* cookie 值
* @param cookieMaxage
* cookie 有效期,秒
* @param encodeString
* 编码格式
* @date 2018年3月14日 下午3:56:13
* @author
*/
private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
String cookieValue, int cookieMaxage, String encodeString) {
try {
if (cookieValue == null) {
cookieValue = "";
} else {
cookieValue = URLEncoder.encode(cookieValue, encodeString);
}
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0)
cookie.setMaxAge(cookieMaxage);
if (null != request) {// 设置域名的cookie
String domainName = getDomainName(request);
System.out.println(domainName);
if (!"localhost".equals(domainName)) {
cookie.setDomain(domainName);
}
}
cookie.setPath("/");
response.addCookie(cookie);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* @Title: getDomainName
* @Description: 获取 cookie 的域名
* @param request
* @return
* @date 2018年3月14日 下午3:56:52
* @author
*/
private static final String getDomainName(HttpServletRequest request) {
String domainName = null;
String serverName = request.getRequestURL().toString();
if (serverName == null || serverName.equals("")) {
domainName = "";
} else {
serverName = serverName.toLowerCase();
serverName = serverName.substring(7);
final int end = serverName.indexOf("/");
serverName = serverName.substring(0, end);
final String[] domains = serverName.split("\\.");
int len = domains.length;
if (len > 3) {
// www.xxx.com.cn
domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
} else if (len <= 3 && len > 1) {
// xxx.com or xxx.cn
domainName = "." + domains[len - 2] + "." + domains[len - 1];
} else {
domainName = serverName;
}
}
if (domainName != null && domainName.indexOf(":") > 0) {
String[] ary = domainName.split("\\:");
domainName = ary[0];
}
return domainName;
}
}