JavaWeb Session 会话管理实例详解

 更新时间:2016年09月18日 13:49:50   作者:随新小雅  
这篇文章主要介绍了JavaWeb Session 会话管理的相关资料,非常不错,具有参考借鉴价值,感兴趣的朋友一起看看吧

Session会话简介

会话是指在一段时间内,用户使用同一个浏览器进程与Web应用之间的交互过程。

会话(Session)通常用来跟踪用户的状态,缓存用户在此浏览器进程中的信息。

当用户关闭浏览器,上一个Session也就无法再次获得了(Cookie的maxAge为-1的情况)。再次打开新的浏览器,将开始一个新的会话。

类javax.servlet.http.HttpSession。每一个HttpSession代表用户的一个会话。
每一个Session的过期时间默认为30分钟。

当浏览器第一次访问服务器时,无论先访问哪一个页面,服务器就会给用户分配一个唯一的会话标识,即jsessionid然后以cookie的形式返回给用户。
下图是一个响应头(下图是基于Servlet3.0的,在Servlet2.5中没有HttpOnly属性)

服务器给每个用户创建一个会话,即HttpSession对象,保存在服务器端。

那么,当用户再次访问服务器时,服务器是如何知道还是当前用户呢?

当浏览器再次访问服务器时,会携带包含了jsessionid的cookie访问服务器。服务器根据此id返回此用户的HttpSession对象,就保持了会话。
( 那么,是否可以在不同的浏览器上实现同一个同一个会话呢?

下面是一个典型的URL,它带有一定的欺骗作用,可以在不同的浏览器上实现同一个会话:

http://localhost:8080/day07_2/CNCookieServlet;jsessionid=F8692D61CD46D094DBB7A8FC7387649C )

浏览器和服务器的关系如下两图:


HttpSession:

在Servlet中,通过HttpServletRequest.getSession方法获取会话对像。

HttpSession接口的以下方法用于向会话范围内共享数据:

getAttribute(“name”)
setAttribute(“name”,object);
getAttributeNames()
removeAttrubute(“name”)

Invalidate(); - 此方法强力删除服务器缓存的session.

示例:

在一个Servlet的向httpSession中setAttribute设置某些值。

通过超连接,或其他方式转到其他servlet并通过getAttribute显示信息。

在任意Servlet中调用getAttribute显示信息。

关闭此浏览器,重新访问获取信息的servlet,你会发现已经没有信息了。

如下:

String name=request.getParameter("name"); 
request.setAttribute("name", "request---"+name); 
request.getSession().setAttribute("name", "session---"+name); 
getServletContext().setAttribute("name", "application---"+name); 

Session的唯一标识Id:

每一个Session都一个唯一标识,即ID。

当浏览器获取一个新的Session时,用户即可以通过session.geId();打印出ID的值 。

在不关闭浏览器的情况下,在多个页面上跳转,使用的是同一个Session。

如:

request.getSession().getId() 

何为安全退出:

用户退出时,应该当将自己的信息从Session中清除-即安全退出。

安全退出是为了将自己在服务器上留下的信息清除干净,以防被黑

Session.invalidate();

1、request.getSession().invalidate();

如此可将session池中的相对应的对象删除

2、Session.removeAttribute(…)

如:

request.getSession().removeAttribute("realCode");

用于删除session对象中的属性

通过重写URL来跟踪会话:

前面已经说过,Servlet容器先在客户端保存一个SessionID,以后,在浏览器发出HTTP请求时,都会包含这个SessionID.Servlet容器读取HTTP请求中的这个SessionID,根据这个SessionID从容器中取出HttpSession对像,以便于跟踪HTTP请求属于哪一个会话,这一过程称为会话的跟踪。

如果浏览器支持Cookie,Servlet容器就将SessionID作为Cookie保存在浏览器的客户端。但如果出于安全的考虑,用户禁用了Cookie,那么Servlet容器又如何来跟踪会话呢?

首先让我们在IE中禁用Cookie(注意:对于某些GHOST的系统不起作用)。

IE>工具>Internet选项>隐私>高级,然后禁用Cookie:

我们可以在主页加上这样的超链接:(与下面代码中相关的SaveServlet.java GetServlet.java LogoutServlet.java的代码我放在最后面贴)

<h2>演示重写url技术---破解用户禁用cookie之后,我们session无效的问题</h2> 
<form action="<%=response.encodeURL("saveServlet") %>" method="post"> 
name:<input type="text" name="name"/><br/> 
<input type="submit"/> 
</form> 
<a href="<%=response.encodeURL("getServlet") %>">重写url-读取几个容器中的数据</a><br/> 
<a href="<%=response.encodeURL("logoutServlet") %>">重写url-安全退出</a> 

这句<form action=“<%=response.encodeURL(“/aa”)%>”>就可以实现这一功能

在这里禁用了cookie以后,浏览器仍然能够接收到服务器发送过来的cookie,但是浏览器只能接受不能发送出去给服务器,不能发送cookie的话也就不能够去session池中去取相应的对象了。

上面的代码在表单里面输入想要的值之后,再到下面的getServlet这里的超链接处访问看是不是仍然能够显示出输入的值,答案是肯定的。这里的访问路径就相当于类似

http://localhost:8080/day07_2/CNCookieServlet;jsessionid=F8692D61CD46D094DBB7A8FC7387649C 的,后面带的jsessionid=F8692D61CD46D094DBB7A8FC7387649C就是其id,如此,你到另一个浏览器中去输入这个网址也能够访问的到。
这里我要补充一下:(以下情况是在我将session池中HttpSession对象将对应session的JSESSIONID值和value值写入cookie中,这个cookie会覆盖系统造的那个,就相当于是我自己造的,我将存在时间设置成了十分钟,如果不覆盖的话,cookie在浏览器关闭时就会消亡,下面的现象也就不会出现了)

在是否禁用了cookie这两种情况下在session池中新建的对象的id是不一样的,即假如你在禁用了cookie时在表单中输入了一个name的值,查询结果如下:

并且jsessionid为2BB51EBDEAAF14D19656C71E1B6F9FF6

然后马上换成不禁用cookie模式,输入另一个名字如Tom,查询结果自然会是两个Tom,jsessionid为

203F9E4DB5D874476B81DAF350661B6A,与禁用是不一样,这就使出现下面的结果了

然后此时我们将浏览器关闭,再次进入浏览器,在不禁用cookie模式下查看访问结果,如下:

下面我将主要的代码贴上来:

SaveServlet.java

package cn.hncu.servlets.session; 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.ServletException; 
import javax.servlet.http.Cookie; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
public class SaveServlet extends HttpServlet { 
public void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
doPost(request, response); 
} 
public void doPost(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
response.setContentType("text/html;charset=utf-8"); 
PrintWriter out = response.getWriter(); 
request.setCharacterEncoding("utf-8"); 
String name=request.getParameter("name"); 
request.setAttribute("name", "request---"+name); 
request.getSession().setAttribute("name", "session---"+name); 
getServletContext().setAttribute("name", "application---"+name); 
//把cookie技术和session技术联合起来做应用的一个例子---※功能:让用户在关闭浏览器之后,如果10分钟之内能够登录本站,还能访问到session中的信息 
//向客户端写一个key为"JSESSIONID"用value为sessionid的cookie, 
Cookie c=new Cookie("JSESSIONID", request.getSession().getId()); 
c.setMaxAge(60*10);//上面的现象就是这一句造成的,没有这一句的话就不会有上面说的现象了 
c.setPath(request.getContextPath()); 
response.addCookie(c); 
out.println("保存成功..."); 
out.flush(); 
out.close(); 
} 
}

