- 环境: MacOS + IntelliJ IDEA 2019.3.1 (Ultimate Edition)
Cookie:存储在用户本地终端上的数据。Cookie 中每条Cookie的存储空间4k
LocalStorage:用于本地存储,解决了Cookie存储空间不足的问题,LocalStorage
中一般浏览器支持的是5M大小。LocalStorage为永久存储。
SessionStorage:当会话结束时,SessionStorage中的键值对就会被清空。
Flash Cookie:可跨浏览器
基于Spring实战 - 用户登录,实现自动登录的功能。
1、编写CookieUtils 工具类
package com.codeonline.cats.commons.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
/**
*
* Cookie 工具类
*
* @author 码出高薪
*/
public final class CookieUtils {
protected static final Logger logger = LoggerFactory.getLogger(CookieUtils.class);
/**
* 得到Cookie的值, 不编码
*
* @param request
* @param cookieName
* @return
*/
public static String getCookieValue(HttpServletRequest request, String cookieName) {
return getCookieValue(request, cookieName, false);
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @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) {
logger.error("Cookie Decode Error.", e);
}
return retValue;
}
/**
* 得到Cookie的值,
*
* @param request
* @param cookieName
* @return
*/
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) {
logger.error("Cookie Decode Error.", e);
}
return retValue;
}
/**
* 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue) {
setCookie(request, response, cookieName, cookieValue, -1);
}
/**
* 设置Cookie的值 在指定时间内生效,但不编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage) {
setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
}
/**
* 设置Cookie的值 不设置生效时间,但编码
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, boolean isEncode) {
setCookie(request, response, cookieName, cookieValue, -1, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
}
/**
* 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
*/
public static void setCookie(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
}
/**
* 删除Cookie带cookie域名
*/
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");
}
addCookieToResponse(request, response, cookieName, cookieValue, cookieMaxage);
} catch (Exception e) {
logger.error("Cookie Encode Error.", e);
}
}
private static void addCookieToResponse(HttpServletRequest request, HttpServletResponse response,
String cookieName, String cookieValue, int cookieMaxage) {
Cookie cookie = new Cookie(cookieName, cookieValue);
if (cookieMaxage > 0) {
cookie.setMaxAge(cookieMaxage);
}
if (null != request)
{
cookie.setDomain(getDomainName(request));
}
cookie.setPath("/");
response.addCookie(cookie);
}
/**
* 设置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(cookieValue, encodeString);
}
addCookieToResponse(request, response, cookieName, cookieValue, cookieMaxage);
} catch (Exception e) {
logger.error("Cookie Encode Error.", e);
}
}
/**
* 得到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;
}
}
2、在实体类User中增加isRemember
package com.codeonline.cats.entity;
/**
* @author 码出高薪
* @Desc. User 实体类
* @date 2020/1/12 04:45
*/
public class User {
private String email;
private String password;
private Boolean isRemembers;
public Boolean getRemembers() {
return isRemembers;
}
public void setRemembers(Boolean remembers) {
isRemembers = remembers;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"email=\'" + email + \'\\\'\' +
", password=\'" + password + \'\\\'\' +
\'}\';
}
}
3、在LoginController中增加Cookie的保存和设置功能
package com.codeonline.cats.web.controller;
import com.codeonline.cats.commons.context.SpringContext;
import com.codeonline.cats.commons.utils.CookieUtils;
import com.codeonline.cats.entity.User;
import com.codeonline.cats.service.UserServiceInterface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
/**
* @author 码出高薪
* @Desc. 登录控制
* @date 2020/1/12 04:57
*/
@Controller
public class LoginController extends HttpServlet {
private Logger logger = LoggerFactory.getLogger(LoginController.class);
/**
* 获取Spring容器中初始化bean, userService
*/
private UserServiceInterface userServiceInterface = SpringContext.getBean("userService");
private static final String COOKIE_NAME_USER_INFO = "userInfo";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String userInfo = CookieUtils.getCookieValue(req,COOKIE_NAME_USER_INFO);
/**
* 自动设置从cookie读取的email,password
*/
if(!StringUtils.isBlank(userInfo)){
String[] userInfoArray = userInfo.split(":");
String email = userInfoArray[0];
String password = userInfoArray[1];
req.setAttribute("email",email);
req.setAttribute("password",password);
req.setAttribute("isRemembers",true);
}
req.getRequestDispatcher("/login.jsp").forward(req,resp);
/**
* 从cookie中获取email, password
*/
CookieUtils.getCookieValue(req,COOKIE_NAME_USER_INFO);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String email = req.getParameter("email");
String password = req.getParameter("password");
boolean isRemembers = req.getParameter("isRemembers")==null?false:true;
/**
* 用户不选择 则清空COOKIE
*/
if(!isRemembers){
CookieUtils.deleteCookie(req,resp,COOKIE_NAME_USER_INFO);
}
User user = userServiceInterface.login(email,password);
/**
* 登录成功
*/
if(user!=null)
{
if(isRemembers){
/**
* 用户信息存储一周
*/
CookieUtils.setCookie(req,resp,"userInfo",
String.format("%s:%s",email,password), 7*24*60*60);
}
/**
* 重定向到首页
*/
resp.sendRedirect("main.jsp");
}
/**
* 登录失败
*/
else{
req.setAttribute("message","用户名或密码错误");
logger.info("用户名或密码错误");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
}
4、在login.jsp中接收传入的email,password
<div class="input-group mb-2">
<input name="email" type="email" class="form-control" placeholder="邮箱" value=${email}>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-envelope"></span>
</div>
</div>
</div>
<div class="input-group mb-3">
<input name="password" type="password" class="form-control" placeholder="密码" value=${password}>
<div class="input-group-append">
<div class="input-group-text">
<span class="fas fa-lock"></span>
</div>
</div>
</div>
<div class="row">
<div class="col-8">
<div class="icheck-primary">
<input id="remember" name="isRemembers" type="checkbox" ${isRemembers==true?"checked":""}>
<label for="remember">
下次自动登录
</label>
</div>
</div>
至此,实现自动登录功能。