java web会话管理

news2024/9/21 14:28:51

在人机交互过程中,会话管理是指保持用户的整个会话活动的交互与计算机系统跟踪的过程。会话管理分为桌面会话管理、浏览器会话管理、Web会话管理。本书讨论的是Web会话管理(通常指的是session以及Cookie) , 也称为会话跟踪。

会话管理基本原理

使用隐藏域

隐藏域是指将表单中的内容在显示页面时隐藏, 即不显示数据。在JSP中将input标签的type 属性值设定为hidden, 即生成一个隐藏表单域。再将会话的唯一标识记录到隐藏域中的value属性中, 并设定name属性值。当表单提交时, 会话标识也被提交到服务端, 服务端根据它找到对应的会话对象。
使用隐藏域时,需要在每个页面中都包含会话标识表单,这样才能在许多页面跳转之间保存会话,并对它进行管理。此方法实现起来比较烦琐,安全性较差,不适合隐秘性的数据,在目前的开发中较少使用。

使用Cookie

利用Cookie实现会话管理是最容易的实现方式, 也是使用较多的方法。其原理是在服务端保存的会话对象中设定会话的唯一标识, 客户端将会话标识保存在Cookie中, 当浏览器发起请求时,从Cookie中取得会话标识并发送给服务端, 服务端在收到请求后, 根据发送过来的会话标识查找到对应的会话对象,这样服务端就清楚当前是哪个客户端在连接,并且可以从会话中获得信息。
利用Cookie实现会话管理是目前开发中采用的主流方法, 大多数的动态页面开发技术都实现了这一功能,并且其管理流程是自动完成的,在实现上并不需要多大的开发工作量。其实现会话管理的过程如图所示。
在这里插入图片描述

使用URL重写

顾名思义, URL重写是指在URL地址的末尾添加会话标识, 改写了原先的URL地址。其本质是用于唯一标识会话的信息, 以参数的形式添加到URL中, 服务端接收到请求时, 解析出会话标识, 然后利用会话标识查找出与当前请求对应的会话对象。该方法是用在浏览器中Cookie被禁用的情况下,利用该方法可以很好地实现会话跟踪而不会受到浏览器参数设定的影响。
利用URL重写的方法, 其特点是在URL后面添加会话标识, 因此整个Web应用中的超链接或者脚本中用到的URL都需要添加会话标识, Web应用中的每一个页面都需要动态生成, 页面中的每一个链接或者由客户端生成的跳转指令都必须加上会话标识,这样才能确保是当前会话。当客户端访问静态页面时,会话标识将会丢失,当重回动态页面时将不能继续此前的会话,以上是它的特点,也是它的缺陷。
利用该方法还有一个问题, 即当用户在浏览网页时, 可能会将URL复制下来分享给朋友, 因为URL中会包含会话标识, 那么其他人可能与当前浏览者使用同一会话对象, 这样当前浏览者的个人隐私就暴露了,信息不再安全。
无论采用哪种方式实现会话管理,在服务端都需要完成相关代码才能完整地实现会话管理的任务。这些任务主要是生成唯一的会话标识、存储会话对象、从Web容器中取得当前请求的会话、回收空闲会话。

HTTP协议是无意识、单向协议。服务端不能主动连接客户端,只能等待并答复客户端请求。客户端连接服务端, 发出一个HTTP请求, 服务端处理请求, 并返回一个HTTP响应给客户端, 至此, 本次会话结束, 从这一过程可以看出, HTTP协议本身并不支持服务端保存客户端的状态等信息。于是, Web服务器中引入了session的概念, 用来保存客户端的信息。

Session会话管理

使用HttpSession管理会话

在Java中, 使用javax.servlet.http.HttpSession类来实现session会话。每个请求者对应一个session 对象, 客户的所有状态信息都保存在该对象里。当用户第一次请求服务器时, 就创建了session对象。它以key-value 的形式进行保存,通过相对应的读写方法来保存客户的状态信息,例如getAttribute(String key) 用于获得参数、setAttribute(String key, Object value) 用于设定参数和参数值。在Servlet中可以通过request.get Session() 方法获取客户的session对象, 例如:

HttpSession session = request.getSession();
session.setAttribute("username","john");

在JSP中内置了Session对象, 可以直接使用, Servlet使用上述方法获取session对象。若JSP 页面中设定了<%@page session=“false”%>, 则该JSP页面的session对象是不可用的。下面通过例子说明如何利用session来保存登录信息。
login.jsp

