Cookie和Session

Posted 小周祖传代码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie和Session相关的知识,希望对你有一定的参考价值。

Cookie和Session区分

1. 会话控制技术

​ 浏览器和服务器之间数据的访问的形式,以及响应的形式都是通过一来一回。如果浏览器发送新的请求和之前的请求没有任何关系。可以使用会话控制技术存储浏览器和服务器之间的交互【核心】信息,之后的浏览器访问服务器可以在对应的【核心】信息中间提交必要内容,简单用户操作逻辑。

​ 会话控制技术主要组成部分是 Cookie and Session可以用于: 自动登陆,IP地址变化提示,上一次访问时间记录。

1.1 使用会话控制的原因

​ HTTP 协议是一个无状态的协议。一个用户向服务器发出请求,然后服务器返回响应,在服务器端不保存任何有关联的信息,因此在下一次的连接的时候,服务器已经没有以前的连接的信息了,无法判断这次的练级而是否和以前的连接属于同一个用户。

​ 浏览器每一次访问服务器,服务器无法知道当前的浏览器访问之前做过什么,不管是浏览器,还是服务器都没有对数据进行保存。

1.2 状态管理

​ web application 会话过程中,浏览器和服务器直接的一次响应和请求就是一次会话,这里需要管理和操作的就是在浏览器和服务器直接交互的过程中,产生无状态的信息,这里可以利用会话控制技术,保存一些浏览器和服务器交互的核心的数据。

​ 可以减少浏览器请求的次数,同时降低服务器处理业务逻辑的压力。并且可以将浏览器的请求和服务器的响应连接到一起。

1.3 核心操作技术

Cookie 客户端保存数据会话的方式。

Session 浏览器保存会话数据的方式

2. Session对象

​ Tomcat 能够使用内置对象记录有关的连接信息。内置对象Session 通过Tomcat 服务器负责创建,Session是实现了HttpSession接口类的一个实例。

【重点】

​ session 是保存在服务器端的一个会话控制对象,保留浏览器访问当前服务器提供的资源和必要的信息。允许浏览器多次的访问情况下,都能够获取到对应的session 信息。

​ session数据

  1. 服务器保存session 数据没有限制。
  2. session存储数据的方式是键值对形式,键是String类型,但是值可以是任意的类型。session可以看做是一个Map双边的队列 HashMap<String ,Object>。
  3. 中文的问题。
  4. 数据量也是没有问题的,但是需要有一定的限制。

2.0 Session 工作原理

Session 会话的技术是依赖于Cookie

  1. 浏览器第一次访问对应的服务器,服务器会根据当前访问的时间,其他参数生成一个Session ID号,这个Session ID 是不能够进行重复的。
  2. 利用Cookie 技术,服务器将Session ID 号发送给浏览器保存。
  3. 浏览器第二次访问对应的服务器,会带有Session ID 号的Cookie 访问对应的资源,服务器能够根据Session ID 找到对应的Session ,从Session 获取对应的数据。
  4. 浏览器如果关闭 Cookie 的技术,Session 使用的时候会非常的麻烦,需要利用URL重写的技术。
  5. 浏览器本地保存Session ID 的cookie JSESSIONID 名字固定。

2.1 session对象的id

场景重现:

​ 当一个用户首次访问web 服务目录中的一个页面的时候,Tomcat服务器产生一个session对象,这个session对象调用相应的方法可以存储用户再去爱访问Web服务目录中各个页面期间提交的各种数据信息,比如姓名、性别等信息。

​ 此时Session对象被分配了一个String类型的ID,Tomcat服务器同时将这个id号发送到用户端,存放在用户的Cookie中。 在这种情况下,Session对象和用户之间建立一对一的对应的关系,即每一个用户都对应着一个Session对象,不用的Session对象互不相同,具有不同的id号码。当用户再次访问该页面的时候,Tomcat 将不会再次创建新的session对象,而是使用完全相同的一个,知道session对象达到了最大的生存的时间或者服务器关闭状态。服务器取消用户的Session对象,即和用户的会话对应的关系消失。当用户重新连接到该页面的时候,服务器会再次创建一个新的Session对象。

​ 总结: 在用户访问页面的时候,会创建一个Session对象,服务器可以在各个页面使用这个Session记录当前的用户的相关的信息。服务器保证不同的用户的Session对象互不相同。

2.2 session 对象与URL重写

