会话技术之Cookie与Session——个人笔记

让服务器有记忆能力之Cookie、Session

会话技术

会话技术指浏览器访问一个网站后,不管点击了多少超链接,发送了多少请求,
一直到关闭浏览器,离开这个服务器的过程称之为一次会话。

为什么要使用会话技术?

比如当我点击淘宝的登录页面,输入用户名密码后,勾选下次自动登录,下次再次访问淘宝时浏览器就会自动帮我登录。

或者是能够保存我上次浏览过的商品信息,猜我喜欢的商品。

以上的操作必须要让服务器知道“”我“”是谁,而http协议恰巧又是无状态协议。
而无状态的协议是什么意思呢? HTTP无状态协议,是指协议对于交互性场景没有记忆能力。

举个例子:
比方说在购物网站上买一个书包:流程如下
1、输入用户名,密码登录
2、选择一款你喜欢的书包,加入购物车
3、购买支付

所谓的登录,只是验证一下你是否是一个合法的用户,合法则跳到指定页面,不合法则提示用户名或密码错误,而当我门完成登录操作以后服务器就忘记了,忘记了你这个人到底有没有认证过。所以在添加商品的时候, 还是需要让你输入用户名密码,验证你的身份。

所以,当页面之间涉及到交互问题的时候,就会很麻烦了,因为这三步是有依赖的,当你输入完用户名密码,点击登录,验证通过服务器会给你返回200/ok,这时候一个请求与相应就结束了,当你选好物品后试图添加到购物车中,添加购物车这个操作和第一步是有关联的,是谁把什么加入了购物车? 这个人有没有在网站上注册过,是不是一个合法的用户呢?所以此时还需要输入用户名和密码,每做一次操作购物车操作时,都需要输入用户名和密码,反反复复输入一遍又一遍,这是因为服务器不知道你20秒前是否已经登录过。

上面的无状态即无登录状态,即服务器不知道某个用户已经登录过一次了,所以每次交互的时候都需要,反复输入用户名和密码,明明只需要在登录的时候输入用户名和密码,然后在数据库中对比用户名密码和和客户端输入的是否一致,但这下在添加购物车操作的时候也需要做同样的操作。即降低了响应速度,又对用户不友好。

缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另外人们常说的“会话”概念则是上面的交互行为的另一种表述方式。

由于HTTP是一种无状态协议,服务器是服务器知道客户端的状态的,而交互又是需要承前启后的,
即使是简单的购物车功能也要知道用户之选择了什么商品,于是就诞生了两种会话技术、Cookie、Session。

Cookie

HTTP是无状态协议,所有服务器从网络连接上无法得知用户的状态,那么怎么办呢? 就给客户端颁发一个通行证吧,用户的状态都保存在这个通行证上面,无论谁访问的时候都需要携带这个通行证,这样服务器就能从通行证上得知用户的身份了,而这个通行证就是Cookie。

Cookie的工作原理:
如果服务器需要记录该用户的状态。就使用response像客户端发送一个Cookie ,客户端浏览器就会把Cookie保存起来,当浏览器再次向服务器发送请求的时候就会携带该Cookie和URL一起提交到服务器,服务器检查该Cookie从而得知用户的状态,服务器还可以根据用户的状态修改Cookie的内容。

Cookie类用于创建一个Cookie对象
response接口中定义了一个addCookie方法,它用于在其响应头中增加一个响应的Set-Cookie头字段
request接口中定义了一个getCookie方法,它用于获取客户端提交的Cookie

常用的Cookie方法

Cookie API
public Cookie(String name,String value)
setValue 与 getValue
setPath 与 getPath
setDomain 与 getDomain
getName
cookie.setMaxAge(int expiry); 设置Cookie的有效期

简单使用Cookie
使用Cookie记录用户上次访问时间


public class  CookieDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/text;charset=utf-8");

          Cookie[] cookies = req.getCookies();
            if (cookies != null) {
            for (int i = 0;  i < cookies.length; i++) {
                Cookie cookie = cookies[i];
                if (cookie.getName().equals("lastLoginTime")) {
                    long lastLoginTime = Long.parseLong(cookie.getValue());
                    Date date = new Date(lastLoginTime);
                    resp.getWriter().println("上次访问时间:" + date.toLocaleString());
                }
            }
        }

        Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis() + "");
        cookie.setMaxAge(60*60*24);
        resp.addCookie(cookie);
    }

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

Cookie 的不可跨域名性

很多网站都会向浏览器颁发Cookie,Google会向浏览器颁发Cookie,BaiDu也会向浏览器办法Cookie,那么访问Google的时候会不会也带上BaiDu的Cookie呢?答案是否定的,Google具有不可具有不可跨
域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操
Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。

