package chauncy.cookie;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @classDesc: 功能描述(创建Cookie)
* @author: ChauncyWang
* @createTime: 2019年4月2日 上午10:16:06
* @version: 1.0
*/
@WebServlet("/CreateCookieServlet")
public class CreateCookieServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//key value 自定义Cookie
Cookie cookie = new Cookie("userName", "123456");
//如果是负数,浏览器关闭失效,如果是正数,以秒为单位进行保存。
cookie.setMaxAge(60*60*24);//cookie保存一天,没有任何一家公司能永久保存登录,说永久只不过把值设置的比较大。
//将Cookie发送给客户端
resp.addCookie(cookie);
System.out.println("创建Cookie成功!");
}
}
2.获取Cookie:package chauncy.cookie;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Cookie默认浏览器关闭失效
* @classDesc: 功能描述(获取Cookie)
* @author: ChauncyWang
* @createTime: 2019年4月2日 上午10:58:22
* @version: 1.0
*/
@WebServlet("/GetCookieServlet")
public class GetCookieServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取所有的Cookie信息
Cookie[] cookies = req.getCookies();
if(cookies != null){
for (Cookie cookie : cookies) {
System.out.println(cookie.getName()+"---"+cookie.getValue());
}
}else{
System.out.println("cookie为null");
}
}
}
3.显示用户最后一次访问时间:package chauncy.cookie;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
/**
* @classDesc: 功能描述(显示用户最后一次访问的时间)
* @author: ChauncyWang
* @createTime: 2019年4月2日 下午2:09:19
* @version: 1.0
*/
@WebServlet("/LastAccessTime")
public class LastAccessTime extends HttpServlet{
private static final String COOKIE_KEY_LASTACCESSTIME="COOKIE_KEY_LASTACCESSTIME";
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");//防止浏览器产生乱码
//1.获取Cookie信息
Cookie[] cookies = req.getCookies();
String lastAccessTime=null;
if(cookies!=null){
for(Cookie cookie:cookies){
String name = cookie.getName();
if(COOKIE_KEY_LASTACCESSTIME.equals(name)){
lastAccessTime=cookie.getValue();
break;
}
}
}
//2.如果Cookie信息没有数据,说明第一次访问,有数据获取上一次Cookie的值。
if(StringUtils.isEmpty(lastAccessTime)){
resp.getWriter().write("您是首次访问!");
}else{
resp.getWriter().write("您上次访问时间为:"+lastAccessTime);
}
//3.现在访问的登录时间存放在Cookie中
//当前访问时间
String currentTime = new SimpleDateFormat("yyyy-mm-dd hh:mm:ss").format(new Date());
//创建cookie将当前时间作为cookie保存到浏览器
Cookie cookie = new Cookie(COOKIE_KEY_LASTACCESSTIME,currentTime);
cookie.setMaxAge(60*60*24);
//将cookie发送给客户端
resp.addCookie(cookie);
}
}
特点:
会话数据保存在服务器端。(内存中)
Session技术核心:
HttpSession类:用于保存会话数据
Session原理
服务器创建完Session,会将SessionId通过响应头方式返回给客户端。客户端将sessionId保存在本地硬盘,再次请求的时候,将sessionId通过请求头的方式传给服务器端。
Session的值是存放在服务器端内存中,只要没有达到失效要求不会失效,关闭浏览器,只是SessionId失效,但是Session没有失效。
移动APP的登录也是此种方式。
具体步骤:
总结:通过JSESSION的cookie值在服务器找session对象。
Sesson细节
java.lang.String getId():得到session编号。
两个getSession方法:
getSession(true) / getSession():创建或得到session对象。没有匹配的session编号,自动创建新的session对象。
getSession(false):得到session对象。没有匹配的session编号,返回null。
void setMaxInactiveInterval(int interval) : 设置session的有效时间。
session对象销毁时间:
<!-- 修改session全局有效时间:分钟 -->
<session-config>
<session-timeout>1</session-timeout>
</session-config>
如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题。
/**
* 手动发送一个硬盘保存的cookie给浏览器
*/
Cookie c = new Cookie("JSESSIONID",session.getId());
c.setMaxAge(60*60);
response.addCookie(c);
代码实现创建、调用Session
package chauncy.session;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @classDesc: 功能描述(创建Session)
* @author: ChauncyWang
* @createTime: 2019年4月2日 下午4:14:34
* @version: 1.0
*/
@WebServlet("/CreateSessionServlet")
public class CreateSessionServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//getSession()无参数形式默认为true,如果没有Session,就会创建一个session,如果参数为false,如果没有找到Session,就不会创建session。
HttpSession session = req.getSession();
session.setAttribute("userName", "ChauncyWang");
System.out.println("保存session成功!sessionId:"+session.getId());
}
}
package chauncy.session;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* @classDesc: 功能描述(获取Session)
* @author: ChauncyWang
* @createTime: 2019年4月2日 下午4:24:31
* @version: 1.0
*/
@WebServlet("/GetSessionServlet")
public class GetSessionServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session使用getSession(false)参数要为false
HttpSession session = req.getSession(false);
if(session != null){
String userName = (String) session.getAttribute("userName");
System.out.println("GetSessionServlet()----userName:"+userName);
System.out.println("GetSessionServlet()----sessionId:"+session.getId());
}else{
System.out.println("没有找到任何结果");
}
}
}
package chauncy.customcache;
/**
* @classDesc: 功能描述(缓存实体类)
* @author: ChauncyWang
* @createTime: 2019年4月3日 上午10:32:52
* @version: 1.0
*/
public class Cache {
//SessionId
private String sessionId;
//键
private String key;
//值
private Object value;
//有效期
private Long timout;
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public Long getTimout() {
return timout;
}
public void setTimout(Long timout) {
this.timout = timout;
}
}
package chauncy.customsession;
import java.util.UUID;
/**
* Token其实就是一个令牌,随机生成,有有效期,不能重重复。
* Token类似于SessionId;
* @classDesc: 功能描述(使用UUID实现Token工具类)
* @author: ChauncyWang
* @createTime: 2019年4月3日 下午3:24:40
* @version: 1.0
*/
public class TokenUtils {
static public String getToken(){
return UUID.randomUUID().toString();
}
public static void main(String[] args) {
System.out.println(TokenUtils.getToken());
}
}
package chauncy.customcache;
import java.nio.channels.NetworkChannel;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import chauncy.customsession.TokenUtils;
/**
* @classDesc: 功能描述(提供缓存的API)
* @author: ChauncyWang
* @createTime: 2019年4月3日 上午10:38:13
* @version: 1.0
*/
public class CacheManager {
private static final CacheManager cacheManager=new CacheManager();
private CacheManager(){
}
public static CacheManager getCacheManager(){
return cacheManager;
}
// 存放缓存数据
private Map<String, Cache> chacheMap = new HashMap<String, Cache>();
public String put(String key, Object value) {
String sessionId = put(key, value, null);
return sessionId;
}
public synchronized String put(String key, Object value, Long timeout) {
Cache cache = new Cache();
//生成SessionId
String sessionId=TokenUtils.getToken();
cache.setSessionId(sessionId);
cache.setKey(key);
cache.setValue(value);
if (timeout != null) {
//保存的是整个毫秒数
cache.setTimout(System.currentTimeMillis()+timeout);
}
chacheMap.put(key, cache);
return sessionId;
}
/**
*
* @methodDesc: 功能描述(删除api)
* @author: ChauncyWang
* @param: @param key
* @createTime: 2019年4月3日 上午11:00:10
* @returnType: void
*/
public synchronized void del(String key) {
System.out.println("key:"+key+"被删除");
chacheMap.remove(key);
}
/**
*
* @methodDesc: 功能描述(使用key查询缓存)
* @author: ChauncyWang
* @param: @param key
* @param: @return
* @createTime: 2019年4月3日 上午10:59:49
* @returnType: Object
*/
public synchronized Object get(String key){
Cache cache = chacheMap.get(key);
if(cache != null){
return cache;
}
return null;
}
/**
*
* @methodDesc: 功能描述(定时检查删除有效期的值)
* @author: ChauncyWang
* @param:
* @createTime: 2019年4月3日 上午11:10:16
* @returnType: void
*/
public synchronized void checkValidityData(){
for (String key : chacheMap.keySet()) {
Cache cache = chacheMap.get(key);
if(cache == null){
break;
}
//检查有效期,获取缓存的毫秒数。
Long timout = cache.getTimout();
//计算时间差,获取当前时间毫秒数
Long currentTime = System.currentTimeMillis();
//说明已经过时
if((currentTime-timout)>0){
del(key);
}
}
}
public static void main(String[] args) {
final CacheManager cacheManager = new CacheManager();
//如果设置时间,开启一个线程,检查有效期
cacheManager.put("userName", "123",5000l);
System.out.println("保存成功。。。");
//开启一个线程定期检查刷新数据
// 入参为线程池大小,
ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5);
// schedule执行定时任务线程池,第一个参数需要创建Runnable接口对象,第二、三个参数表示多少个单位时间执行run方法。
newScheduledThreadPool.schedule(new Runnable() {
public void run() {
cacheManager.checkValidityData();
}
}, 5000, TimeUnit.MILLISECONDS);
try {
Thread.sleep(5000);
} catch (Exception e) {
e.printStackTrace();
}
Cache cache = (Cache) cacheManager.get("userName");
System.out.println("userName:"+cache.getValue());
}
}
package chauncy.customsession;
import chauncy.customcache.Cache;
import chauncy.customcache.CacheManager;
public class SessionUtil {
private CacheManager cacheManager;
/**
*
* @methodDesc: 功能描述(初始化cacheManager)
* @author: ChauncyWang
* @param:
* @createTime: 2019年4月3日 下午3:03:35
* @returnType: void
*/
public SessionUtil() {
cacheManager=CacheManager.getCacheManager();
}
/**
*
* @methodDesc: 功能描述(新增一个Session,返回一个SessionId)
* @author: ChauncyWang
* @param: @param key
* @param: @param value
* @param: @return
* @createTime: 2019年4月3日 下午3:11:34
* @returnType: String
*/
public String setAttribute(String key,Object value){
//生成SessionId
String sessionId=cacheManager.put(key, value);
return sessionId;
}
//通过key值获取缓存对象Cache,缓存对象包含sessionId和value值
public Object getAttribute(String key){
return cacheManager.get(key);
}
public static void main(String[] args) {
SessionUtil sessionUtil = new SessionUtil();
String setAttribute = sessionUtil.setAttribute("userName", "ChauncyWang");
System.out.println("CreateSessionId:"+setAttribute);
Cache cache = (Cache) sessionUtil.getAttribute("userName");
System.out.printf("CacheEntity--->sessionId:"+cache.getSessionId()+"\tkey:"+cache.getKey()+"\tvalue:"+cache.getValue());
}
}
UUID.randomUUID().toString();
表单重复提交 常用两个解决办法
通过前端解决
通过后端解决