​ session 对象是否能够与用户建立起一一对应的关系以来于用户端是否能够支持Cookie.如果用户端不支持Cookie ,那么用户在不同的网页之间的session对象可能是相互不相同的,因为服务器无法将ID存放到用户端,就不能够建立Session对象和用户的一一对应的关系。如果浏览器关闭Cookie的设置,上述的情况就会发生改变,也就是说:同一个用户对应了多个session 对象,这样服务器就无法知道在这些页面上访问的实际上是同一个用户。

​ 如果用户端不支持Cookie,JSP页面可以通过URL重写来实现session对象的唯一性,所谓的URL重写,就是当用户从一个页面重新连接到另外的一个页面的时候,通向这个新的URL添加参数,把session 对象的id 传输过去,这样就可以保证用户在网站各个页面中的session对象是完全相同的。可以使用response 对象调用 encodeURL() 或者encodeRedirectURL() 方法实现URL重写操作。

2.3 session对象存储数据

​ session 对象会驻留在服务器端,该对象在调用某些方法保存用户在访问某个web服务目录期间的有关的数据。当session对象处理数据的时候,非常类似一个购物车,一个用户访问一个商场的时候,类似于一个web服务目录,可以将商品放到购物车中,也能够将之从购物车中拿出来。

方法概念
void setAttribute(String key,Object obj)session 对象可以调用该方法将参数Object指定的对象添加到session对象中,并且为添加的对象指定一个索引的关键字。如果添加的两个对象的关键字相同,则先前添加的对象被清除。
Object getAttribute(String key)获取session对象索引的关键字是key 对象,由于任何对象都能够添加到session对象中,因此使用该方法获取对象的时候,应该使用强制类型转换的类型。
void removerAttribute(String name)session 对象调用该方法关键字key 对应的对象。

2.4 session对象的生存周期

​ session 对象的生存周期依赖于session对象是否调用invalidate() 方法使得session对象无效或者session对象达到了设置的最长的发呆时间。session 对象使用setMaxInactiveInterval(int interval) 方法设置最长的发呆的状态时间,一般来说发呆的时间是30分钟。

2.5 HttpSession 方法

方法功能
Request.getSession();然后存在对应当前请求的Session返回对应Session,如果没有创建一个新的Session
Request.getSession(boolean);参数为true,获取对应请求的Session对象,如果没有创建一个新的Session。参数为false,只会获取对应当前请求的Session,没有返回null
String getId();获取当前Session ID号,ID不可以重复
long getLastAccessedTime()获取上一次的访问时间
setMaxInactiveInterval(int interval);设置当前Session有效时间,单位是秒数
long getMaxInactiveInterval();获取当前Session有效时间
long getCreationTime()获取Session的创建时间
setAttribute(String name, Object value)设置Session中存储的数据,键值对形式,String类型的键,值为Object类型
Object getAttribute(String name)获取指定键值对应的Object数据
removeAttribute(String name)删除对应的键值对
invalidate()销毁Session对象

2.6 总结

对象的销毁

// 销毁对应的session对象
session.invalidate()

使用session 操作

// 如果有对应的session id 查询对应的session 对象,返回HttpSession 对象
// 如果没有对应的session id 查询不到对应的session 对象,会创建新的HttpSession。服务器会在浏览器端留下一个Cookie的信息,JSESSIONID 里面保存的是Session ID

HttpSession session = req.getSession();
sout(session.getID());
session.setMaxInactiveInterval(30)

3. Cookie 对象

3.1 概述

​ Cookie 是浏览器保存访问的WEB Application时留存的会话的数据,服务器会在浏览器访问指定的资源时,使用响应头发送一定的Cookie信息给浏览器保存,浏览器会存储对应的Cookie的数据,并且在下一次的访问对应的WEB Application自动带上对应的Cookie 数据,访问资源。

  1. Cookie 数据时通过Response 响应从Web Appincation 接受,响应头:Set -Cookie
  2. Cookie 数据会随着Request 请求从浏览器到对应的WEB Application 请求头中的Cookie
  3. 会根据Cookie 限制的有效的路径来选择对应的资源
  4. Cookie 的数据在浏览器中进行保存,有一定的限制,浏览器中保存的Cookie 个数总数限制在300左右,单一的站点问题限制的Cookie的个数是20个,单一的Cookie 的数据大小是在4KB的范围之内,单一的Cookie 形式是通过键值对的形式进行创建的,有name 和 value ,并且不支持中文。

3.2 方法

