session入门

Session 原理

 

HttpSession

session和cookie 其实是一个东西,保存在服务端就是session 保存在客户端就是cookie

1. HttpSession概述
  * HttpSession是由JavaWeb提供的,用来会话跟踪的类。session是服务器端对象,保存在服务器端!!!
  * HttpSession是Servlet三大域对象之一(request 一次请求就创建一个request 一个serlvet 可能会有多请求就创建多个request、session、application(ServletContext)),
   什么叫会话:就是一次对话,就是我们在大街上碰到了一个人,你们之间的交流就是一直到你们不说了,一直到交流中断了
   在浏览器中的会话: 从你打开浏览器开始Httpsession 一直存活,不管你中间打开了多少页面,访问了多少次请求,一直都是一个session 但是要保证一直用的都是同一个浏览器 ,一直到你关闭了浏览器,session 就死了,
   但是如果设置了session的时间,即使打开上一次关闭的浏览器,session 也死亡,session 只是针对一个浏览器,所以并发请求不会出现在同一个session 中,
    服务器会为每个客户端创建一个session对象,session就好比客户在服务器端的账户,它们被服务器保存到一个Map中,这个Map被称之为session缓存,
    所以session 是在同一个会话中的多个请求多个servlet 间数据共享。
    > Servlet中得到session对象:HttpSession session = request.getSession();
    > Jsp中得到session对象:session是jsp内置对象之下,不用创建就可以直接使用!
  * session域相关方法:
    > void setAttribute(String name, Object value);
    > Object getAttribute(String name);
    > void removeAttribute(String name);
  * HttpSession底层依赖Cookie,或是URL重写!

 

1 都是浏览器关闭了才消失,cookie 模式是关闭浏览器就消失了,但是session 默认是30分钟,30 分钟是默认最大不活动时间

2 都是以键值对的方式保存用户信息

 Cookie 和session 的关系:

当打开一个新的会话的,并且第一次请求的时候,产生一个session 并且把sessionId 保存在cookie 中,当浏览器再一次访问的时候cookie 会自动把cookie 返回并且携带者sessionId 就是相当于携带着银行账号,这个时候通过sessionId 就可以找到session,cookie 保存的sessionId 在cookie 中叫做 JSESSIONID(java sessionId),当浏览器关闭了以后,cookie 就没有了,所以sessionId 也就没有了,所以session 也就找不到了,虽然session找不到了,就像是银行需要办卡,但是仍然存活在服务器中,只有30分钟没有动网页,没有发送请求,session才有消失。

1 当打开一个新的会话的,并且第一次请求的是jsp 

1 浏览器在第一次访问的时候通过jsp访问,由于在jsp中就有现成的session 所以在http响应的那一端可以看到cookie中的含有的JSESSIONID

并且在第二次访问的时候,由于访问的地址包含cookie 的路径,cookie 中包含着jsessionId,所以再一次发送http 请求的时候,请求中含有cookie,cookie 中就含有JSESSIONID,并且通过请求发送过来,所以总结cookie不同过创建也是含有一个默认的装有sessionId 的cookie ,在jsp 中创建cookie 只是增加cookie 的数量。

2 当打开一个新的会话的,并且第一次请求的是Servlet

如果只是用Servlet 访问,如果没有request.getSession() 这句话的时候服务器是不会创建session 的

public class AServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().print("请查看是否有jsessionid这个cookie");
    }
}

在http的响应行是没有SessionId 的

如果有了request.getSession() 这句话的时候

public class AServlet extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=utf-8");
		request.getSession();
		response.getWriter().print("请查看是否有jsessionid这个cookie");
	}
}

 

 服务器不会在打开浏览器马上给你创建session,在第一次获取session时,才会创建!request.getSession();
 request.getSession(false)、request.getSession(true)、request.getSession(),后两个方法效果相同,
    > 第一个方法:如果session缓存中(如果cookie不存在),不存在session,那么返回null,而不会创建session对象。

 

3 Session 可以在多个servlet 中共享

  案例1:演示session中会话的多次请求中共享数据
  * AServlet:向session域中保存数据
  * BServlet:从session域中获取数据
  * 演示:
    > 第一个请求:访问AServlet

    > 第二个请求:访问BServlet

先从jsp 中获取session

代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'a.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
<h1>向session域保存数据</h1>
<%
	session.setAttribute("aaa", "AAA");
%>
  </body>
</html>

代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'b.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
<h1>获取session中的数据</h1>
<%
	String s = (String)session.getAttribute("aaa");
%>
<%=s %>
  </body>
</html>

ie 浏览器

只有ie 浏览器中有新建会话

如果换了浏览器也是不行的

 

是null的主要原因是

 关闭浏览器session就被干掉的假象的问题

当在前台取出session时,关闭浏览器后再次访问服务器,这时服务器返回了一个null,此时的返回的session并非之前的那个session而是一个新的session。

-->先来看看session的生命周期:

  创建:当getSession()后,session就被创建。

  结束:有三种结束生命的情况 >>

        1.服务器会默认一个30分钟的生命时间值,若在这个期间,为被访问服务器时就会自动结束生命;

          |--可以在服务器下的web.xml文件中的 <session-timeout> 30 </session-timeout> 修改这是默认值,是以分为单位。

        2.session自杀: 调用session.invalidate()方法可以立即杀死session;

        3.服务器意外关闭。(服务器正常关闭时session是会被服务器保存在服务器的 session.ser 文件中(在work文件夹下))

 

