继续上文,登录用户的信息如何保存才利于系统对用户信息的读取呢?想到的是使用HttpServletResponse类的addCookie()方法,参数自然是一个cookie对象,即为javax.servlet.http.Cookie的实例,具体代码如下:
public static void saveCookie(HttpServletResponse response, String name, String value, int saveTime, String domain, String path) { if(value == null) value = ""; Cookie cookie = new Cookie(name, value); cookie.setDomain(domain); cookie.setMaxAge(saveTime); if(StringUtils.isNotBlank(path)) cookie.setPath(path); else cookie.setPath("/"); cookie.setSecure(false); response.addCookie(cookie); }这样就可以使用HttpServletRequest类的getCookie()方法来获取相应的cookie,代码如下:public static Cookie getCookie(HttpServletRequest request, String name) { Cookie cookies[] = request.getCookies(); if(cookies == null || StringUtils.isBlank(name)) return null; for(int i = 0; i < cookies.length; i++) if(name.equals(cookies[i].getName())) return cookies[i]; return null; }如果想要获得某个cookie的value,则代码如下:public static String getCookieValue(HttpServletRequest request, String name) { Cookie cookies[] = request.getCookies(); if(cookies == null || cookies.length == 0) return null; Cookie acookie[]; int j = (acookie = cookies).length; for(int i = 0; i < j; i++) { Cookie cookie = acookie[i]; if(StringUtils.isNotBlank(cookie.getValue()) && StringUtils.equals(cookie.getName(), name)) { String value = cookie.getValue(); return value; } } return null; }删除某个cookie的代码如下(即将cookie的指定name的值设为空即可,因为保留name以便以后需要添加对应name的cookie时不需要重新初始化一个Cookie实例):
public static transient void deleteCookie(HttpServletResponse response, String name, String domain, String paths[]) { Cookie cookie = new Cookie(name, ""); if(StringUtils.isNotBlank(domain)) cookie.setDomain(domain); cookie.setMaxAge(-1); if(paths == null || paths.length == 0 || StringUtils.isBlank(paths[0])) cookie.setPath("/"); else cookie.setPath(paths[0]); response.addCookie(cookie); }有了这些方法就可以结合之前的session pojo类来实现具体session的存取操作了,当然这时的cookie的value值需要经过加密或者解密之后再进行存取的,以提高安全性。具体的加密解密方法如下:
static {
desUidKey = generateDesKey("cd910a7685b32fe4").getEncoded();//private static byte[] desUidKey = null;
}
/**
* 根据给定的密钥种子生密钥。
* <p />
* 若给定的密钥种子{@code keySeed} 为{@code null} 或空字符串,则随机生成密钥。
*
* @param keySeed 密钥种子。
* @return 密钥。
*/
public static Key generateDesKey(String keySeed) {
KeyGenerator keyGen = null;
try {
keyGen = KeyGenerator.getInstance("DES");
} catch (NoSuchAlgorithmException ex) {
LOGGER.warn("System does not support the DES algorithm. message: " + ex.getMessage());
}
byte[] keyBytes = new byte[DESKeySpec.DES_KEY_LEN];
if (StringUtils.isNotBlank(keySeed)) {
byte[] bytes = DigestUtils.md5(keySeed.trim());
keyBytes = Arrays.copyOfRange(bytes, 8, 16);
return new SecretKeySpec(keyBytes, "DES");
} else {
if (keyGen == null) {
SecureRandom random = new SecureRandom();
random.nextBytes(keyBytes);
return new SecretKeySpec(keyBytes, "DES");
}
return keyGen.generateKey();
}
}
/**
* 使用DES算法加密用户Id。
*
* @param userId 要加密的用户Id。
* @return 返回给定用户Id的密文。
*/
public static String encryptUid(Long userId) {
if (userId == null) {
return StringUtils.EMPTY;
}
try {
JCEdes des = JCEdes.getInstance(desUidKey);//JCEdes是自己封装的一个关于加密解密方法的类
return des.encryptStringToHex(String.valueOf(userId), CharEncoding.UTF_8);
} catch (Exception ex) {
return StringUtils.EMPTY;
}
}
/**
* 使用DES算法解密给定的用户Id密文。
*
* @param uid 用户Id密文。
* @return 返回 {@code Long} 型的用户Id。
*/
public static Long decryptUid(String uid) {
Long deafultUid = -1L;
if (StringUtils.isNotBlank(uid)) {
try {
JCEdes des = JCEdes.getInstance(desUidKey);
return NumberUtils.toLong(des.decryptHexToString(uid, CharEncoding.UTF_8), deafultUid);
} catch (Exception ex) {
return deafultUid;
}
}
return deafultUid;
}