方法功能呢
Cookie(String name, String value)服务器创建一个Cookie对象
setPath(String path)Cookie数据的有效路径
setMaxAge(int time)Cookie的有效时间
Cookie[] Request.getCookies();获取当前请求头中所有的Cookie数据数组
Response.addCookie(Cookie cookie)发送Cookie数据到浏览器

3.3 创建Cookie

// 创建一个Cookie
Cookie cookie = new Cookie("code", "CodingMonkey");
// 设置Cookie的有效路径
cookie.setPath("/");
// 设置当前Cookie的有效时间
cookie.setMaxAge(10);
// 通过Response响应对象发送数据到浏览器
resp.addCookie(cookie);

3.4 服务器获取浏览器请求带有的Cookie的数据


// 从浏览器获取对应的Cookie 数据
@WebServlet("/getCookie")
public class GetCookieServlet extends HttpServlet 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        // 从HttpServletRequest对象中获取浏览器请求服务器带有的Cookie数据
        Cookie[] cookies = req.getCookies();
        for (Cookie cookie : cookies) 
            // 获取Cookie的名字和Cookie的值
            System.out.println(cookie.getName() + ":" + cookie.getValue());
        
    

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        doGet(req, resp);
    

3.5 Cookie 有效的时间

Cookie cookie = new Cookie("code", "Java_Coder");
cookie.setPath("/");
/*
正数 大于0 有效时间,保存在浏览器本地磁盘中,时间Timeout自动销毁
负数 小于0 浏览器未关闭之前有效,内存存储Cookie
0 等于0 销毁Cookie
 */
cookie.setMaxAge(-1);
resp.addCookie(cookie);

3.6 Cookie的路径的问题

Cookie路径限制是为了约束当前Cookie在访问那些资源时带有对应的Cookie数据
	1. 如果是默认情况下,没有自定义约束当前Cookie数据有效路径,默认是当前项目
	2. 设置有效路径为setPath("/") 表示整个Tomcat服务器有效
	3. /Day44/admin 指定Cookie有效路径,就是URL匹配路径,在一定范围内有效,可
	以提高Cookie数据使用的安全性

4. 实现自动登录的操作

4.1 前端展示

// login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
    <style>
        * 
            margin: 0;
            padding: 0;
        

        table, tr, td, th 
            border: 1px silver solid;
        

        table 
            width: 600px;
            margin: auto;
        

        td 
            text-align: center;
            font-size: 32px;
        

        input 
            font-size: 32px;
        
    </style>
</head>
<body>
<div style="width: 100%; height: 100px; background-color: greenyellow"></div>
<hr>
<!--首先需要进行的操作是,登录个人的信息,然后实现验证操作,如果符合操作,然后进入到Servlet——Controller层中进行验证操作-->
<form action="loginServlet" method="post">
    <table>
        <tr>
            <td colspan="2">用户登陆</td>
        </tr>
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="username" placeholder="请输入用户名"></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type="password" name="password" placeholder="请输入密码"></td>
        </tr>
        <tr>
            <td colspan="2"><input type="submit" value="登陆"></td>
        </tr>
    </table>
</form>
</body>
</html>

4.2 Controller层

@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet 
    private static final Integer MAX_IN_ACTIVE_TIME = 60 * 60 * 24 * 15;

    /**
     * 实现核心功能的操作
     *
     * @param req 请求操作
     * @param resp 响应操作
     * @throws ServletException SQL异常抛出
     * @throws IOException IO流异常抛出
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        /*
         * 首先进行编码的操作
         */
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        // 获取用户姓名、用户密码、然后进行登录操作实现
        String username = req.getParameter("username");
        String pass = req.getParameter("password");

        // 进行密码的判定操作。如果密码符合要求,验证通过。
        if ("admin".equals(username) && "root".equals(pass))
            //登录成功的操作
            /**
             * 自动登录的实现操作
             *  1. 创建Session 对象
             *  2. Session对象存储username
             *  3. 设置Session 有效时间
             *  4. 设置和当前同步的Cookie的数据
             *  5. 设置Cookie 有效时间和Session 保持一致
             *  6. 添加Cookie 数据,同时重定向到IndexServlet
             */

            // 创建Session对象
            HttpSession session = req.getSession(true);
            // Session 对象中存储数据username
            session.setAttribute("username",username);
            // 设置Session 有效时间
            session.setMaxInactiveInterval(MAX_IN_ACTIVE_TIME);

            //设置和当前同步的cookie 的数据
            Cookie cookie = new Cookie("JSESSION", session.getId());
            // 设置有效时间和Session一致
            cookie.setMaxAge(MAX_IN_ACTIVE_TIME);

            // 添加Cookie 数据,同时重定向到IndexServlet
            resp.addCookie(cookie);

            // 登录成功之后进行重定向操作
            resp.sendRedirect("indexServlet");

         else 
            //登录失败的操作
            resp.getWriter().append("登录失败");
            // 设置响应头信息。使用的方法是 setHeader(String name,String value)
            resp.setHeader("refresh","3;url=login.html");
        
    


