JavaWeb开发Session管理

简介: JavaWeb开发Session管理

博主信息:

📢@博主: 嘟嘟的程序员铲屎官
💬:一位爱喵咪,爱开源,爱总结,爱分享技术的Java领域新星博主,如果你想和博主做朋友,关注博主,并私聊博主(给我发一条消息我就会关注你喔),博主本人也十分喜欢解决问题,如果你有什么问题,也可以来私聊博主喔,希望能够和C站的朋友相互学习,相互进步。
💬:关于本篇博客,最近在学习JavaWeb部分的知识,对<<Servlet和JSP学习指南>>本书第二章Session管理进行个人总结,如果有什么错误的,请各位大佬能够及时提出,以免小弟误人子弟!

资料下载:
Servlet和JSP学习指南:https://pan.baidu.com/s/1vqzRAE7bfbOGJYgXLFbjGg 提取码:1o7u

相关学习链接:
廖雪峰-使用Session和Cookie
菜鸟编程-Servlet Cookie 处理
菜鸟编程-Servlet Session 跟踪

一.Session管理

关于什么是Session管理?
搜狗百科:

Session:在计算机中,尤其是在网络应用中,称为“会话控制”。 Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。例如,如果用户指明不喜欢查看图形,就可以将该信息存储在 Session 对象中。

<<Servlet和JSP学习指南>>本书第二章Session管理讲解了四种保持状态的四种方法:

  • 网址重写
  • 隐藏域
  • cookie
  • HttpSession

1.网址重写

网址重写是一种Session追踪技术,需要将一个或多个token作为一个查询字符串添加到一个URL中。token的格式一般是: 键=值

