Cookie認識與使用

00潤物無聲00發表於2017-03-06

  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壓縮:

  Cookie在HTTP的頭部,不能通過壓縮HTTP Body來壓縮Cookie。應該將多個k/v看成普通的文字,做文字壓縮。Cookie中

1.不能包含控制字元

2.僅包含ASCII碼為34-126的可見字元

3.必須壓縮結果再次轉碼,Base32或者Base64


在Cookie中新增商品列表

   如果有就取出Cookie的值並轉為List,如果沒有建立一個空的list;

/**
	 * 取購物車商品列表
	 * 
	 * @param request
	 * @return
	 */
	private List<CartItem> getCartItemList(HttpServletRequest request) {
		try {
			// 從cookie中取商品列表
			String json = CookieUtils.getCookieValue(request, "TT_CART", true);

			// json轉成list
			List<CartItem> list = JsonUtils.jsonToList(json, CartItem.class);
			if (list != null && list.size() > 0) {
				return list;
			} else {
				return new ArrayList<CartItem>();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return new ArrayList<CartItem>();
		}
	}

        @Override
	public void addCart(Long itemId, Integer num,
			HttpServletRequest request, HttpServletResponse response) {

		// 1.接收商品id;
		// 2.從cookie中購物車商品列表
		List<CartItem> 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;
	}

 針對Cookie做快取提高資料的訪問效能,可以臨時存放資料。



相關文章