@WebServlet("/indexServlet")
public class IndexServlet extends HttpServlet 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 
        // 先解决乱码问题
        resp.setContentType("text/html;charset=utf-8");

        // 通过session 对象判断是否能够正常的登录操作
        HttpSession session = req.getSession(false);

        // 判断是否登录正常
        if (null == session || null == session.getAttribute("username"))
            resp.getWriter().append("未登录状态,请进行登录操作");

            // 设置响应头信息。使用的方法是 setHeader(String name,String value)
            resp.setHeader("refresh","3;url=login.html");
         else 
            Object username = session.getAttribute("username");
            resp.getWriter().append("<h1>欢迎光临~~~ 尊贵的" + username + "</h1>")
                    .append("<a href='logoutServlet'>退出~~~</a>");
        
    



@WebServlet("/logoutServlet")
public class LogoutServlet extends HttpServlet 
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException 

        //创建Session对象,如果没有则不需要进行创建
        HttpSession session = req.getSession(false);

        if (session != null) 
            //销毁session对象
            session.invalidate();

            // 销毁cookie 对象
            Cookie cookie = new Cookie("JSESSION", "");
            cookie.setMaxAge(0);

            resp.addCookie(cookie);
        
        resp.sendRedirect("login.html");
    
 

Session和Cookie

Session和Cookie介绍

1 什么是会话跟踪技术

会话跟踪是Web程序中常⽤的技术,⽤来跟踪⽤户的整个会话。保持对⽤户会话期间的数据管理。常⽤的会话跟踪技术是Cookie与Session。
Cookie通过在客户端记录信息确定⽤户身份
Session通过在服务器端记录信息确定⽤户身份。

2.1 Cookie

2.1.1 什么是cookie

Cookie是客户端(⼀般指浏览器)请求服务器后,服务器发给客户端的⼀个辨认标识,保存在客户端,当客户端再次向服务器发送请求时,会携带着这个辨认标识,服务器就可以通过这个标识来识别客户端的身份或状态等。

Cookie的作⽤:跟踪会话,记录⼀次会话中(即Session,⼀次会话可能会有多次请求,当然也可以有多个Cookie来跟踪不同的信息)的信息,这样服务器就会知道⽤户的状态,⽐如有没有登录成功,付款时购物⻋中的东⻄等,就相当于贴在客户端脑⻔上的纸条,浏览器看不到,但服务器看得到。

2.1.2 Cookie的应⽤

保持⽤户登录状态:
将⽤户的信息保存到Cookie中,并发送给浏览器,并且将有效时间设置为⼀个较⻓的时间,这样浏览器在以后访问⽹站时,都会带着该Cookie,服务器以此来辨识⽤户,⽤户就不再需要输⼊⽤户名和密码等信息。
记录⽤户名:
⼀旦⽤户登录成功以后,下次再登录时,直接将Cookie中的⽤户名读取并显示出来,这样⽤户就不需要再次输⼊⽤户名,只输⼊密码即可。常见的就是你在游览器上登录了账号,下一次就不用输入密码可以直接登录了。

2.1.3 Cookie的工作原理

工作原理
原理:用户通过浏览器第一次向MyWeb网站发送请求申请OneServlet。OneServlet在运行期间创建一个Cookie存储与当前用户相关的数据,OneServlet工作完毕后,会将【Cookie写入到响应头】交还给当前浏览器。
浏览器接收到响应后,将Cookie存入浏览器的缓存,之后用户通过【同一个浏览器】再次向MyWeb网站发送请求申请TwoServlet时。浏览器会将之前推送过来的Cookie,写入到请求头发送去,此时TwoServlet在运行时,就可以通过读取请求头中Cookie信息,得到OneServlet提供的共享数据。
实现命令:同一个网站的不同请求,Cookie数据是共享的。

2.1.4 总结Cookie

工作流程:

 1. servlet创建cookie,保存少量数据,发送浏览器。
 2. 浏览器获得服务器发送的cookie数据,将自动的保存到浏览器端。
 3. 下次访问时,浏览器将自动携带cookie数据发送给服务器。

