博主信息:
📢@博主: 嘟嘟的程序员铲屎官
💬:一位爱喵咪,爱开源,爱总结,爱分享技术的Java领域新星博主,如果你想和博主做朋友,关注博主,并私聊博主(给我发一条消息我就会关注你喔),博主本人也十分喜欢解决问题,如果你有什么问题,也可以来私聊博主喔,希望能够和C站的朋友相互学习,相互进步。
💬:关于本篇博客,最近在学习JavaWeb部分的知识,对<<Servlet和JSP学习指南>>本书第二章Session管理进行个人总结,如果有什么错误的,请各位大佬能够及时提出,以免小弟误人子弟!
资料下载:
<<Servlet和JSP学习指南>> 提取码:1o7u
相关学习链接:
廖雪峰-使用Session和Cookie
菜鸟编程-Servlet Cookie 处理
菜鸟编程-Servlet Session 跟踪
@TOC
一.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对象时要特别小心,因为每个对象都会消耗服务器的内存。