cookie和session

这里是修真院后端小课堂,每篇分享文从

八个方面深度解析后端知识/技能,本篇分享的是:

【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
设置会话时间(分钟):方便进行对比

1 123 运行访问http://localhost:8080/test/session

刷新页面

两次会话只要不超过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 结束语

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值