cookie操作

	1.创建cookie:new Cookie(name,value)
	2.发送cookie到浏览器:HttpServletResponse.addCookie(Cookie)
	3.servlet接收cookie:HttpServletRequest.getCookies()  浏览器发送的所有cookie       

cookie特点

	1. 每一个cookie文件大小:4kb , 如果超过4kb浏览器不识别
	2. 一个web站点(web项目):发送20个
	3.一个浏览器保存总大小:300个
	4.cookie 不安全,可能泄露用户信息。浏览器支持禁用cookie操作。
	5. 默认情况生命周期:与浏览器会话一样,当浏览器关闭时cookie销毁的。

cookie api

	getName() 获得名称,cookie中的key
	getValue() 获得值,cookie中的value
	setValue(java.lang.String newValue)  设置内容,用于修改key对应的	value值。
	setMaxAge(int expiry) 设置有效时间【】
	setPath(java.lang.String uri)  设置路径【】

3 Session

3.1.1 什么是Session

Session是另⼀种记录客户状态的机制,不同的是Cookie保存在客户端浏览器中,⽽Session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了。

如果说Cookie机制是通过检查客户身上的“通⾏证”来确定客户身份的话,那么Session机制就是通过检查服务器上的“客户明细表”来确认客户身份。Session相当于程序在服务器上建⽴的⼀份客户档案,客户来访的时候只需要查询客户档案表就可以了。

3.1.2 创建Session的格式

Session对应的类为javax.servlet.http.HttpSession类。每个来访者对应⼀个Session对象,所有该客户的状态信息都保存在这个Session对象⾥。Session对象是在客户端第⼀次请求服务器的时候创建的。

Session也是⼀种key-value的属性对,通过getAttribute(Stringkey)和setAttribute(String key,Objectvalue)⽅法读写客户状态信息。Servlet⾥通过request.getSession()⽅法获取该客户的 Session
例如:

HttpSession session = request.getSession(); // 获取Session对象
session.setAttribute("loginTime", new Date()); // 设置Session中的属性                       
out.println("登录时间为:" +(Date)session.getAttribute("loginTime")); // 获取Session属性

3.1.3 Session的⽣命周期

Session保存在服务器端。为了获得更⾼的存取速度,服务器⼀般把Session放在内存⾥。每个⽤户都会有⼀个独⽴的Session。如果Session内容过于复杂,当⼤量客户访问服务器时可能会导致内存溢出。因此,Session⾥的信息应该尽量精简。

Session⽣成后,只要⽤户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。⽤户每访问服务器⼀次,⽆论是否读写Session,服务器都认为该⽤户的Session“活跃(active)”了⼀次。

由于会有越来越多的⽤户访问服务器,因此Session也会越来越多。为防⽌内存溢出,服务器会把⻓时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就⾃动失效了。一般是30分钟

Session的超时时间也可以在web.xml中修改。另外,通过调⽤Session的invalidate()⽅法可以使Session失效。

<session-config> 
 <session-timeout>30</session-timeout>
</session-config>

3.1.4 Session常⽤的⽅法

在这里插入图片描述

3.1.5 Session和Cookie的区别

(1) Cookie数据保存在客户端; Session数据保存在服务器端。
(2) Cookie的安全性较低; Session的安全性较高
(3) Cookie保存的内容是String类型; Session保存的类型是Object

cookie的工作原理?
	 cookie是由服务器端创建发送回浏览器端的,并且每次请求服务器都会将cookie带过去,以便服务器知道该用户是哪一个。
	 其cookie中是使用键值对来存储信息的,并且一个cookie只能存储一个键值对。所以在获取cookie时,是会获取到所有的cookie,然后从其中遍历。

session的工作原理?
	 session的工作原理就是依靠cookie来做支撑,第一次使用request.getSession()时session被创建,
	 并且会为该session创建一个独一无二的sessionid存放到cookie中,然后发送会浏览器端,浏览器端每次请求时,都会带着这个sessionid,服务器就会认识该sessionid,
	 知道了sessionid就找得到哪个session。以此来达到共享数据的目的。
	 这里需要注意的是,session不会随着浏览器的关闭而死亡,而是等待超时时间。

最后,如果有问题,希望指正,一起进步。

以上是关于Cookie和Session的主要内容,如果未能解决你的问题,请参考以下文章

Cookie和Session详解

tomcat负载均衡配置

服务端session笔记

session 与 cookie

java-tomcat-session机制和原理

JSP Session管理