<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" %>
<%
    String userName = (String) session.getAttribute("username");
    String basePath = request.getContextPath();
    if (userName != null && userName != "") {
        response.sendRedirect(basePath + "/index.jsp");
        return;
    }
%>
<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<h1>用户登录</h1>
<form action="<%=basePath%>/login" method="post">
    <p>
        <label>输入用户名:</label>
        <input type="text" name="name">
    </p>
    <p>
        <label>输入密码:</label>
        <input type="password" name="pwd">
    </p>
    <p>
        <input type="submit" value="提交">
    </p>
</form>
</body>
</html>

loginServlet.java

package com.wujialiang;

import javax.servlet.RequestDispatcher;
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 = "login",urlPatterns = {
        "/login"
})
public class loginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userName = req.getParameter("name");
        String pwd = req.getParameter("pwd");
        String basePath = getServletContext().getContextPath();
        if(userName.equals("admin")&&pwd.equals("123456")){
            HttpSession session = req.getSession();
            session.setAttribute("username",userName);
            RequestDispatcher requestDispatcher = req.getRequestDispatcher("/index.jsp");
            requestDispatcher.forward(req,resp);
        }else{
            //错误跳转登录页面
            RequestDispatcher requestDispatcher = req.getRequestDispatcher("/login.jsp");
            requestDispatcher.forward(req,resp);
        }
    }
}

index.jsp

<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" %>
<%
    String userName = (String) session.getAttribute("username");
    String basePath = request.getContextPath();
    if (userName == null || userName == "") {
        response.sendRedirect(basePath + "/login.jsp");
        return;
    }
%>
<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<h1>欢迎你:<%=userName%>
</h1>
</body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

HttpSession管理会话的原理

HttpSession 会话管理是利用服务器来管理会话的机制,当程序为某个客户端的请求创建了一个session的时候, 服务器会检查客户端的请求是否已经包含了一个session标识, 如果已经有了session标识, 服务器就把该session检索出来使用; 如果请求不包含session标识, 就为客户端创建一个该请求的唯一session标识。其会话管理流程如图所示。
在这里插入图片描述

HttpSession与URL重写

提到URL重写是用在客户端不支持Cookie的情况下。它的实现方式是将Session的标识id添加到URL中。服务器通过解析重写后的URL获取Session的标识id。这样即使客户端不支持Cookie, 也可以用Session来记录状态信息。重写的方法如下:

response.encodeURL("login.jsp");
//或者
response.sendRedirect(response.encodeURL("login.jsp"));

这两种方法的效果是一样的, 如果客户端支持Cookie, 那么生成的URL不变; 如果不支持,生成的URL中就会带有jsessionid字符串的地址, 超链接如图所示。

在这里插入图片描述
从图中可以看出, 在URL的文件名后面, 参数的前面添加了字符串“; jsessionid=标识id”o 用户单击这个链接时, 客户端会把session的id值通过URL提交到服务器上, 服务器通过解析URL 地址获得session的id值。

HttpSession中禁用Cookie

可以通过配置的方式在Web项目中禁用Cookie, 禁用方法如下:
在webapp目录下新建META-INF文件夹,打开或者新建context.xml

<?xml version="1.0" encoding="UTF-8" ?>
<Context cookies="false">
</Context>

如果想全局配置需要修改tomcat下的context.xml
上述两种方法都是在Context元素中添加属性cookies=“false”, 二者的区别在于前者是对单个项目的Cookie禁止, 后者是禁止部署在Tomcat服务器里的Web项目使用Cookie。

HttpSession的生命周期

Servlet有它的生命周期, 同样, HttpSession也有其生命周期:创建→使用→消亡。

HttpSession对象的创建

当客户端第一次访问服务器时, 服务器为每个浏览器创建不同Session的ID值。在服务器端使用request.getSession() 或者request.get Session(true) 方法来获得HttpSession对象。

HttpSession对象的使用

创建HttpSession对象后, 使用Session对象进行数据的存取和传输。具体的过程如下:

  • 将产生的sessionID存入Cookie中。
  • 当客户端再次发送请求时, 会将sessionID与request一起传送给服务器端。
  • 服务器根据请求过来的sessionID与保存在服务器端的session对应起来,判断是否为同session。

HttpSession对象的消亡

有如下3种方式可以结束session对象:

  • 将浏览器关闭。
  • 调用HttpSession的invalidate() 方法。
  • session超时。
    关闭浏览器, 这样会使浏览器端的session失效, 服务器端session并不会失效。如果服务器进程终止了, 那么session会被结束。
    在session结束时, 服务器会清空当前浏览器的相关数据信息。
    以上就是HttpSession的生命周期过程, 在请求处理时不断循环第2步, 直到session对象消亡。session是保存在服务器内存中的, 每个用户都有一个独立的session。session中的内容应该尽量少,这样当有大量客户访问服务器时才不会导致内存溢出。