在这里插入图片描述
注意:
URL和token之间要用一个问号(?〉隔开,两个token之间则是用一个&符号隔开。

缺点:
在这里插入图片描述

例子:
项目结构:
在这里插入图片描述
前端页面(Login.html):
在这里插入图片描述
注意在web.xml中设置首页
在这里插入图片描述
通过Servlet进行交互(Login.java)
在这里插入图片描述
运行效果:
在这里插入图片描述

在这里插入图片描述
分析:
(跳转之后的地址如下:)
http://localhost:8085/app02/login?userName=admin&userPwd=123456

  • 数据通过URL后面的token传递到下一个页面,在下一个页面(即下一个http请求)中,通过request.getParameter(name)获取tonken的值,从而保证了数据在不同页面间的传递。

在这里插入图片描述

  • 表单的提交方式为get时,表单中的参数也会显示的出现在URL后面

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

  • Token的键名就是表单Input标签中的name的值,Token的值为用户输入的值

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

2.隐藏域

利用隐藏域来保持状态,与采用网址重写技术类似。但它不是将值添加到URL后面,而是 将它们放在HTML表单的隐藏域中。当用户提交表单时,隐藏域中的值也传送到服务器。 只有当页面包含表单,或者可以在页面中添加表单时,才适合使用隐藏域。这种技术胜过网址重写技术的地方在于,可以将更多的字符传到服务器,并且不需要进行字符编码。但是像网址重写一样,也只有当要传递的信息不需要跨越多个页面时,才适合使用这种技术。

login.html:
在这里插入图片描述
Login.Java:
在这里插入图片描述
运行效果:
在这里插入图片描述
在这里插入图片描述

3.cookie

  • cookie适用于那些需要跨越许多页面的信息
  • cookie是作为HTTP标头嵌入的,因此传输它的过程由HTTP协议处理
  • 根据自己的需要设置cookie的有效期限
网址重写和隐藏域都只适用于保持那些不需要跨越许多页面的信息。如果这些信息需要跨越很多页面,这两种技术就变得很难实现,因为你必须管理每一个页面的信息。值得庆幸的是,cookie能够解决网址重写和隐藏域都无法解决的问题。
cookie是自动地在Web服务器和浏览器之间来回传递的一小块信息cookie适用于那些需要跨越许多页面的信息。由于 cookie是作为HTTP标头嵌入的,因此传输它的过程由HTTP协议处理。除此之外,还可以 根据自己的需要设置cookie的有效期限。对于Web浏览器而言,每台Web 服务器最多可以支持20个cookie。

关于cookie是作为HTTP标头嵌入的:
在这里插入图片描述

(1) 创建cookie
Cookie cookie = new Cookie (name, value) ;
(2) 创建Cookie之后,可以设置它的domain,path及maxAge属性。尤其值得关注的是maxAge 属性,因为它决定cookie的有效期限。
cookie.setMaxAge(number);
  • number>0:cookie存活number秒
  • number<0:此cookie只是存储在浏览器内存里,只要关闭浏览器,此cookie就会消失。maxAge默认值为-1。
  • number=0:从客户端电脑或浏览器内存中删除此cookie

备注:

  • 创建一个新Cookie时,除了指定名称和值以外,通常需要设置setPath("/"),浏览器根据此前缀决定是否发送Cookie。如果一个Cookie调用了setPath("/user/"),那么浏览器只有在请求以/user/开头的路径时才会附加此Cookie。
  • 如果访问的是https网页,还需要调用setSecure(true),否则浏览器不会发送该Cookie。
(3) 为了将一个cookie发送到浏览器,需在HttpServletResponse上调用add方法
httpservletResponse.addCookie ( cookie) ;
(4) 在HttpServletRequest中使用getCookies()方法获取Cookie数组,无法直接通过name获取指定Cookie

实例:
login.html
在这里插入图片描述
login.java
在这里插入图片描述
mainServlet.java
在这里插入图片描述

运行效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
等待60s后刷新页面
在这里插入图片描述

4.HttpSession

  • 注意,与网址重写、隐藏域和cookie不同的地方在于,放在HttpSession中的值是保存在内存中的。因此,你只能将尽可能小的对象放在里面,并且数量不能太多。即使现代的
  • 添加到 HttpSession中的值不一定是String,可以为任意Java对象,只要它的类实现了java.io.Serializable接口即可,以便当Servlet容器认为有必要的时候,保存的对象可以序列化成一个文件或者保存到数据库中,例如,当容器的内存快要用完的时候。仍然可以将非序列化的对象保存在HttpSession中,但是如果Servlet容器试图将它们序列化,将会以失败告终,并抛出异常。
  • setAttribute方法要求不同的对象要有不同的名称。如果传递一个之前用过的属性名称,那么该名称将与旧值无关联,而与新值相关联了。
  • Servlet容器为它所创建的每一个HttpSession生成一个唯一标识符,并将这个标识符作为token发送给游览器,通过在HttpSession中调用getld方法,可以获取HttpSession的标识符。
HttpSession是当一个用户第一次访问某个网站时自动创建的。通过在HttpServlet-Request中调用getSession方法,可以获取用户的 HttpSession,通过HttpSession的setAttribute 方法将一个值放在HttpSession中,。
(1) 创建HttpSession
HttpSession httpSession=req.getSession(false);
  • Httpsession getSession ()
  • HttpSession getSession (boolean create)

备注: 无参的getSession方法返回当前的 HttpSession,如果当前没有,则创建一个并返回。getSession(false)方法返回当前的HttpSession(若有),如果没有,则返回null。getSession(true)方法返回当前的HttpSession(若有),如果没有,则新建一个并返回。

(2) 将数据放入到HttpSession中
void setAttribute(java.lang.string name,java.lang.0bject value)
(3) 获取HttpSession里的数据
  • 获取HttpSession的标识
httpSession.getId()
  • 通过name获取指定Session的数据
httpSession.getAttribute(arg0)
  • 通过Enumeration获取所有的Session信息
httpSession.getAttributeNames()

遍历Enumeration<String>:
在这里插入图片描述
例子:
Login.html
在这里插入图片描述
HttpSessionServlet.Java

package servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

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;

/**
 * Servlet implementation class HttpSessionServlet
 */
@WebServlet("/HttpSessionServlet")
public class HttpSessionServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            String info = null;
            String info2 = "";
            String sessionId = null;
            // 创建HttpSession
            HttpSession httpSession = req.getSession(false);
            if (httpSession!=null) {
                // 获取Session的标识
                sessionId = req.getSession().getId();
                System.out.println(sessionId);
                // 通过name获取Session的值
                String[] userInfo=(String[])httpSession.getAttribute("user1");
                info="</br>userName:"+userInfo[0]+"userPwd:"+userInfo[1];
                // 获取所有Session的值
                Enumeration<String> enumeration= httpSession.getAttributeNames();
                while (enumeration.hasMoreElements()) {
                    // 获取Session中的name
                    String name=(String) enumeration.nextElement();
                    // 通过name获取Session的值
                    info2+="</br>userName:"+name
                            +";userPwd:"+((String[])httpSession.getAttribute(name))[1]
                                    +"</br>";
                }
            }
            
            
            //设置编码为utf-8
            req.setCharacterEncoding("utf-8");
            resp.setCharacterEncoding("utf-8");
            resp.setContentType("text/html");
            PrintWriter writer=resp.getWriter();
            writer.print("<html><head></head>");
            writer.print("<body>Session的标识:"+sessionId
                    +"</br>user1的信息:"+info
                    +"</br>Session中所有信息:"+info2
                    +"</body></html>");
            
        }
        
        
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
          doGet(req, resp);
        }

}

