这里是修真院后端小课堂,每篇分享文从
八个方面深度解析后端知识/技能,本篇分享的是:
【cookie和session】
大家好,我是IT修真院上海分院第八期学员,一枚正直纯洁善良的JAVA程序员。
今天给大家分享一下,修真院官网JAVA任务五,扩展思考中的知识点——cookie和session
1 背景介绍
什么是会话?
用户打开一个浏览器, 点击多个超链接, 访问服务器多个web资源, 然后关闭浏览器, 整个过程称之为一个会话
HTTP协议是一种"无状态"协议,客户浏览器与服务器建立连接,发出请求,得到相应,然后关闭连接,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。
所以容器不能辨认下一个请求和之前的请求是不是同一个请求,对于容器而言,每个请求都是新的。
使用浏览器与服务器进行会话的过程中,不可避免会产生一些数据, Web服务器没有短期记忆,如何保存这些用户数据?
客户需要一个唯一的会话ID
客户的第一次请求,容器会生成一个唯一的会话ID,并通过响应把它发回客户端,客户在以后的每一个请求中发回这个会话ID。容器看到后,就会找到匹配的会话,并把这个会话与请求关联。
如何交换会话信息?
保存会话数据的两种技术:
cookie和session
2 知识剖析
Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
3 常见问题
浏览器禁用Cookie怎么办?
4 解决方案
URL重写、隐藏表单字段
5 编码实战
cookie:
cookie工具类
public class CookieUtil {
/**
* 添加cookie
* @param response
* @param key cookie主键
* @param value cookie值
*/
public static void addCookie(HttpServletResponse response,String key,String value){
Cookie cookie = new Cookie(key,value);
//设置路径
cookie.setPath("/");
//设置保存时间为1天,单位为s
cookie.setMaxAge(24*60*60);
//通过response.addCookie将此条cookie添加到客户端
response.addCookie(cookie);
}
/**
* 删除cookie
* @param response
* @param request
* @param key
*/
public static void deleteCookie(HttpServletResponse response, HttpServletRequest request,String key) {
//获取浏览器访问服务器时传递来的cookie数组
Cookie cookies[] = request.getCookies();
if (cookies != null) {
for (int i = 0; i < cookies.length; i++) {
if (cookies[i].getName().equals(key)) {
Cookie cookie = new Cookie(key, null);
//此路径需与之前创建时相同
cookie.setPath("/");
//设置为0即为删除
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
}
/**
* 获取指定cookie
* @param request
* @param key
* @return
* @throws UnsupportedEncodingException
*/
public static String getCookieValue(HttpServletRequest request,String key) throws UnsupportedEncodingException {
//通过request.getCookies获取客户端提交的所有cookie
for (Cookie cookie : request.getCookies()) {
if (cookie.getName().equals(key)) {
return URLDecoder.decode(cookie.getValue(), "UTF-8");
}
}
return null;
}
}
controller
@Controller
public class CookieController {
@RequestMapping(value = "/cookie", method = RequestMethod.POST)
public String cookie(@RequestParam String name, String password, HttpServletResponse response, Model model){
CookieUtil.addCookie(response,"name",name);
CookieUtil.addCookie(response,"password",password);
model.addAttribute("name",name);
model.addAttribute("password",password);
return "cookie";
}
@RequestMapping(value = "getcookie",method = RequestMethod.GET)
public String getcookie(HttpServletRequest request,Model model) throws UnsupportedEncodingException {
String name =CookieUtil.getCookieValue(request,"name");
String password = CookieUtil.getCookieValue(request,"password");
model.addAttribute("name",name);
model.addAttribute("password",password);
return "cookie";
}
@RequestMapping(value = "deletecookie",method = RequestMethod.GET)
public String deletecookie(HttpServletRequest request,HttpServletResponse response,Model model) throws UnsupportedEncodingException {
// CookieUtil.deleteCookie(response,request,“name”);
CookieUtil.deleteCookie(response,request,“password”);
String name = CookieUtil.getCookieValue(request,“name”);
String password = CookieUtil.getCookieValue(request,“password”);
model.addAttribute(“name”,name);
model.addAttribute(“password”,password);
return “redirect:test.jsp”;
}
}
表单jsp
密码
<a href="/getcookie">获取cookie</a>
<a href="/deletecookie">删除cookie</a>
</body>
获取cookie
点击删除cookie(controller删除了密码的cookie),可以看到密码已经查询不到了
session:摘自菜鸟教程
public class seesion extends HttpServlet {
private static final long serialVersionUID = 1L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// 如果不存在 session 会话,则创建一个 session 对象
HttpSession session = request.getSession(true);
// 获取 session 创建时间
Date createTime = new Date(session.getCreationTime());
// 获取该网页的最后一次访问时间
Date lastAccessTime = new Date(session.getLastAccessedTime());
//设置日期输出的格式
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String title = "Servlet Session 实例";
Integer visitCount = new Integer(0);
String visitCountKey = new String("visitCount");
String userIDKey = new String("userID");
String userID = new String("Runoob");
if(session.getAttribute(visitCountKey) == null) {
session.setAttribute(visitCountKey, new Integer(0));
}
// 检查网页上是否有新的访问者
if (session.isNew()){
title = "Servlet Session 实例";
session.setAttribute(userIDKey, userID);
} else {
visitCount = (Integer)session.getAttribute(visitCountKey);
visitCount = visitCount + 1;
userID = (String)session.getAttribute(userIDKey);
}
session.setAttribute(visitCountKey, visitCount);
// 设置响应内容类型
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
String docType = "<!DOCTYPE html>\n";
out.println(docType +
"<html>\n" +
"<head><title>" + title + "</title></head>\n" +
"<body bgcolor=\"#f0f0f0\">\n" +
"<h1 align=\"center\">" + title + "</h1>\n" +
"<h2 align=\"center\">Session 信息</h2>\n" +
"<table border=\"1\" align=\"center\">\n" +
"<tr bgcolor=\"#949494\">\n" +
" <th>Session 信息</th><th>值</th></tr>\n" +
"<tr>\n" +
" <td>id</td>\n" +
" <td>" + session.getId() + "</td></tr>\n" +
"<tr>\n" +
" <td>创建时间</td>\n" +
" <td>" + df.format(createTime) +
" </td></tr>\n" +
"<tr>\n" +
" <td>最后访问时间</td>\n" +
" <td>" + df.format(lastAccessTime) +
" </td></tr>\n" +
"<tr>\n" +
" <td>用户 ID</td>\n" +
" <td>" + userID +
" </td></tr>\n" +
"<tr>\n" +
" <td>访问统计:</td>\n" +
" <td>" + visitCount + "</td></tr>\n" +
"</table>\n" +
"</body></html>");
}
}
seesion
com.ppteng.controller.seesion
seesion
/test/session
1234567891011
设置会话时间(分钟):方便进行对比
刷新页面
两次会话只要不超过1min,就会累加
无操作1min后,session就会过期,刷新页面,session重建
6 扩展思考
下面这篇文章介绍了Cookie 和 Session 的工作原理,并介绍了一致分布式 Session 的解决方案。
可以看看:https://my.oschina.net/kevinair/blog/192829
7 参考文献
菜鸟教程-servlet
Head First Servlet&Jsp
8 更多讨论
Q1:cookie有哪些不足呢?
A1:cookie是客户端技术,对客户端是可见的,数据安全性较低。
Q2:cookie和session存取方式不同
A2:cookie中只能保管ASCII字符串,假如需求存取Unicode字符或者二进制数据,需求先进行编码。Cookie中也不能直接存取Java对象。若要存储略微复杂的信息,运用Cookie是比拟艰难的。
Session中能够存取任何类型的数据,包括而不限于String、Integer、List、Map等。Session中也能够直接保管Java Bean乃至任何Java类,对象等,运用起来十分便当。能够把Session看做是一个Java容器类。
Q3:网站如何选择?
A3:Session是保管在服务器端的,每个用户都会产生一个Session。假如并发访问的用户十分多,会产生十分多的Session,耗费大量的内存。发访问量极高的网站,是不太可能运用Session来追踪客户会话的。
Cookie保管在客户端,不占用服务器资源。假如并发阅读的用户十分多,Cookie是很好的选择。
9 鸣谢
10 结束语
今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~