目录
一.HttpSession对象的特点
二.HttpSession对象的创建
三.HttpSession对象的使用
四.HttpSession的销毁方式
五.通过HttpSession实现客户端与服务端会话的维持
六.HttpSession生命周期
七.HttpSession对象总结
1.HttpSession与Cookie的区别
2.HttpSession的使用建议
一.HttpSession对象的特点
- HttpSession保存在服务端
- HttpSession使用Key与Value结构存储数据
- HttpSession的Key是字符串类型,Value则是Object类型
- HttpSession存储数据大小无限制,Cookie存储数据大小有限制
二.HttpSession对象的创建
HttpSession
对象的创建是通过
request.getSession()
方法来创建的。客户端浏览器在请求服务端资源时,如果在请求中没有
jsessionid
,
getSession()
方法将会为这个客户端浏览器创建一个新
的
HttpSession
对象,并为这个
HttpSession
对象生成一个
jsessionid
,在响应中通过
状态Cookie
写回给客户端浏览器,如果
在请求中包含了
jsessionid
,
getSession()
方法则根据这个
ID
返回与
这个客户端浏览器对应的
HttpSession
对象。
getSession()
方法还有一个重载方法
getSession(true|false)
。当参数为
true
时与
getSession()
方法作用相同。当参数为
false
时则只去
根据
jsessionid
(无需指定)查找是否有与这个客户端浏览器对应的
HttpSession
,如果有则返回,如果没有
jsessionid
则不会创建新的
HttpSession
对象。
每个浏览器都有自己的session对象。
CreateHttpSessionServlet.java:
package com.first.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
public class CreateHttpSessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建HttpSession对象
//true可不传,若传false,则没有session对象则不创建对象,即session是null,若有则返回
HttpSession session= req.getSession(true);
System.out.println(session);
PrintWriter pw=resp.getWriter();
pw.println("Create HttpSession ok!");
pw.flush();
pw.close();
}
}
web.xml配置:
CreateHttpSessionServlet com.first.servlet.CreateHttpSessionServlet CreateHttpSessionServlet /session.do
输出:
换个浏览器试试,发现 jsessionid不一样了,我这里就不演示了。
控股台输出:
org.apache.catalina.session.StandardSessionFacade@6d46c82c
三.HttpSession对象的使用
session.setAttribute("key",value)
将数据存储到
HttpSession
对象中
Object value = session.getAttribute("key")
根据
key
获取
HttpSession
中的数据,返回
Object
Enumeration attributeNames = session.getAttributeNames()
获取
HttpSession
中所有的
key
,返回枚举类型
session.removeAttribute("key")
根据
key
删除
HttpSession
中的数据
String id = session.getId()
根据获取当前
HttpSession
的
SessionID
,返回字符串类型
在CreateHttpSessionServlet.java中增添如下代码:
//存放数据
session.setAttribute("key1","下一次");
//获取sessionID
String sessionID=session.getId();
System.out.println("sessionID: "+sessionID);
GetHttpSessionDataServlet.java:
package com.first.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
public class GetHttpSessionDataServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取HttpSession对象
HttpSession session=req.getSession();
//获取数据
String value= (String) session.getAttribute("key1");
PrintWriter pw=resp.getWriter();
pw.println(value);
pw.flush();
pw.close();
}
}
配置web.xml:
GetHttpSessionDataServlet com.first.servlet.GetHttpSessionDataServlet GetHttpSessionDataServlet /getSession.do
输出:
控制台输出:
session: org.apache.catalina.session.StandardSessionFacade@5fffb2bc sessionID: 8E5DA726F902D8CA52F74045795C28A9
浏览器输出:
注意一个浏览器对应一个session,关闭浏览器再打开登陆localhost:8888/ajaxDemo/session.do,会发现jsessionid变了,因为一关闭浏览器状态Cookie会被销毁,所以又创建了新的session对象,原来的session对象不会立即销毁,而是放到了HttpSession对象列表里。
四.HttpSession的销毁方式
HttpSession
的销毁方式有两种:
- 通过web.xml文件指定超时时间
- 通过HttpSession对象中的invalidate()方法销毁当前HttpSession对象
我们可以在
web.xml
文件中指定
HttpSession
的超时时间,当到达指定的超时时间后,容器就会销该
HttpSession
对象,单位为分钟。
该时间对整个
web
项目中的所有
HttpSession
对象有效。时间的计算
方式是根据最后一次请求时间作为起始时间。只要用户继续访问,
服务器就会更新
HttpSessio
的最后访问时间,并维护该
HttpSession
。用户每访问服务器一次,无论是否读写
HttpSession
,服务器都认为该用户的
HttpSession"
活跃
(
active
)
"
了一次
,
销毁时间则会重新计算。如果有哪个客户端浏览
器对应的
HttpSession
的失效时间已到,那么与该客户端浏览器对应
的
HttpSession
对象就会被销毁。其他客户端浏览器对应的
HttpSession
对象会继续保存不会被销毁。
示例思路,在第二节CreateHttpSessionServlet.java基础上修改,用两个浏览器访问这个servlet,一个浏览器的HttpSession到达指定的超时时间后销毁,但另一个时不时刷新一下(为的是重新计时),所以没有销毁,以此验证上面那段话。
如何区分浏览器,看请求头中的User-Agent。
配置web.xml:
这个没有位置要求
1
CreateHttpSessionServlet.java:
package com.first.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
public class CreateHttpSessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取请求头中的User-Agent的数据
String header=req.getHeader("User-Agent");
//创建HttpSession对象
//true可不传,若传false,则没有session对象则不创建对象,即session是null,若有则返回
HttpSession session= req.getSession(true);
System.out.println("session: "+session);
//看着是key是一样的,但其实两个浏览器的HttpSession是不一样的
if (header.indexOf("Chrome")!=-1){
session.setAttribute("browser","Chrome");
//销毁session对象
//session.invalidate();
}else {
session.setAttribute("browser","Firefox");
}
//存放数据
session.setAttribute("key1","下一次");
//获取sessionID
String sessionID=session.getId();
System.out.println("sessionID: "+sessionID);
PrintWriter pw=resp.getWriter();
pw.println("Create HttpSession ok!");
pw.flush();
pw.close();
}
}
GetHttpSessionDataServlet.java:
package com.first.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
public class GetHttpSessionDataServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取HttpSession对象
HttpSession session=req.getSession();
//获取数据
String value= (String) session.getAttribute("browser");
resp.setContentType("text/plain;charset=utf-8");
PrintWriter pw=resp.getWriter();
pw.println(value);
pw.flush();
pw.close();
}
}
输出:
没超时之前
超时之后
而火狐期间时不时刷新一下,重新计时,HttpSession对象就一直没被销毁。
我们也可以在 Tomcat 的 web.xml 文件(在Tomcat安装目录的conf文件中,而不是项目的web.xml,如果下面的配置代码写到项目的web.xml中,那么启动Tomcat时会报错)中配置 HttpSession 的销毁时间。如果在 Tomcat 的 web.xml 文件中配置了 HttpSession 的超时时 间对应的是 Tomcat 中所有的 Web 项目都有效。相当于配置了全局的 HttpSession 超时时间。如果我们在 Web 项目中配置了超时时间, 那么会以 Web 项目中的超时时间为准。 在这里配置的超时时间是全局的,即在Tomcat中部署的所有项目都受此超时时间设定(项目没有根据上面那个方式单独给自己部署的情况下) invalidate() 方法是 HttpSession 对象中所提供的用于销毁当前HttpSession 的方法。我们通过调用该方法可以销毁当前 HttpSession 对象。
session.invalidate();
五.通过HttpSession实现客户端与服务端会话的维持
需求:当客户端浏览器第一次访问
Servlet
时响应
“
您好,欢迎您第一次访问!
”
,第二次访问时响应
“
欢迎您回来!
”
。
package com.first.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
import java.io.PrintWriter;
public class WelcomeSessionServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取HttpSession对象
//false参数:没有session对象也不会创建新的
HttpSession session=req.getSession(false);
boolean flag=true;
//如果是第一次访问那么肯定不存在session对象
if (session==null){
flag=false;
//创建session对象
req.getSession();
}
resp.setContentType("text/plain;charset=utf-8");
PrintWriter pw=resp.getWriter();
if (flag){
pw.println("欢迎您回来!");
}else {
pw.println("您好,欢迎您第一次访问!");
}
}
}
配置web.xml:
WelcomeSessionServlet com.first.servlet.WelcomeSessionServlet WelcomeSessionServlet /welcomeSession.do
输出:
刷新:
刚开始Tomcat是默认自己打开Chrome浏览器的,默认执行index.js
index.js里面有创建session对象的代码,所以刚开始开发者工具里面会有一条jsessionid。