只有访问JSP、Servlet时才会创建session, 访问静态页面时是不会创建session对象的。

HttpSession的有效期

通常情况下, 都给session设定一个有效期, 当某用户访问的session超过这个有效期时, 即不是活跃的session, 那么session就失效了, 服务器会将它从内存中清除。设定session的有效期有以下三种方法:

  • 在对应的Web服务器配置中设置所有session的有效期。
  • 调用session的setMaxInactiveInterval(long interval) 进行设定。
  • 在web.xml中修改, 例如:
<session-config>
 <!--会话超时时长30分钟-->
 <session-timeout>30</session-timeout>
</session-config>

调用session的invalidate() 可以销毁session.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/480672.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习笔记 图像特征提取器(卷积变体)的技术发展与演变

一、图像特征提取器简述 图像特征提取器是可用于从图像中学习表示的函数或模块。最常见的特征提取器类型是卷积,其中内核在图像上滑动,允许参数共享和平移不变性。 在深度学习技术的快速发展过程中,基于卷积也演变出来了若干新技术由于图像特征的提取,这里进行了一下简单梳…

[oeasy]python0145_版本控制_git_备份还原

git版本控制 回忆上次内容 上次我们了解了 try 的完全体 try 尝试运行 except 发现异常时运行的代码块 else 没有发现异常时运行的代码块 finally 无论是否发现异常最终都要运行的代码块 发现导入部分 可以再分为两个子模块一个输入 a一个输入 b 可以再拆分么&#xff1f;&…

【Python基础练习100题--第一篇:文件篇】

前言 这些题都是在B站的练习题&#xff0c;链接在这 对于刚学python的新手来说十分的适合&#xff0c; 可以加强和巩固我们的基础。 嘿嘿 一起噶油吧&#xff01;&#x1f349; &#x1f349;1.对学生成绩排序 # 这里对字典进行排序&#xff0c;同事使用到了sorted函数 # 这…

【安全工具】Httpx信息收集

文章目录 前言一、下载二、使用步骤1.帮助文档2.常用命令常用组合命令&#xff1a; 总结 前言 HTTPX 是一个功能强大的 HTTP 客户端工具&#xff0c;用于执行各种网络任务&#xff0c;例如发现 Web 应用程序漏洞、探测域名和端口等。它使用了 retryablehttp 库来运行多个探测器…

[计算机图形学]相机与透镜(前瞻预习/复习回顾)

一、相机 1.成像方法 成像方法有两种&#xff0c;合成和捕捉&#xff0c;我们之前所说的光栅化和光线追踪都属于合成的方法&#xff0c;也就是实际上不存在的东西。而另一种成像方法叫做捕捉成像&#xff0c;也就是把真实世界中存在的一些东西变成照片这就是捕捉成像&#xf…

【量化课程】01_投资与量化投资

文章目录 1.1 什么是投资1.1.1 经济意义上的投资1.1.2 投资的分类1.1.3 金融投资1.1.4 个人投资者投资品种1.1.5 投资VS投机 1.2 股票投资的基本流程1.3 常见的股票投资分析流派1.3.1 投资者分析流派 1.4 什么是量化投资1.4.1 量化投资基本概念1.4.2 量化投资的优势1.4.3 量化投…

C多线程、锁、同步、信号量

文章目录 一 线程函数1.1 创建线程1.2 线程退出1.3 线程回收1.4 线程分离&#xff1a;1.5 其他线程函数1.5.1 线程取消1.5.2 线程ID比较 二 线程同步2.1 互斥锁2.1.1定义2.1.2 初始化2.1.3 销毁2.1.4 加锁 、 常试锁、解锁2.1.5 互斥锁使用 2.2 死锁2.3 如何避免死锁2.4 读写锁…

05_从0运行,重定位,初始化,中断再到定时器

总结 这边简单讲讲,代码上电后从0开始发生了什么,为什么要重定位把代码复制到sdram, bin文件前面几条跳转函数都跳转去哪 中断产生后发生什么 重定位问题 1.为什么需要重定位 把程序从一个位置移到另一个位置 叫重定位 可以只重定位部分段的数据 也可以把所有的都重定位到sd…

Linux运维之shell基础

