All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.feilong.servlet.http.CookieUtil Maven / Gradle / Ivy

Go to download

feilong is a suite of core and expanded libraries that include utility classes, http, excel,cvs, io classes, and much much more.

There is a newer version: 4.0.8
Show newest version
/*
 * Copyright (C) 2008 feilong
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.feilong.servlet.http;

import static com.feilong.core.Validator.isNotNullOrEmpty;
import static com.feilong.core.Validator.isNullOrEmpty;
import static java.util.Collections.emptyMap;

import java.util.Collections;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.feilong.core.bean.PropertyUtil;
import com.feilong.json.JsonUtil;
import com.feilong.core.Validate;
import com.feilong.servlet.http.entity.CookieEntity;

/**
 * {@link javax.servlet.http.Cookie Cookie} 工具类.
 * 
 * 

说明:

*
* *

* 注意:该类创建Cookie仅支持 Servlet3 以上的版本 *

* *

* 不建议直接调用这个类,可以使用feilong-accessor CookieAccessor 含有更多的特性和更简便,更易管理的配置 *

* * 依赖方式: * *
 * {@code 
 *  
 *      com.feilong.platform
 *      feilong-accessor
 *  
 * }
 * 
* *
* *

使用说明:

* *

* case:创建Cookie *

* *
*

* 1.创建一个name名字是shopName,value是feilong的 Cookie (通常出于安全起见,存放到Cookie的值需要加密或者混淆,此处为了举例方便使用原码)
* 可以调用{@link #addCookie(String, String, HttpServletResponse)}
* 如: *

* *

* CookieUtil.addCookie("shopName","feilong",response) *

* *

* 注意:该方法创建的cookie,有效期是默认值 -1,即浏览器退出就删除 *

* *

* 2.如果想给该cookie加个过期时间,有效期一天,可以调用 {@link #addCookie(String, String, int, HttpServletResponse)}
* 如: *

* *

* CookieUtil.addCookie("shopName","feilong", SECONDS_PER_DAY,response) *

* *

* 3.如果还想给该cookie加上httpOnly等标识,可以调用 {@link #addCookie(CookieEntity, HttpServletResponse)}
* 如: *

* *
 * CookieEntity cookieEntity = new CookieEntity("shopName", "feilong", SECONDS_PER_DAY);
 * cookieEntity.setHttpOnly(true);
 * CookieUtil.addCookie(cookieEntity, response);
 * 
* *

* 此外,如果有特殊需求,还可以对cookieEntity设置 path,domain等属性 *

*
* *

* case:获取Cookie *

* *
* *
* 特殊说明: *
* *

* 在读取Cookie 操作时,除了 {@link Cookie#getName()},{@link Cookie#getValue()} 外,不要妄图得到其他信息,如下方法不会得到值的: * * {@link Cookie#getMaxAge()}; * {@link Cookie#getDomain()}; * ... * * 因为,客户端传来的时候,就只剩下key和value *

* *

* 1.可以使用 {@link #getCookie(HttpServletRequest, String)}来获得 {@link Cookie}对象 *
* 如: *

* *

* CookieUtil.getCookie(request, "shopName") *

* *

* 2.更多的时候,可以使用 {@link #getCookieValue(HttpServletRequest, String)}来获得Cookie对象的值 *
* 如: *

* *

* CookieUtil.getCookieValue(request, "shopName") *

* *

* 返回 "feilong" 字符串 *

* * *

* 3.当然,你也可以使用 {@link #getCookieMap(HttpServletRequest)}来获得 所有的Cookie name和value组成的map *
* 如: *

* *

* CookieUtil.getCookieMap(request) *

* *

* 使用场景,如 {@link com.feilong.servlet.http.RequestLogBuilder#build()} *

*
* * *

* case:删除Cookie *

* *
* *

* 1.可以使用 {@link #deleteCookie(String, HttpServletResponse)}来删除Cookie *
* 如: *

* *

* CookieUtil.deleteCookie(request, "shopName") *

* *

* 2.特殊时候,由于Cookie原先保存时候设置了path属性,可以使用 {@link #deleteCookie(CookieEntity, HttpServletResponse)}来删除Cookie *
* 如: *

* *
 * CookieEntity cookieEntity = new CookieEntity("shopName", "feilong");
 * cookieEntity.setPath("/member/account");
 * CookieUtil.deleteCookie(request, "shopName");
 * 
* *
* *

* 更多,请参考 CookieUtil wiki *

* * @author feilong * @see javax.servlet.http.Cookie * @see "org.springframework.web.util.CookieGenerator" * @see "org.springframework.session.web.http.CookieSerializer" * @see com.feilong.servlet.http.entity.CookieEntity * @see HTTP State Management Mechanism * @see HTTP State Management Mechanism (废弃 被rfc6265取代) * @since 1.0.0 */ @SuppressWarnings("squid:S1192") //String literals should not be duplicated public final class CookieUtil{ /** The Constant LOGGER. */ private static final Logger LOGGER = LoggerFactory.getLogger(CookieUtil.class); /** Don't let anyone instantiate this class. */ private CookieUtil(){ //AssertionError不是必须的. 但它可以避免不小心在类的内部调用构造器. 保证该类在任何情况下都不会被实例化. //see 《Effective Java》 2nd throw new AssertionError("No " + getClass().getName() + " instances for you!"); } //----------------------get----------------------------------------- /** * 取指定cookieName的 {@link Cookie}值. * * @param request * the request * @param cookieName * cookie名字,{@link Cookie#getName()},名称区分大小写,比如 JSESSIONID 如果改成 jsessionid 将取不到值 * @return 如果取不到cookie,返回 null;
* 否则,返回 {@link Cookie#getValue()} * @see #getCookie(HttpServletRequest, String) * @see Cookie#getValue() */ public static String getCookieValue(HttpServletRequest request,String cookieName){ Cookie cookie = getCookie(request, cookieName); return null == cookie ? null : getReadValue(cookie); } /** * 获得 {@link Cookie}对象. * *

* 循环遍历 {@link HttpServletRequest#getCookies()},找到 {@link Cookie#getName()}是 cookieName 的 {@link Cookie} *

* * @param request * the request * @param cookieName * cookie名字,{@link Cookie#getName()},名称区分大小写,比如 JSESSIONID 如果改成 jsessionid 将取不到值 * @return 如果 {@link HttpServletRequest#getCookies()}是 null,则返回null;
* 如果通过 cookieName 找不到指定的 {@link Cookie},也返回null * @see javax.servlet.http.HttpServletRequest#getCookies() * @see javax.servlet.http.Cookie#getName() */ public static Cookie getCookie(HttpServletRequest request,String cookieName){ Cookie[] cookies = request.getCookies(); if (isNullOrEmpty(cookies)){ LOGGER.debug("when get cookieName:[{}],but request's cookies is null or empty!!", cookieName); return null; } //--------------------------------------------------------------- for (Cookie cookie : cookies){ if (cookie.getName().equals(cookieName)){ if (LOGGER.isDebugEnabled()){ LOGGER.debug("[getCookie],cookieName:[{}],cookie info:[{}]", cookieName, JsonUtil.format(cookie, 0, 0)); } return cookie; } } LOGGER.debug("can't find the cookie:[{}]", cookieName); return null; } /** * 将{@link Cookie}的 key 和value转成 map({@link TreeMap}). * * @param request * the request * @return 如果没有 {@link HttpServletRequest#getCookies()},返回 {@link Collections#emptyMap()};
* 否则,返回 loop cookies,取到 {@link Cookie#getName()}以及 {@link Cookie#getValue()} 设置成map 返回 * @see HttpServletRequest#getCookies() * @see javax.servlet.http.Cookie#getName() * @see javax.servlet.http.Cookie#getValue() * @see "javax.servlet.jsp.el.ImplicitObjectELResolver.ImplicitObjects#createCookieMap(javax.servlet.jsp.PageContext)" */ public static Map getCookieMap(HttpServletRequest request){ Cookie[] cookies = request.getCookies(); if (isNullOrEmpty(cookies)){ return emptyMap(); } //--------------------------------------------------------------- Map map = new TreeMap<>(); for (Cookie cookie : cookies){ map.put(cookie.getName(), getReadValue(cookie)); } return map; } //--------------------delete------------------------------------------- /** * 删除{@link Cookie}. * *

* 删除{@link Cookie}的时候,path必须保持一致;
* 如果path不一致,请使用 {@link CookieUtil#deleteCookie(CookieEntity, HttpServletResponse)} *

* * @param cookieName * cookie名字,{@link Cookie#getName()},名称区分大小写,比如 JSESSIONID 如果改成 jsessionid 将取不到值 * @param response * the response * @see #deleteCookie(CookieEntity, HttpServletResponse) */ public static void deleteCookie(String cookieName,HttpServletResponse response){ deleteCookie(new CookieEntity(cookieName, ""), response); } /** * 删除cookie. * *

* 删除 Cookie的时候,path必须保持一致 *

* * @param cookieEntity * the cookie entity * @param response * the response * @see #addCookie(CookieEntity, HttpServletResponse) * @since 1.5.0 */ public static void deleteCookie(CookieEntity cookieEntity,HttpServletResponse response){ Validate.notNull(cookieEntity, "cookieEntity can't be null!"); cookieEntity.setMaxAge(0);// 设置为0为立即删除该Cookie addCookie(cookieEntity, response); LOGGER.debug("[deleteCookie],cookieName:[{}]", cookieEntity.getName()); } //-------------------------add-------------------------------------- /** * 创建cookie. * *

* 注意:该方法创建的cookie,有效期是默认值 -1,即浏览器退出就删除 *

* *

* 如果 cookieName 是null,抛出 {@link NullPointerException}
* 如果 cookieName 是blank,抛出 {@link IllegalArgumentException}
*

* * @param cookieName * cookie名字,{@link Cookie#getName()},名称区分大小写,比如 JSESSIONID 如果改成 jsessionid 将取不到值 * @param value * cookie的值,更多说明,参见 {@link CookieEntity#getValue()} *

* 注意:如果值长度超过4K,浏览器会忽略,不会执行记录的操作 *

* @param response * response * @see CookieUtil#addCookie(CookieEntity, HttpServletResponse) * @since 1.5.0 */ public static void addCookie(String cookieName,String value,HttpServletResponse response){ Validate.notBlank(cookieName, "cookieName can't be null/empty!"); addCookie(new CookieEntity(cookieName, value), response); } /** * 创建cookie. * *

* 如果 cookieName 是null,抛出 {@link NullPointerException}
* 如果 cookieName 是blank,抛出 {@link IllegalArgumentException}
*

* * @param cookieName * cookie名字,{@link Cookie#getName()},名称区分大小写,比如 JSESSIONID 如果改成 jsessionid 将取不到值 * @param value * cookie的值,更多说明,参见 {@link CookieEntity#getValue()} *

* 注意:如果值长度超过4K,浏览器会忽略,不会执行记录的操作 *

* @param maxAge * 设置以秒计的cookie的最大存活时间,可以使用 {@link com.feilong.core.TimeInterval TimeInterval}相关常量 * @param response * response * @see CookieUtil#addCookie(CookieEntity, HttpServletResponse) * @since 1.5.0 */ public static void addCookie(String cookieName,String value,int maxAge,HttpServletResponse response){ Validate.notBlank(cookieName, "cookieName can't be null/empty!"); addCookie(new CookieEntity(cookieName, value, maxAge), response); } /** * 创建cookie. * *

* 如果 cookieEntity 是null,抛出 {@link NullPointerException}
* 如果 cookieEntity.cookieName 是null,抛出 {@link NullPointerException}
* 如果 cookieEntity.cookieName 是blank,抛出 {@link IllegalArgumentException}
*

* * @param cookieEntity * cookieEntity * @param response * response * @see "org.apache.catalina.connector.Response#generateCookieString(Cookie, boolean)" */ public static void addCookie(CookieEntity cookieEntity,HttpServletResponse response){ validateCookieEntity(cookieEntity);//校验 if (LOGGER.isDebugEnabled()){ LOGGER.debug("[addCookie],cookieName:[{}],cookieEntity info:[{}]", cookieEntity.getName(), JsonUtil.format(cookieEntity, 0, 0)); } response.addCookie(toCookie(cookieEntity)); } //--------------------------------------------------------------- /** * To cookie. * * @param cookieEntity * the cookie entity * @return the cookie * @since 1.5.3 */ private static Cookie toCookie(CookieEntity cookieEntity){ Cookie cookie = new Cookie(cookieEntity.getName(), resolveWriteValue(cookieEntity)); PropertyUtil.copyProperties(cookie, cookieEntity, "maxAge", "secure", "version", "httpOnly"); PropertyUtil.setPropertyIfValueNotNullOrEmpty(cookie, "comment", cookieEntity.getComment());//指定一个注释来描述cookie的目的. //NullPointerException at javax.servlet.http.Cookie.setDomain(Cookie.java:213) ~[servlet-api-6.0.37.jar:na] PropertyUtil.setPropertyIfValueNotNullOrEmpty(cookie, "domain", cookieEntity.getDomain());// 指明cookie应当被声明的域. PropertyUtil.setPropertyIfValueNotNullOrEmpty(cookie, "path", cookieEntity.getPath());//指定客户端将cookie返回的cookie的路径. return cookie; } /** * Validate cookie entity. * * @param cookieEntity * the cookie entity * @since 1.5.0 */ private static void validateCookieEntity(CookieEntity cookieEntity){ Validate.notNull(cookieEntity, "cookieEntity can't be null!"); Validate.notBlank(cookieEntity.getName(), "cookieName can't be null/empty!"); //--------------------------------------------------------------- if (LOGGER.isWarnEnabled()){ String value = resolveWriteValue(cookieEntity); //如果长度超过4000,浏览器可能不支持 if (isNotNullOrEmpty(value) && value.length() > 4000){ String pattern = "cookie value:{},length:{},more than [4000]!!!some browser may be not support!!!!!,cookieEntity info :{}"; LOGGER.warn(pattern, value, value.length(), JsonUtil.format(cookieEntity, 0, 0)); } } } //--------------------------------------------------------------- /** * Resolve write value. * * @param cookieEntity * the cookie entity * @return the string * @see "org.springframework.session.web.http.DefaultCookieSerializer#writeCookieValue(CookieValue)" * @since 1.10.4 */ private static String resolveWriteValue(CookieEntity cookieEntity){ //保持兼容,暂不encode see https://github.com/venusdrogon/feilong-servlet/issues/7 //com.feilong.accessor.cookie.CookieAccessor 支持 return cookieEntity.getValue(); } /** * 获得value. * * @param cookie * the cookie * @return the read value * @since 1.10.4 */ private static String getReadValue(Cookie cookie){ //保持兼容,暂不encode see https://github.com/venusdrogon/feilong-servlet/issues/7 //com.feilong.accessor.cookie.CookieAccessor 支持 return cookie.getValue(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy