Session和Cookie一篇理解

Session 和 cookie

一、Cookie

​ Cookie是什么呢?Cookie,有时也用其复数形式 Cookies。类型为“小型文本文件”,是某些网站为了辨别用户身份,进行Session跟踪而储存在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息-----来自维基百科。用一句话来讲,就是存储在客户端服务器上的数据,是由网景公司(也就是这个公司发明了浏览器哦)发明的一种网络会话状态跟踪技术。

1.1 会话

​ 可能有人会提出疑问,网络会话状态又是什么呢?首先我们要弄清网络会话,会话,字面意思上就是一次交谈,就客户端A和服务端B就可以类比成两个人小A和小B,一次会话就是AB之间的一次对话。如果用专业点的术语来讲的话(●’◡’●),就是一次请求与响应。

​ 在一次请求和响应中,肯定是有数据传递的,所以这时,就需要会话状态跟踪 来查看数据在这次会话中的状态,但是在网络层的Http协议是无状态的。


小插曲:无状态是什么?

也就是当我们的小A和小B在进行通话完毕后,他们第二次又见面了,但是他们对上一次的会话一点都不记得了(当然现实中不太可能啦),也就是相当于丢失了在上次会话中的状态。


​ 所以Cookie是由服务器并存放在客户端的一种信息载体,存有这次会话的信息,只要Cookie没有被清空,或者Cookie没有失效,那么会话状态就是有效的。

1.2 Cookie在会话中的状态

​ 用户在第一次请求后,由服务器生成Cookie,并将其封装到响应头中,以响应的方式发送给客户端,客户端接受到这个请求后,保存到客户端。当客户端再次发同类请求,那么就会将Cookie携带上,以此作为凭证,来访问服务端作校验。

1.3 Cookie本质

​ 其实Cookie本质是多个Key-value键值对而已。但是针对不同的浏览器,Cookie的保存方式和保存的位置都不一样。

1.4 JavaEE下的Cookie

常用API
public class ServletDome extends HttpServlet {
    @Override
    protected  void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException{

        //利用唯一的构造函数狗杂Cookie
        Cookie cookie=new Cookie("key","value");
        //绑定这个Cookie是在哪个资源路径下的,注意,这里必须要绑定项目名称
        cookie.setPath(req.getContextPath()+"/a/b");
        /**
         * @target         设置这个Cookie的过时时间,单位是秒
         *      如果时间大于0则需要将这个cookie存入外存中
         *          时间小于就是存在内存(缓存中),关闭页面就消失
         *          时间等于0就是一旦产生就马上失效
         */
        cookie.setMaxAge(60*60);
        //在HTTP Servlet Response中添加这个Cookie键值对
        resp.addCookie(cookie);
    }
}
public class ServletGetCookie extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取请求中的Cookie信息
        Cookie[] cookies=req.getCookies();
        for(Cookie c:cookies){
            System.out.println(c.getName()+"======="+c.getValue());
        }
    }
}

1.5 域属性空间

总的来说一共有三个域属性空间,在使用时优先肯定是使用小的,方便于保障数据的安全性,由大到小依次是:

  • ServletContext

是属于域的,可以完成跨会话的共享数据

  • HttpSession

    置入其中的域属性是会话范围的,可以完成同类请求下的访问共享数据

  • HttpServletRequest

    置入其实中的域属性只有在当前的请求路径下,可以完成跨Servlet共享数据


二、Session

2.1 Session

​ Session也是一种会话状态跟踪技术。当然前面所讲述的Cookie也是同样目的的技术。但是两者并不冲突,通常是将两者进行混合使用,因为Session是将相关数据保存在服务器端的,并不是在客户端。

​ Session是整个Web应用中所使用的,是以javax.servlet.http.HttpSession的接口对象的形式出现。

2.2 域属性空间

Session,简称为域。其实也就是HttpSession,是可以进行跨请求的。

其中有三个方法可以对其数据进行写和读:

  • setAttribute(Stirng name,Object value)

    用于存放数据

  • getAttribute(String name)

    用于获取Value

  • removeAttribute(String name)

    用于删除

2.3 Sesion的具体使用

public class SomeServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        //获取用户提交的参数
        String username=request.getParameter("username");

        //将参数放入request域
        request.setAttribute("user",username);

        //获取Session对象
        HttpSession session=request.getSession(false);

        //在session域中写入属性
        session.setAttribute("username",username);

        response.getWriter().print("SomeServlet: "+username);
    }
}
public class OtherServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String user=req.getParameter("user");

        //获取Session
        HttpSession session=req.getSession(false);

        //从Session中读取指定属性
        String username=null;
        if (session!=null){
            username= (String) session.getAttribute("username");
        }
        PrintWriter out=resp.getWriter();
        out.print("OtherServlet:user: "+user);
        out.print("OtherServlet:username: "+username);
    }
}

2.4 Session工作原理

在系统中会对每一个会话维护一个Session会话,这里扩展下前面的域属性空间,其中,跨域,是指可以跨越不同的服务器;跨请求,是指可以跨越不同的工程;跨Servlet是指可以跨越不同的具体资源。(HttpSession的具体实现类是在Tomcat中的)

  • 写入Session列表

    服务器对当前的Session是以Map管理的,也就是Session列表

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mltw3ewn-1588090079713)(D:\App\Typora\resources\md-image\Session和Cookie\image-20200428222809253.png)]

key是以32位长度的随机串,被称作JSessionID

value是Session对象的引用

当用户第一次提交请求时,服务端Servlet中执行request.getSession()后,会自动生成一个Map.Entry对象,然后存入key-value;

  • 服务器生成并发送Cookie

    在服务端存入了相应的Session信息后,系统还会自动将“JSESSIONID”作为key,sessionid作为value,放到response的头中去,并存入客户端,这个也就是Cookie。

  • 客户端接受并发送Cookie

    客户端将接受到的JSESSIONID这个Cookie放入缓存中,当用户第二次访问的时候,会将缓存中这个Cookie,伴随着请求头的头部信息,一起发送出去。

2.5 Session的失效

我们在平时会发现,当我们长时间不去登录一个网站后,本来会自动显示的账号提示信息会消失不见(这个信息也是由session存放的)。其实这个因为Session失效了。那么什么是失效呢?

首先,我们可以在web.xml中设置session的超时时间(默默提一句,为什么是在web.xml中设置,因为HttpSession的具体实现类是在Tomcat中实现的)

<session-config>
    <!--以分钟为单位-->
    <session-timeout>10</session-timeout>
</session-config>

或者在Java代码中,拿到session对象调用invalidate方法

那么什么时候会失效呢?我们把页面关了算不算以及失效了呢?在平时我们总是这样认为,但其实并不是。在上面我们已经知道session的真正引用会存储在服务端,所以当我们没用Cookie这个凭证时,我们直接拿那32位的门票进去也可以获取到那个Session的引用。所以只有当我们等服务端的session真正失效后才总算是真正安全的。

2.6 重定向和转发的番外

当我们在禁用Cookie后,上面提到了,我们扔可以通过JSeesionID来获取到Session对象。但是当我们重定向时禁掉Cookie时怎么获取那个重定向后的数据呢?我们可以encode来自动通过上面的方法来访问重定向后的禁用掉Cookie的网站

String url=req.getContextPath()+"someSevlet";
url=resp.encodeRedirectURL(url);
resp.sendRedirect(url);

转发也是如此,只是调用的函数不同罢了:

String url=req.getContextPath()+"someSevlet";
url=resp.encodeURL(url);
resp.sendRedirect(url);
)+"someSevlet";
url=resp.encodeRedirectURL(url);
resp.sendRedirect(url);

转发也是如此,只是调用的函数不同罢了:

String url=req.getContextPath()+"someSevlet";
url=resp.encodeURL(url);
resp.sendRedirect(url);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值