一.流程控制 1.if判断 基本语法&#xff1a; if [ 条件判断式 ] then 程序 elif [ 条件判断式 ] then 程序 else 程序 fi注意事项&#xff1a; ①[ 条件判断式 ]&#xff0c;中括号和条件判断式之间必须有空格②if 后要有空格 例如&#xff0c;现在写一个if.sh脚本文件 #…

echarts关于自定义饼图数据刷新和颜色渲染问题

在使用echarts的自定义饼图Customized Pie时&#xff0c;定义的动态数据会发生颜色无法渲染的问题&#xff0c;如下图所示&#xff1a; 该图表的颜色是根据itemStyle内的color属性而来&#xff0c;如下&#xff1a; itemStyle: {color: #4d90fe, /* 图表的颜色 */shadowBlur:…

【python知识】importlib包详解

importlib — The implementation of import — Python 3.11.3 documentation 目录 一、说明 二、 模块导入简介 2.1 最简单的 importlib用途 2.2 importlib 包的目的有三个 2.3 import_module() 和__import__() 三、高级模块使用 3.1 动态引入 3.2 模块引入检查 3…

SpringBoot整合Mybatis-Plus、Jwt实现登录token设置

Spring Boot整合Mybatis-plus实现登录常常需要使用JWT来生成用户的token并设置用户权限的拦截器。本文将为您介绍JWT的核心讲解、示例代码和使用规范&#xff0c;以及如何实现token的生成和拦截器的使用。 一、JWT的核心讲解 JWT&#xff08;JSON Web Token&#xff09;是一种…

JavaWeb——HTML和CSS

HTML和CSS定义 标记语言 :比如XML:可扩展的标记语言&#xff0c;标签可以自己定义&#xff0c;解析时需要按照定义的规则去解析。 学习目的:掌握常见标签和常见样式的使用 HTML 结构: 特点: 1.不区分大小写&#xff0c;不管是<html>还是<HTML>都是一样的作用 …

错题笔记第一篇

目录 1. strlen的用法2. case3. switch4. 二分查找 1. strlen的用法 正确答案 &#xff1a;C strlen计算的是字符串的长度&#xff0c;二字符串是以\0结尾&#xff0c;而咱们并没有存储\0&#xff0c;后序的空间是未知的&#xff0c;strlen找不到\0就会一直找&#xff0c;所以它…

如何使 VSCode 中 CMake Debug 的输出显示在 cmd 上而不是自带的 debug console

如何使 VSCode 中 CMake Debug 的输出显示在 cmd 上而不是自带的 debug console 首先需要明确的一点是从 VSCode 插件商店下载的 CMake 是默认打印输出的结果在 debug console 中的&#xff0c;就像下面这样&#xff1a; 可以看到&#xff0c;一个问题是在加载 dll 时候会频繁…

82. Python split方法-分割字符串

82. split方法-分割字符串 文章目录 82. split方法-分割字符串1. 什么是split( )函数2. split( )方法的语法格式如下&#xff1a;3. 实操练习4. 列表索引取值知识回顾5. 用split方法分解网址提取有效信息6. 从地址信息中拆分省、市、区信息 1. 什么是split( )函数 split[splɪ…

深度学习模型压缩与优化加速

1. 简介 深度学习&#xff08;Deep Learning&#xff09;因其计算复杂度或参数冗余&#xff0c;在一些场景和设备上限制了相应的模型部署&#xff0c;需要借助模型压缩、系统优化加速、异构计算等方法突破瓶颈&#xff0c;即分别在算法模型、计算图或算子优化以及硬件加速等层…

《LearnUE——基础指南:上篇—2》——GamePlay架构之Level和World

目录 听说世界是由多个Level组成的 1.2.1 引言 1.2.2 建造大陆&#xff08;ULevel&#xff09; 1.2.3构建世界&#xff08;World&#xff09; 1.2.4总结 听说世界是由多个Level组成的 1.2.1 引言 上小节谈到Actor和Component的关系&#xff0c;UE利用Actor的概念组成了世…

GitLab统计代码量

gitlab官方文档&#xff1a;https://docs.gitlab.com/ee/api/index.html 1、生成密钥 登录gitlab&#xff0c;编辑个人资料&#xff0c;设置访问令牌 2、获取当前用户所有可见的项目 接口地址 GET请求 http://gitlab访问地址/api/v4/projects?private_tokenxxx 返回参数 …

【文章学习系列之模型】Non-stationary Transformers

本章内容 文章概况总体结构主要模块Series Stationarization&#xff08;序列平稳化模块&#xff09;De-stationary Attention&#xff08;逆平稳化注意力模块&#xff09; 实验结果消融实验总结 文章概况 《Non-stationary Transformers:Exploring the Stationarity in Time …