HttpSession对象
Session是什么
session和cookie就是为解决HTTP协议的无状态采用的两种解决方案,称为会话跟踪技术。与cookie将信息保存在客户端不同,session将信息保存在服务器端解决。
PS : 一次请求,指的是客户端发送数据到服务器端,服务器端接收并相应,这可以称之为一次请求。由于HTTP协议是无状态的,你无法从一个请求中拿到另一个请求中的数据,多个请求之间的数据无法共享,那么就引入会话的概念。会话怎么理解呢?就好比你和我坐下来聊天谈话,你问我答,你问我答,你再问我前面的问题我还是可以回答你,整个会话聊天中的内容我们可以随时交谈使用。那我们这里说的会话(Session)指的是什么:
对于服务器而言,每一个连接到它的客户端,都产生一个会话 (Session),服务端为他们之间的会话创建一个session对象。servlet 容器使用 javax.servlet.http.HttpSession接口创建 HTTP 客户端和 HTTP 服务器之间的会话(构建HttpSession对象- Session在服务器端对应的实现是:HttpSession对象是 javax.servlet.http.HttpSession 的实例。)。Session是在服务器端生成的,存储在服务器端,即存在内存中。
Session生成的同时,会生成一个与之相关联的的SessionID, 此SessionID的存储是需要Cookie来完成的。SessionID是以名称为JSESSIONID、其值应该是一个既不会重复,又不容易被找到规律以仿造的字符串组成。SessionID会随着此次Http 响应,一并返回到客户端,并保存在客户端中。到当前请求再次发出后,该SessionID会随着Http头部,传到服务器中,服务器依据当前SessionID 得到与之对应的session。
一次会话(一个用户的多次请求)期间共享数据。我们可以通过 request.getSession()方法,来获取当前会话的 session 对象。
// 如果session对象存在,则获取;如果session对象不存在,则创建
HttpSession session = request.getSession();
案例:
在Servlet中获取Session内容:
package com.msb.testsession;
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;
/**
* @Author: zhaoss
*/
@WebServlet("/testsession01")
public class TestSession01 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取Session对象:
HttpSession session = req.getSession();
// 获取Session的唯一标识符:
String id = session.getId();
System.out.println(id);
// 断判是否是新的session对象:
System.out.println(session.isNew());
}
}
你也可以请求其它页面,只要在同一个会话中,JSESSIONID都有效。(客户端请求服务器,会话即开启)
结论:
第一次访问发送请求到后端,第一次没有创建会话(Session)之前,那么由服务器创建一个HttpSession,并且将HttpSession对应的Sessionid绑定到http协议中响应回客户端。
第二次再访问,请求的时候在http请求协议中会在Cookie中携带Sessionid ,那么后台就会根据这个id取出对应的HttpSession。
测试,关闭服务器再重新测试,观察Sessionid的变化。
测试,关闭浏览器再重新测试,观察Sessionid的变化。
发现:一次会话(浏览器打开到关闭,访问多页页面,都在一个会话中)结束,结束后再次访问时,那么会创建新的Session。
标识符 JSESSIONID
Session 既然是为了标识一次会话,那么此次会话就应该有一个唯一的标志,这个标志就是 sessionId。
每当一次请求到达服务器,开启了会话,服务器第一步会查看是否从客户端回传一个名为 JSESSIONID 的 cookie,如果没有则认为这是一次新的会话,会创建 一个新的 session 对象,并用唯一的 sessionId 为此次会话做一个标志。如果有 JESSIONID 这 个cookie回传,服务器则会根据 JSESSIONID 这个值去查看是否含有id为JSESSION值的session 对象,认为是之前标志过的一次会话,返回该 session 对象,数据达到共享。
服务器在创建好Session对象后,服务器会将Session对象的id以Cookie的形式保存在客户端(浏览器),用户在发请求的时候,就会带上该Cookie,也就是SessionId到服务器,服务器会根据该id找到用户的Session对象。存储SessionId的Cookie不需要我们自己创建,我们在调用服务器完成Session创建的时候,Tomcat服务器会自动的创建Cookie,Cookie里面保存的是SessionId并响应给浏览器。但是注意,Cookie默认的有效期为浏览器运行期间,浏览器关闭,Cookie即失效。
不管是存储了用户SessionId的Cookie信息丢失,还是服务器存储的Session对象被销毁,(无论你是关闭浏览器还是关闭服务器,相当于会话断开了)默认只要服务器接收到用户发起的请求后,如果找不到对应的Session对象,都会重新创建,并将新的SessionId以Cookie的形式保存到浏览器中 。
session的使用
Session 用来表示一次会话,在一次会话中数据是可以共享的,这时 session 作为域对象存在(会话是一个域,在其中共享数据),可以通过setAttribute(name,value) 方法向域对象中添加数据,通过 getAttribute(name) 从域对象中获取数据,通过 removeAttribute(name) 从域对象中移除数据。
数据存储在 session 域对象中,当 session 对象不存在了,数据也就不能共享了。这就不得不谈到 session 的生命周期。
案例:
请求Servlet,将数据存于Session中(存两个,删一个),然后请求转发到另一个Servlet,从另一个Servlet中取出Session:
package com.msb.testsession;
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("/ts02")
public class TestSession02 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取Session对象:
HttpSession session = req.getSession();
// 在session域对象中存入内容:
session.setAttribute("uname1","lili");
session.setAttribute("uname2","feifei");
// 移除指定名称的session域对象:
session.removeAttribute("uname2");
// 请求转发到另一个Servlet:
req.getRequestDispatcher("/ts03").forward(req, resp);
}
}
package com.msb.testsession;
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("/ts03")
public class TestSession03 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取Session对象:
HttpSession session = req.getSession();
// 获取指定名称的session域对象:
String uname = (String)session.getAttribute("uname1");
System.out.println(uname);
String uname2 = (String)session.getAttribute("uname2");
System.out.println(uname2);
}
}
控制台结果:
lili
null
session对象的销毁
默认时间到期
可以对生成的 Session 设置过期时间,如果不设置过期时间,默认的Session过期时间是30分钟(在不同的服务器中,它的过期时间略有不同,以Tomcat为案例来说)。
那么 session 的默认时间可以改么?答案是肯定的。可以在 Tomcat 中的 conf 目录下的 web.xml 文件中进行修改。
<!-- session 默认的最大不活动时间。单位:分钟。 -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
当客户端第一次请求 servlet 并且操作 session 时,session 对象生成,Tomcat 中 session 默认的存活时间为 30min**(指的是这30min完全不操作),即你不操作界面的时间,一旦有操作,session 会重新计时。**
当然我们也可以通过 getMaxInactiveInterval() 方法来查看当前 Session 对象的最大不活动时间。
// 获取session的最大不活动时间
int time = session.getMaxInactiveInterval();
实际案例:在登录某个网站的时候,比如长时间不用以后,登录信息就过期了,你再操作就让你重新登录了,那就是因为登录数据都存在session中了,超过有效时间,session就消失了,那么就需要重新登录。
自己设定到期时间
当然除了以上的修改方式外,我们也可以在程序中自己设定 session 的生命周期,通过session.setMaxInactiveInterval(int) 来设定 session 的最大不活动时间,单位为秒。
// 获取session对象
HttpSession session = request.getSession();
// 设置session的最大不活动时间
session.setMaxInactiveInterval(15); // 15秒
立刻失效
或者我们也可以通过 session.invalidate() 方法让 session 立刻失效
// 销毁session对象
session.invalidate();
代码:
package com.msb.testsession;
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("/ts04")
public class TestSession04 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 获取session对象:
HttpSession session = req.getSession();
// 立即失效:
session.invalidate();
// 设置session的最大不活动时间:
//session.setMaxInactiveInterval(30);
// 获取session的最大不活动时间:
/*int time = session.getMaxInactiveInterval();
System.out.println(time);*/
}
}
关闭浏览器
从前面的 JESSIONID 可知道,session 依赖 cookie 实现,并且该 cookie 的有效时间为关闭浏览器,从而 session 在浏览器关闭时也相当于失效了(因为没有 JSESSION 再与之对应)。
关闭服务器
当关闭服务器时,session 销毁。
Session 失效则意味着此次会话结束,数据共享结束。
评论区