Cookie的有效期
cookie的有效期是通过setMaxAge来设置的。

  1. 如果MaxAge为正数,浏览器就会把Cookie写到硬盘中,只要还在MaxAge毫秒之前,登录网址时 Cookie就有效【不论关了电脑还是浏览器】
  2. 如果Max为负数,Cookie是临时性的,仅在本浏览器中有效,关闭浏览器Cookie就失效了,Cookie也不会写入硬盘中。Cookie默认值就是-1。
  3. 如果MaxAge为0。则代表删除该Cookie。Cookie没有提供删除Cookie的对应方法,把MaxAae设置为0,则表示删除该Cookie。

Session

什么是Session

Session是另一种记录浏览器状态的机制。不同的是Cookie保存在浏览器中,而session保存在服务器中。用户使用浏览器访问服务器的时候,服务器把用户的信息以某种形式记录在服务器,这就是session

如果说Cookie 是检查用户身上的“通行证”来确认用户身份,那么Session就是通过检查服务器上的“客户明细表”来确认用户身份。Session相当于在服务器中建立了一张客户明细表。

为什么要使用session

Session比Cookieyao使用方便,Seesion可以解决Cookie解决不了的事情【Session可以存储对象,Cookie只能存储字符串】

Session API

long getCreationTime();;获取session被创建的时间
String getId();获取Session的id
long getLastAccessedTime();返回Session的最后活跃的时间
ServletContext getServletContext();获取ServletContext对象
void setMaxInactiveInterval(int var1);设置Session超时时间
int getMaxInactiveInterval() ;获取Session超时时间
Object getAttribute(String var1);获取Sessino属性
Enumeration getAttributeNames();获取session的所有属性名
void removeAttribute(String var1);移除session属性
void invalidate();销毁该Session
boolean isNew();该session是否为新的

Seesion作为域对象
从上面的ApI可以看出Session有着和ServletContext类似的方法,Session也是一个域对象。
Session作为一种记录浏览器状态的机制,只要Session对象没有被销毁,Serlvet之间就可
以通过Session对象实现通讯。

一般来讲,当我们要存进的是用户级别的数据就用Session,那么什么是用户级别的呢?
只要浏览器不关闭希望数据还在,就使用Session来保存。

Session的生命周期和有效期

Session在用户第一次访问服务器Servlet,jsp等动态资源的时候被自动创建,Session对象
保存在内存里,这也就是为什么可以通过request对象获取到Session对象,如果访问HTML等动态资源则不会被创建。

Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,无论是否对
Session进行读写,服务器都会认为Session活跃了一次。

由于会有越来越多的用户访问服务器,因此Session也会越来越多。为了防止内存溢出,
服务器会把长时间没有活跃的Session删除,这个时间也就是Session的超时时间。

Session的超时时间默认是30分钟,有三种方式可以对Session的超时时间进行修改

第一种方式 在tomcat/conf/web.xml文件中设置,时间值为20分钟,所有的WEB应用都有效。

<session-config>  
	<session-timeout>20</session-timeout> 
</session-config>

第二种方式:在单个的web.xml文件中设置,对单个web应用有效,如果有冲突,以自己的web应用为准。`

<session-config>
  <session-timeout>20</session-timeout>
</session-config>	

第三种方式:通过setMaxInactiveInterval()方法设置

//设置Session最长超时时间为60秒,这里的单位是秒
httpSession.setMaxInactiveInterval(60);
System.out.println(httpSession.getMaxInactiveInterval());

Session的实现原理

在Servlet3中获取session ,设置一个属性


public class servlet3 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        session.setAttribute("name","看完博客就要点赞!");
    }

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

在Servlet4中可以获取到刚才在Servlet3中设置的session属性

public class Servlet4 extends HttpServlet{
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();

        String value = (String) session.getAttribute("name");

        System.out.println(value);


    }

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

但是当我打开另外一个浏览器访问servlet4的时候,却拿不到session3中存进去的属性了。

那么服务器是如何实现一共session为一个浏览器服务的?为什么服务器为不同浏览器提供不同的session?我用Google浏览器访问servlet3存进去的属性,为什么换成360浏览器就取不出来了?

HTTP是无状态协议,Session不能依据HTTP连接来判断是否是同一个用户,于是浏览器想服务器发送了一个名为JESSION的Cookie,它的值是Session的id值,其实Session是依据Cookie来判断是否是同一个用户。

简单来说,Session之所以可以识别不同的用户,依靠的是Cookie。

当我访问Servlet3的时候,服务器会创建一个Session对象,执行程序代码,并自动颁发一个Cookie给浏览器。

当我再使用浏览器访问servlet4的时候,浏览器会把Cookie的值通过Http协议带过去给服务器,服务器就知道用哪一个Seesion

但是当我换一个浏览器访问servlet4的时候,该浏览器并没有Cookie,服务器就不知道用哪一个Session,所以就获取不到值。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

200Ok。。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值