前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java面试HTTP篇(三):Session(会话)

Java面试HTTP篇(三):Session(会话)

作者头像
二哥聊运营工具
发布2021-12-17 09:43:36
5980
发布2021-12-17 09:43:36
举报
文章被收录于专栏:程序员泥瓦匠

摘要: 原创出处 www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢!

继《图解 Http 协议》和《图解 Cookie》 之后,被大家猜到写 Session 。本系列皆以图为主,力求简单易懂,娓娓道来~

一、Session由来

HTTP 的无状态,也就是说,每次请求都是独立的线程。举个例子吧:购物中,你选择了 A 商品,加入购物车,这就是 A 线程。然后在选择 B 商品就是 B 线程。可是每次线程独立(对容器而言,A、B成了不同的用户),线程 A 不知道有 B,B 也不知道 A。如何一起付款呢?

简单来说:怎么保存同个用户多个请求会话状态呢HTTPS 保证连接是安全的,可以使它与一个会话关联。

问题就在于如何跟踪同一个用户,选择可以很多:

1、EJB (有状态会话bean保存会话状态) 环境苛刻需要带EJB的J2EE服务器,而不是Tomcat这种Web容器。 2、数据库(这貌似万能的。针对数据) 3、就是我们要讲的 HttpSeesion保存跨一个特定用户多个请求的会话状态。 4、上面说的 HTTPS ,条件太苛刻了。

如图:

二、Session机制

机制,什么用词有点高大上。其实就是把它内在的一点东西说出来。主要两个W:What?How?

What is Session?

Session代表着服务器客户端一次会话的过程。直到 Session 失效(服务端关闭),或者客户端关闭时结束。

How does session works?

Session 是存储服务端的,并针对每个客户端(客户),通过 SessionID 来区别不同用户的。Session 是以 Cookie 技术或 URL 重写实现。默认以 Cookie技术实现,服务端会给这次会话创造一个 JSESSIONID 的 Cookie 值。

补充

其实还有一种技术:表单隐藏字段。它也可以实现 Session 机制。这里只是作为补充,服务器响应前,会修改 Form 表单,添加一个 SessionID 类似的隐藏域,以便传回服务端的时候可以标示出此会话。 这技术,也可以使用在 Web 安全上,可以有效地控制 CRSF 跨站请求伪造

三、详细介绍Seesion机制过程

图中这是 Session 第一次请求的详细图。以 Cookie 技术实现,我也写了个HttpSessionByCookieServletT.java 的 Servlet 小 demo,模拟下 Seesion 的一生。代码如下:

代码语言:javascript
复制
package org.servlet.sessionMngmt;
 
import java.io.IOException;
import java.io.PrintWriter;
 
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;
/*
 * Copyright [2015] [Jeff Lee]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
 
/**
 * @author Jeff Lee
 * @since 2015-7-12 10:58:28
 *  HttpSession的默认Cookie实现案例
 */
@WebServlet(urlPatterns = "/sessionByCookie")
public class HttpSessionByCookieServletT extends HttpServlet {
 
    private static final long serialVersionUID = 1L;
 
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
         
        // 获取session
        // 如果是第一次请求的话,会创建一个HttpSeesion,等同于 req.getSession(true);
        // 如果已存在session,则会获取session。
        HttpSession session = req.getSession();
         
        if (session.isNew()) {
            // 设置session属性值
            session.setAttribute("name", "Jeff");
        }
        // 获取SessionId
        String sessionId = session.getId();
         
        PrintWriter out = resp.getWriter();
        // 如果HttpSeesion是新建的话
        if (session.isNew()) {
            out.println("Hello,HttpSession! <br>The first response - SeesionId="
                    + sessionId + " <br>");
        } else {
            out.println("Hello,HttpSession! <br>The second response - SeesionId="
                    + sessionId + " <br>");
            // 从Session获取属性值
            out.println("The second-response - name: "
                    + session.getAttribute("name"));
        }
         
    }
     
}

代码都在github上: https://github.com/JeffLi1993

① 客户端向服务端发送第一次请求

此时,客户端想让服务端把自己的名字设置到会话中。

② 服务端的容器产生该用户唯一 SessionID 的 Session 对象,并设置值

可以从代码中看出通过从请求中 req.getSession(),新生成了一个 Session 对象。并设置了 setAttribute(“name”, “Jeff”),key 为 string,value 是对象皆可。

这时候,我们不用再把session通过cookie技术处理,容器帮我们处理了。

③ 容器响应 Set-Cookie:JSESSIONID= …

我们可以F12,查看此次响应。

从图中可得到,每个 Cookie 的 set,都有一个对应 Set-Cookie 的头。HttpOnly 可是此 Cookie 只读模式。只不过 Session 唯一标识是:JSESSIONID

④ 浏览器解析 Cookie,保存至浏览器文件。

如图,找到了对应的 Session 存储的 cookie 文件。该文件被保护不能打开。图解Cookie 教你怎么找到该文件。

第二次请求会发什么变化呢?

下面,泥瓦匠重新访问了这个地址:

① 再次请求

此时,请求会有 Cookie 值:JSESSIONID=… 该值传给服务端

② 容器获取 SessionId,关联 HttpSession

③ 此时响应无 SetCookie

如图:

但是这次请求,我们响应出上一次请求set的值。Jeff 就打印出来了!

关于服务端获取 session,也就是从请求中获取 session 对象,容器会帮你根据Cookie 找到唯一的 session 对象。

泥瓦匠记忆小抄:Seesion机制,记住两次请求图即可。

四、补充

点到为止哈~ 以后详细写。此图来自网络

上图 Bad guy,就是攻击者。跨站请求伪造,伪造用户请求来对服务器数据或者是用户等造成威胁。web 安全也就是从这些基础中慢慢提升。

五、总结

1、大概地描述了 session 的工作机制,和一些安全相关。记住 Seesion 是什么,怎么用,在服务端客户端之间怎么传输即可。 2、从基础中学习,预祝大家双十一剁手快乐。

如以上文章或链接对你有帮助的话,别忘了在文章结尾处评论哈。你也可以分享哦,让更多的人阅读这篇文章。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员泥瓦匠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Session由来
  • 二、Session机制
  • 三、详细介绍Seesion机制过程
  • 四、补充
  • 五、总结
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档