--> 当关闭浏览器时怎么就会有session干掉的假象呢?

  由于session是基于Cookie的。浏览器发起请求会携带sessionId到服务器,服务器根据这个id来判读当前访问的是哪个session。

  然而浏览器被关闭后由于浏览器的Cookie文件还未设置MaxAge值,所以在此时浏览器的Cookie是会话级别的,是存在浏览器的内存中,当浏览器被关闭浏览器的内存被释放,临时文件被清除,这时的Cookie也随之销毁,则当前这个请求中被没有之前的那个sessionId值,服务器就当时第一次访问,给浏览器创建一个新的session值并返回一个null;

  但是之前的那个session并没有被干掉,只是浏览器找不到这个sessionId了。这样一来,此时服务器器就存在了两个session了。

-->解决这个假象的方案

   我们可以创建一个新的CooKie,该Cookie的名字为jsession,path为WEB应用的虚拟路径,并设置setMaxAge()的毫秒值,让Cookie保存在客户端的硬盘中,这时即使多次对浏览器进行关开操作是不会清楚客户端硬盘文件的。所以,Cookie就不丢失了,SessionId也不会随浏览器关闭而丢失。

  具体代码实现:

 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'a.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

  </head>
  
  <body>
  <h1>向session中保存session数据</h1>
<%
session.setAttribute("xxx", new cn.itcast.User());
Cookie cookie = new Cookie("JSESSIONID", session.getId());
cookie.setMaxAge(30*60);
response.addCookie(cookie);
%>
  </body>
</html>

在客户端会保存两个sessionid ,但是是一个cookie,由于map 的键和值是一样的,保存这两个cookie,一个是之前客户端访问的时候的sessionid,但是这个session当浏览器关闭的时候,这个cookie 就没有了,第二个是我们存进去的cookie ,虽然两个cookie 一致但是这个cookie的生存时间长,即使浏览器关闭了,服务器仍然能根据这个sessionid 找到这个session,所以即使浏览器关闭了,再打开,也能获取到值。

但是如果这个时候重新启动服务器

仍然可以但是获取的对象发生了变化

还有一种情况,当服务器关闭的时候session是不会死的

点击这个

这个时候重新启动服务器

仍然还是可以获取到的

原因是因为session 要想能复活,就是保存在硬盘上

eclipse 和myeclipse 访问路径有点不同

如果是myeclipse 的话

当stop 的时候会生成一个

eclipse 中说明,当点击这个按钮的时候

 

没点击之前,这个文件夹下是这样的

 

E:\workspaceforeclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\day20_2\org\apache\jsp\a_jsp.class 通过这个路径去找

E:\workspaceforeclipse\.metadata\.plugins\org.eclipse.wst.server.core\tmp1\work\Catalina\localhost\day20_2\

点击stop 按钮之后

所有的session 都保存在这个地方,所以叫做sessions

如果这个时候启动服务器

启动服务器以后文件就不见了

如果出现在淘宝上的时候,服务器重新启动了以后,session还可以复活的话,就保证了大家的数据的安全,这就是session 序列化

如何把session的序列化废掉

在这个里面加一句话

 

 

 

 

 

 

 

 

 

但是如果

点击这个

右点击了这个

再重新启动服务器,就没有了,这个按钮相当于是直接切断电源,再重新启动,还是没有的

所以session 具有复活的能力

3. 案例2:演示保存用户登录信息(精通)
   session 的最大的作用就是保存用户的登录信息,如果登陆了,该用户就会一直保存着登录信息,要么就不显示登录信息

4. HttpSession其他方法:

  * String getId():获取sessionId;

    sessionId 的字符串是由uuid 生成的

public class CommonUtils {
	public static String uuid() {
		return UUID.randomUUID().toString().replace("-", "").toUpperCase();
	}
}

 

  * int getMaxInactiveInterval():获取session可以的最大不活动时间(秒),默认为30分钟。当session在30分钟内没有使用,那么Tomcat会在session池中移除这个session;
  * void invalidate():让session失效!调用这个方法会被session失效,当session失效后,客户端再次请求,服务器会给客户端创建一个新的session,并在响应中给客户端新session的sessionId;
  * boolean isNew():查看session是否为新。当客户端第一次请求时,服务器为客户端创建session,但这时服务器还没有响应客户端,也就是还没有把sessionId响应给客户端时,这时session的状态为新。

5 web.xml中配置session的最大不活动时间
    <session-config>
        <session-timeout>30</session-timeout>
    </session-config>

6. URL重写(理解)
 

 

      Session 底层以来cookie 或者是url 重写

   

 

    由于ie 浏览器中可以设置阻止所有cookie,服务器给我也不要,这个时候是浏览器的安全级别过高,所以就会导致服务器发送请求的时候不会把sessionId带回去,这个时候怎么办方,用另外一种方式维护sessionid的生命。

在找sessionId 的时候,如果cookie 中没有的话,还会去url重写过后面跟的参数中找,如果还是没有才会创建session


 

代码:

 

当首次访问这个页面的时候是没有名字为jsessionID 的cookie 的名字送给服务器,就是首次访问这个页面request cookies 当中是没有cookie,只有响应cookies 当中才有

 

二次访问的时候,有名字为jsessionID 的cookie 的名字送给服务器

<body>
<a href='<%=response.encodeURL("/day11_3/AServlet") %>'>点击这里</a>
<a href='<%=response.encodeURL("/day11_3/AServlet") %>'>点击这里</a>
<a href='<%=response.encodeURL("/day11_3/AServlet") %>'>点击这里</a>
<!-- 可以替代上面的方法 -->
<%
// 它会查看cookie是否存在,如果不存在,在指定的url后添加jsessionid参数
// 如果cookie存在,它就不会再url后添加任何东西!
out.println(response.encodeURL("/day11_3/AServlet"));
%>
</body>
</html>

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值