GetServlet.java

package cn.hncu.servlets.session; 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
public class GetServlet extends HttpServlet { 
public void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
response.setContentType("text/html;charset=utf-8"); 
PrintWriter out = response.getWriter(); 
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">"); 
out.println("<HTML>"); 
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>"); 
out.println(" <BODY>"); 
String reqName=(String) request.getAttribute("name"); 
String seName=(String) request.getSession().getAttribute("name"); 
String appName=(String) getServletContext().getAttribute("name"); 
out.println(reqName+"<br/>"); 
out.println(seName+"<br/>"); 
out.println(appName+"<br/>"); 
out.println(" </BODY>"); 
out.println("</HTML>"); 
out.flush(); 
out.close(); 
} 
}

LogoutServlet.java

package cn.hncu.servlets.session; 
import java.io.IOException; 
import java.io.PrintWriter; 
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
public class LogoutServlet extends HttpServlet { 
public void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException { 
response.setContentType("text/html;charset=utf-8"); 
PrintWriter out = response.getWriter(); 
//安全退出---只要让session对象无效就可以了 
request.getSession().invalidate(); 
out.println("已安全退出..."); 
} 
} 

以上所述是小编给大家介绍的JavaWeb Session 会话管理,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

相关文章

  • 使用java反射将结果集封装成为对象和对象集合操作

    使用java反射将结果集封装成为对象和对象集合操作

    这篇文章主要介绍了使用java反射将结果集封装成为对象和对象集合操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • java.lang.UnsupportedOperationException分析及解决办法

    java.lang.UnsupportedOperationException分析及解决办法

    日常开发中我遇到java.lang.UnsupportedOperationException:异常两次了,下面这篇文章主要给对大家介绍了关于java.lang.UnsupportedOperationException分析及解决办法,需要的朋友可以参考下
    2024-03-03
  • 详解SpringBoot配置连接池

    详解SpringBoot配置连接池

    本篇文章主要详解SpringBoot配置连接池,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • mybatis学习笔记之mybatis注解配置详解

    mybatis学习笔记之mybatis注解配置详解

    本篇文章主要介绍了mybatis学习笔记之mybatis注解配置详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • 【java 多线程】守护线程与非守护线程的详解

    【java 多线程】守护线程与非守护线程的详解

    这篇文章主要介绍了java守护线程与非守护线程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • Java中和队列相关的基本操作

    Java中和队列相关的基本操作

    在Java中,队列是一种常用的数据结构,用于存储和管理元素。Java提供了Queue接口和其实现类,包括LinkedList和ArrayDeque等。队列的基本操作包括入队(enqueue)、出队(dequeue)、获取队首元素(peek)和判断队列是否为空(isEmpty)。
    2023-09-09
  • Java 实现二叉搜索树的查找、插入、删除、遍历

    Java 实现二叉搜索树的查找、插入、删除、遍历

    本文主要介绍了Java实现二叉搜索树的查找、插入、删除、遍历等内容。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • JAVA通过HttpClient发送HTTP请求的方法示例

    JAVA通过HttpClient发送HTTP请求的方法示例

    本篇文章主要介绍了JAVA通过HttpClient发送HTTP请求的方法示例,详细的介绍了HttpClient使用,具有一定的参考价值,有兴趣的可以了解一下
    2017-09-09
  • 浅谈Java中的Queue家族

    浅谈Java中的Queue家族

    Java中Collection集合有三大家族List,Set和Queue。当然Map也算是一种集合类,但Map并不继承Collection接口。List,Set在我们的工作中会经常使用,通常用来存储结果数据,而Queue由于它的特殊性,通常用在生产者消费者模式中。今天这篇文章将带大家进入Queue家族。
    2021-06-06
  • SpringBoot中对SpringMVC的自动配置详解

    SpringBoot中对SpringMVC的自动配置详解

    这篇文章主要介绍了SpringBoot中的SpringMVC自动配置详解,Spring MVC自动配置是Spring Boot提供的一种特性,它可以自动配置Spring MVC的相关组件,简化了开发人员的配置工作,需要的朋友可以参考下
    2023-10-10

最新评论