Java Web之Cookie和Session详解

我们知道http协议是无状态的,也就是说就算客户端是第二次访问服务器,服务器还是把此次访当做一个新的访问进行处理,因为服务端并不知道客户端之前是否访问过。而cookie和session则就是为了弥补这一缺陷出现的一种机制。


Cookie

服务端给客户端的数据,存储于客户端(浏览器)。由于是保存在客户端上的,所以存在安全问题,并且cookie是由个数和大小限制的(4KB),所以一般cookie用来存储一些比较小且安全性要求不高的数据,而且一般数据都会进行加密。

我们平时在登录某些网站时,关闭浏览器后再次打开登录,用户名密码等数据会自动填充在表单。
或者我们浏览淘宝的某个商品后,下次再打开发现出现的商品很多都是我们之前浏览的同类商品等。
这些都是cookie的应用场景。

Cookie cookie = new Cookie("account", account);//创建一个cookie,保存账号数据
cookie.setMaxAge(1*60*60*24);//cookie存在在本地的有效时长(单位为秒) 默认为-1  表示页面关闭cookie就失效
cookie.setDomain("");//设置在某个域名下生效
cookie.setPath("/login.jsp");//设置访问该域名下某个路径时生效
response.addCookie(cookie);//添加到response
Cookie[] cookies=request.getCookies();//获取cookies
cookie.getName();//cookie的name
cookie.getValue();//cookie的value

我们来实现一个记住用户名的小案例

首先写一个登录的界面,我们在页面中获取request中的cookie数组,如果cookie数组中有account的值,则赋给账号输入框。没有的话默认就是空字符串。

代码如下:

<%--
  Created by IntelliJ IDEA.
  User: yzq
  Date: 2018/7/27
  Time: 9:51
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登录</title>
</head>
<body>

<%
    String path = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
            + application.getContextPath();

    /*获取request中的cookie*/
    Cookie[] cookies = request.getCookies();
    String cookieAccount = "";

    if (cookies != null) {

        for (Cookie cookie :
                cookies) {
            System.out.println(cookie.getName() + ":" + cookie.getValue());

            /*如果cookie中存储的有account,取出该值 */
            if (cookie.getName().equals("account")) {
                cookieAccount = cookie.getValue();
            }

        }
    }


%>

<form action="<%=application.getContextPath()%>/login">

    <%--将cookie中携带的account值赋值给value--%>
    <input name="account" value="<%=cookieAccount%>"><br>
    <input name="pwd"><br>
    记住密码:<input type="checkbox" name="remember"> <br>
    <input type="submit" value="登录">


</form>

</body>
</html>

 

我们请求下页面先看一下,首次登录时没有存储账号数据的

在这里插入图片描述
可以看到默认Cookie中是没有account的。

下面我们实现一下将账号存储到Cookie中

package servlet;

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 java.io.IOException;

@WebServlet(name = "LoginServlet", urlPatterns = "/login")
public class LoginServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");

        
        String account = request.getParameter("account");
        String pwd = request.getParameter("pwd");

        String isRemember = request.getParameter("remember");

        System.out.println("account=" + account);
        System.out.println("pwd=" + pwd);
        System.out.println("isRemember=" + isRemember);

        if (isRemember != null) {
            Cookie cookie = new Cookie("account", account);//保存账号数据
            cookie.setMaxAge(1*60*60*24);//cookie存在在本地的有效时长(单位为秒) 默认为-1  表示页面关闭cookie就失效
            response.addCookie(cookie);//添加到response
        }
        
    }
}


在这里插入图片描述
可以看到,登录成功后我们再次请求登录页面,此时就拿到了account数据了。只要是在有效期内,关闭浏览器再次打开依然是可以获取到account的值的。


Session
在学习jsp的时候我们知道了session是jsp的内置对象,其作用域是在整个会话期间。

我们在之前Cookie的例子会发现cookie中有JSESSIONID这个字段,实际上首次请求网页时在请求头里是没有这个字段的,因为我们并没有创建session,当我们调用request.getSession()时,此时会创建一个session,并且将sessionId保存到cookie中,然后回写给response,所以我们发现首次创建session时的响应头中有JSESSIONID这个字段,后面的request默认都会带上JSESSIONID这个字段,而response中则不会再有该字段了。而服务器就能够根据JSESSIONID这个字段值查找对应的session。

我们创建一个SessionServlet ,编写下面代码

package servlet;

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;
import java.io.IOException;

@WebServlet(name = "SessionServlet",urlPatterns = "/session")
public class SessionServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        HttpSession session = request.getSession();//获取session,没有则创建
        String sessionId = session.getId();//获取sessionId

        long createTime = session.getCreationTime();//获取session创建的时间

        long lastTime = session.getLastAccessedTime();//最后一次修改session的时间


        System.out.println("sessionId="+sessionId);
        System.out.println("createTime="+createTime);
        System.out.println("lastTime="+lastTime);
    }
}

运行看看效果

如下图所示,首次请求时响应头中的cookie会有JSESSIONID字段,此时请求头中是没有cookie的,然后再次请求,响应头中则没有了cookie,但是请求头中会有包含JSESSIONID字段的cookie

在这里插入图片描述
下图是request中cookie默认携带的JSESSIONID

在这里插入图片描述
但是,如果浏览器禁用了cookie,那么,每次请求都会重新创建session,因为服务器没有获取到JSESSIONID这个值,也无法根据JSESSIONID的值查找相应的session,也就是说,如果客户端禁用了cookie,那么,每次请求得到的sessionId是不一样的。

图示:
先禁用cookie
在这里插入图片描述
然后再次请求SessionServlet

可以看到,由于禁用了cookie,request中无法携带cookie数据,所以每次请求都会重新创建session,并且将sessionId回写到response的cookie中。
在这里插入图片描述
跟Cookie不同的是session是将数据存储在服务端的。

常用方法

 HttpSession session = request.getSession();//获取session,没有则创建
 session.getId();//获取sessionId
 session.getAttribute("key");//获取存储的某个值
 session.setAttribute("key","value");//存储数据,value是object类型
 session.getCreationTime();//获取session创建的时间
 session.removeAttribute("key");//移除某个数据
 session.invalidate();//重置session,使session失效
 session.setMaxInactiveInterval(1*60*60);//设置会话的超时时间(单位:秒),默认30分钟
 session.getLastAccessedTime();//最后一次修改session的时间

总结一下
Session和Cookie的特点

Session:
保存在服务端
生命周期短,会随着会话的结束而销毁

cookie:
保存在浏览器
保存时间长,可长期保存
一般用于保存不重要的数据

注:转自喻志强的博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值