Cookie和Session都是为了保证访问用户与后端服务器的交互状态。这里我们谈一下Cookie的使用,javax.servlet.http.Cookie是Servlet规范中的类。
Cookie的作用:当一个用户通过HTTP访问一个服务器时,这个服务器会将一些Key/Value键值对返回给客户端浏览器,并给这些数据加上一些限制条件,在条件符合时,该用户下次访问这个服务器时,数据被完整的带回给服务器;
下图中的属性是Cookie的常用属性,如果Cookie中包含了Version1的属性,即使不设置Version的属性值,构建HTTP相应头同样会将Version设置为1;
package com.taotao.common.utils;
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;
/**
* Cookie工具类
*
* @author fxq
*
*/
public final class CookieUtils {
/**
* 得到Cookie的值
*
* @param request
* @param cookieName
* @param isDecoder
* @return
*/
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;
}
/**
* 得到Cookie的值
*
* @param request
* @param cookieName
* @param encodeString
* @return
*/
public static String getCookieValue(HttpServletRequest request,
String cookieName, String encodeString) {
// 从request中获得cookie;
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;
}
public static void deleteCookie(HttpServletRequest request,
HttpServletResponse response, String cookieName) {
doSetCookie(request, response, cookieName, "", -1, false);
}
/*
* 设置Cookie的值,并使其在指定时间内生效
*
* @param cookieMaxage cookie生效的最大秒数
*/
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();
}
}
/**
* 设置Cookie的值,并使其在指定时间内生效;
*
* @param cookieMaxage
* cookie生效的最大秒数
*/
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(cookieName, cookieValue);
}
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();
}
}
/*
* 得到cookie的域名
*/
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;
}
}
服务器端通过HttpServletRequest的getCookies()获取所有的Cookie的值,然后通过Cookie的名称获得Cookie的值;
服务器通过HttpServletResponse的addCookie()把Cookie的值加入到Response中返回给客户端。而Cookie的真正构建过程是在org.apache.catalina.connector.Response类中完成,调用generateCookieString方法把Cookie对象构建成一个字符。
Cookie通过把所有保存的数据通过HTTP的头部从客户端传递到服务端,又从服务端传回到客户端,所有的数据都存储在客户端的浏览器中。它们可以被访问到
Cookie在HTTP的头部,不能通过压缩HTTP Body来压缩Cookie。应该将多个k/v看成普通的文本,做文本压缩。Cookie中
1.不能包含控制字符
2.仅包含ASCII码为34-126的可见字符
3.必须压缩结果再次转码,Base32或者Base64
如果有就取出Cookie的值并转为List,如果没有创建一个空的list;
/**
* 取购物车商品列表
*
* @param request
* @return
*/
private List getCartItemList(HttpServletRequest request) {
try {
// 从cookie中取商品列表
String json = CookieUtils.getCookieValue(request, "TT_CART", true);
// json转成list
List list = JsonUtils.jsonToList(json, CartItem.class);
if (list != null && list.size() > 0) {
return list;
} else {
return new ArrayList();
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList();
}
}
@Override
public void addCart(Long itemId, Integer num,
HttpServletRequest request, HttpServletResponse response) {
// 1.接收商品id;
// 2.从cookie中购物车商品列表
List itemList = getCartItemList(request);
// 3.从商品列表中查询列表是否存在此商品
boolean haveFlag = false;
for (CartItem cartItem : itemList) {
if (cartItem.getId().longValue() == itemId) {// 4.如果存在商品的数量加上参数中的商品数量
cartItem.setNum(cartItem.getNum() + num);
haveFlag = true;
break;
}
}
// 5.如果不存在,调用rest服务,根据商品id获得商品数据;
if (!haveFlag) {
TbItem item = itemService.getItemById(itemId);
// 转化成CardItem;
CartItem cartItem = new CartItem();
cartItem.setId(itemId);
cartItem.setNum(num);
cartItem.setPrice(item.getPrice());
cartItem.setTitle(item.getTitle());
if (StringUtils.isNotBlank(item.getImage())) {
String image = item.getImage();
String strings[] = image.split(",");
cartItem.setImage(strings[0]);
}
// 6.把商品数据添加到列表中
itemList.add(cartItem);
}
CookieUtils.setCookie(request, response, "TT_CART", JsonUtils.objectToJson(itemList),COOKIE_EXPIRE,true);
// 7.把购物车商品列表写入cookie
// 8.返回TaotaoResult;
}