运行效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

5.总结

本章学习了Session管理和4种Session管理技术。网址重写和隐藏域主要针对“轻量化”的Session追踪技术,它适用于不需要跨越许多页面的信息。另两种技术:cookie和HttpSession对象则比较灵活,但绝非没有局限性。在使用HttpSession对象时要特别小心,因为每个对象都会消耗服务器的内存。
相关文章
|
3天前
|
人工智能 自然语言处理 Java
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
文章介绍了Spring AI,这是Spring团队开发的新组件,旨在为Java开发者提供易于集成的人工智能API,包括机器学习、自然语言处理和图像识别等功能,并通过实际代码示例展示了如何快速集成和使用这些AI技术。
Spring AI,Spring团队开发的新组件,Java工程师快来一起体验吧
|
8天前
|
前端开发 Oracle Java
【前端学java】java开发的依赖安装与环境配置(1)
【8月更文挑战第8天】java开发的依赖安装与环境配置
26 1
【前端学java】java开发的依赖安装与环境配置(1)
|
1天前
|
数据采集 供应链 JavaScript
分享基于Java开发的Java毕业设计实战项目题目
这篇文章分享了67套基于Java开发的毕业设计实战项目题目,覆盖了互联网、企业管理、电子政务、Java基础项目、ERP系统、校园相关、医疗以及其他细分行业等多个领域,并推荐了使用IDEA、Vue和Springboot的技术栈。
|
1天前
|
分布式计算 Java API
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率
Java 8带来了流处理与函数式编程等新特性,极大提升了开发效率。流处理采用声明式编程模型,通过filter、map等操作简化数据集处理,提高代码可读性。Lambda表达式支持轻量级函数定义,配合Predicate、Function等接口,使函数式编程无缝融入Java。此外,Optional类及新日期时间API等增强功能,让开发者能更优雅地处理潜在错误,编写出更健壮的应用程序。
6 1
|
6天前
|
SQL 存储 Java
完整java开发中JDBC连接数据库代码和步骤
该博客文章详细介绍了使用JDBC连接数据库的完整步骤,包括加载JDBC驱动、提供连接URL、创建数据库连接、执行SQL语句、处理结果以及关闭JDBC对象的过程,并提供了相应的示例代码。
|
6天前
|
安全 前端开发 Java
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
在Web安全上下文中,源(Origin)是指一个URL的协议、域名和端口号的组合。这三个部分共同定义了资源的来源,浏览器会根据这些信息来判断两个资源是否属于同一源。例如,https://www.example.com:443和http://www.example.com虽然域名相同,但由于协议和端口号不同,它们被视为不同的源。同源(Same-Origin)是指两个URL的协议、域名和端口号完全相同。只有当这些条件都满足时,浏览器才认为这两个资源来自同一源,从而允许它们之间的交互操作。
Web端系统开发解决跨域问题——以Java SpringBoot框架配置Cors为例
|
23天前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
【7月更文挑战第28天】在 Android 开发中, NDK 让 Java 与 C++ 混合编程成为可能, 从而提升应用性能。**为何选 NDK?** C++ 在执行效率与内存管理上优于 Java, 特别适合高性能需求场景。**环境搭建** 需 Android Studio 和 NDK, 工具如 CMake。**JNI** 构建 Java-C++ 交互, 通过声明 `native` 方法并在 C++ 中实现。**实战** 示例: 使用 C++ 计算斐波那契数列以提高效率。**总结** 混合编程增强性能, 但增加复杂性, 使用前需谨慎评估。
58 4
|
1天前
|
人工智能 网络协议 Java
23.12月中旬 上海寻序人工智能科技-上海嘉定-Java开发实习生-薪资150-230/d 面经
关于上海寻序人工智能科技有限公司Java开发实习生岗位的面试经验分享,涵盖了技术问题如对象存储MinIO、ArrayList扩容、Object类方法、hashCode和equals方法、处理哈希冲突、JVM垃圾回收器、GC算法、网络协议、邮件协议、HTTP请求方法、Linux和Docker命令、Dockerfile制作等。
3 0
|
26天前
|
Java 运维
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
开发与运维命令问题之使用jstack命令查看Java进程的线程栈如何解决
28 2
|
5天前
|
SQL 存储 Java
完整java开发中JDBC连接数据库代码和步骤
该博客文章详细介绍了使用JDBC连接数据库的完整步骤,包括加载JDBC驱动、提供连接URL、创建数据库连接、执行SQL语句、处理结果以及关闭JDBC对象的过程,并提供了相应的示例代码。