Session跟踪(重要)

声明

本文部分内容参考自其他作者原创文章,仅供个人学习留档,特此声明

参考文章链接

(3条消息) 【狂神】JavaWeb笔记_码畜也有梦想的博客-CSDN博客_狂神javaweb笔记

Servlet Session 跟踪 | 菜鸟教程 (runoob.com)

Session 跟踪★★★

Servlet Session 跟踪 | 菜鸟教程 (runoob.com)

1、什么是 Session ?


什么是Session:浏览器访问服务器,服务器就会创建一个 session

web 服务程序只要打开,session 就会存在,n 个用户(浏览器)访问服务器,服务器会创建 n 个 session,通过 sessionId 进行区分,保证每个用户的数据是单独的

  • 服务器会给每一个用户(浏览器)创建一个Seesion对象;
  • 一个 Session 独占一个浏览器,只要浏览器没有关闭,这个 Session 就存在;
  • 用户登录之后,整个网站它都可以访问!–-> 保存用户的信息;保存购物车的信息……

Session 和 cookie 的区别:

  • Cookie 是把用户的数据写给用户的浏览器,浏览器保存 (可以保存多个)
  • Session 把用户的数据写到 用户(浏览器) 独占的 Session 中,服务器端保存 (保存重要的信息,减少服务器资源的浪费)
  • Session 对象由服务器创建;

使用场景:

  • 保存一个登录用户的信息;
  • 购物车信息;
  • 在整个网站中经常会使用的数据,我们将它保存在Session中;

HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话,以下仅供了解

1.Cookies

一个 Web 服务器可以分配一个唯一的 session 会话 ID 作为每个 Web 客户端的 cookie,对于客户端的后续请求可以使用接收到的 cookie 来识别。

这可能不是一个有效的方法,因为很多浏览器不支持 cookie,所以我们建议不要使用这种方式来维持 session 会话。

2.隐藏的表单字段

一个 Web 服务器可以发送一个隐藏的 HTML 表单字段,以及一个唯一的 session 会话 ID,如下所示:

<input type="hidden" name="sessionid" value="12345">

该条目意味着,当表单被提交时,指定的名称和值会被自动包含在 GET 或 POST 数据中。每次当 Web 浏览器发送回请求时,session_id 值可以用于保持不同的 Web 浏览器的跟踪。

这可能是一种保持 session 会话跟踪的有效方式,但是点击常规的超文本链接不会导致表单提交,因此隐藏的表单字段也不支持常规的 session 会话跟踪。

3.URL 重写

您可以在每个 URL 末尾追加一些额外的数据来标识 session 会话,服务器会把该 session 会话标识符与已存储的有关 session 会话的数据相关联。

例如

<input type="hidden" name="sessionid" value="12345">

session 会话标识符被附加为 sessionid=12345,标识符可被 Web 服务器访问以识别客户端。

URL 重写是一种更好的维持 session 会话的方式,它在浏览器不支持 cookie 时能够很好地工作,但是它的缺点是会动态生成每个 URL 来为页面分配一个 session 会话 ID,即使是在很简单的静态 HTML 页面中也会如此。


我们要学习的是下面这种维持 Session 对话的方法

4.HttpSession 对象

Servlet 提供了 HttpSession 接口,该接口提供了一种跨多个页面请求或访问网站时识别用户以及存储有关用户信息的方式。

Servlet 容器使用这个接口来创建一个 HTTP 客户端和 HTTP 服务器之间的 session 会话。会话持续一个指定的时间段,跨多个连接或页面请求。

通过调用 HttpServletRequest 的公共方法 getSession() 来获取 HttpSession 对象,如下所示:

HttpSession session = request.getSession();

需要在向客户端发送任何文档内容之前调用 request.getSession()


2、HttpSession 对象方法

序号 方法 & 描述
1 public Object getAttribute(String name) 该方法返回在该 session 会话中具有指定名称的对象,如果没有指定名称的对象,则返回 null。
2 public Enumeration getAttributeNames() 该方法返回 String 对象的枚举,String 对象包含所有绑定到该 session 会话的对象的名称。
3 public long getCreationTime() 该方法返回该 session 会话被创建的时间,自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
4 public String getId() 该方法返回一个包含分配给该 session 会话的唯一标识符的字符串。
5 public long getLastAccessedTime() 该方法返回客户端最后一次发送与该 session 会话相关的请求的时间自格林尼治标准时间 1970 年 1 月 1 日午夜算起,以毫秒为单位。
6 public int getMaxInactiveInterval() 该方法返回 Servlet 容器在客户端访问时保持 session 会话打开的最大时间间隔,以秒为单位。
7 public void invalidate() 该方法指示该 session 会话无效,并解除绑定到它上面的任何对象。
8 public boolean isNew() 如果客户端还不知道该 session 会话,或者如果客户选择不参入该 session 会话,则该方法返回 true。
9 public void removeAttribute(String name) 该方法将从该 session 会话移除指定名称的对象。
10 public void setAttribute(String name, Object value) 该方法使用指定的名称绑定一个对象到该 session 会话。
11 public void setMaxInactiveInterval(int interval) 该方法在 Servlet 容器指示该 session 会话无效之前,指定客户端请求之间的时间,以秒为单位。

3、Session 跟踪实例

3.1 代码

1.新建Person类

package com.xy.servlet;

public class Person {
    private String name;
    private int age;

    public Person(String name, int age){
        this.name=name;
        this.age=age;
    }

    public String getName(){
        return name;
    }

    public void setName(String name){
        this.name=name;
    }

    public int getAge(){
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.用于测试Session的SessionDemo01代码

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;
import java.text.SimpleDateFormat;
import java.util.Date;

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        //解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");

        //得到Session,重点:如果当前没有session,则会立刻建立一个session;如果有session则返回当前session
        HttpSession session = req.getSession();
        //给Session中存东西
        session.setAttribute("name",new Person("xy",18));
        //获取Session的ID
        String sessionId = session.getId();
        //获取 session 创建时间
        Date createTime = new Date(session.getCreationTime());
        //获取该网页的最后一次访问时间
        Date lastAccessTime = new Date(session.getLastAccessedTime());
        //设置日期输出的格式
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 设置响应内容类型
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter out = resp.getWriter();


        //判断Session是不是新创建的
        if (session.isNew()){
            out.println(
                    "<html>\n" +
                    "<body bgcolor=\"#f0f0f0\">\n" +
                    "<h2 align=\"center\">Session 信息</h2>\n" +
                    "<table border=\"1\" align=\"center\">\n" +
                    "<tr bgcolor=\"#949494\">\n" +
                    "  <th>Session 信息</th><th>值</th></tr>\n" +
                    "<tr>\n" +
                    "  <td>id</td>\n" +
                    "  <td>" + session.getId() + "</td></tr>\n" +
                    "<tr>\n" +
                    "  <td>创建时间</td>\n" +
                    "  <td>" +  df.format(createTime) +
                    "  </td></tr>\n" +
                    "<tr>\n" +
                    "  <td>最后访问时间</td>\n" +
                    "  <td>" + df.format(lastAccessTime) +
                    "  </td></tr>\n" +
                    "<tr>\n" +
                    "</body></html>");
        } else {
            out.println(
                    "<html>\n" +
                            "<body bgcolor=\"#f0f0f0\">\n" +
                            "<h2 align=\"center\">Session 信息</h2>\n" +
                            "<table border=\"1\" align=\"center\">\n" +
                            "<tr bgcolor=\"#949494\">\n" +
                            "  <th>Session 信息</th><th>值</th></tr>\n" +
                            "<tr>\n" +
                            "  <td>已存在sessionid</td>\n" +
                            "  <td>" + session.getId() + "</td></tr>\n" +
                            "<tr>\n" +
                            "  <td>已存在session创建时间</td>\n" +
                            "  <td>" +  df.format(createTime) +
                            "  </td></tr>\n" +
                            "<tr>\n" +
                            "  <td>最后访问时间</td>\n" +
                            "  <td>" + df.format(lastAccessTime) +
                            "  </td></tr>\n" +
                            "<tr>\n" +
                            "</body></html>");
        }

        //Session创建的时候做了什么事情;
//        Cookie cookie = new Cookie("JSESSIONID",sessionId);
//        resp.addCookie(cookie);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

3.用于注册映射路径的web.xml代码

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">

    <servlet>
        <servlet-name>cookie01</servlet-name>
        <servlet-class>com.xy.servlet.CookieDemo01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>cookie01</servlet-name>
        <url-pattern>/cookie01</url-pattern>
    </servlet-mapping>

    <!--设置Session默认的失效时间-->
    <session-config>
        <!--15分钟后Session自动失效,以分钟为单位-->
        <session-timeout>15</session-timeout>
    </session-config>

    <servlet>
        <servlet-name>session01</servlet-name>
        <servlet-class>com.xy.servlet.SessionDemo01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>session01</servlet-name>
        <url-pattern>/session01</url-pattern>
    </servlet-mapping>

</web-app>

3.2 代码测试

  • 首次创建Session

  • 刷新网页


4、删除Session会话数据

完成了一个用户的 session 会话数据以后我们有以下几种选择:

  • 移除一个特定的属性:可以调用 public void removeAttribute(String name) 方法来删除与特定的键相关联的值。
  • 删除整个 session 会话:可以调用 public void invalidate() 方法来丢弃整个 session 会话。
  • 设置 session 会话过期时间可以调用 public void setMaxInactiveInterval(int interval) 方法来单独设置 session 会话超时。
  • 注销用户:如果使用的是支持 servlet 2.4 的服务器,可以调用 logout 来注销 Web 服务器的客户端,并把属于所有用户的所有 session 会话设置为无效。
  • web.xml 配置:如果我们使用的是 Tomcat,除了上述方法,还可以在 web.xml 文件中配置 session 会话超时,如下所示:
<session-config>
	<session-timeout>15</session-timeout>
</session-config>

上面实例中的超时时间是以分钟为单位,将覆盖 Tomcat 中默认的 30 分钟超时时间。

在一个 Servlet 中的 getMaxInactiveInterval() 方法会返回 session 会话的超时时间,以为单位。所以,如果在 web.xml 中配置 session 会话超时时间为 15 分钟,那么 getMaxInactiveInterval() 会返回 900。

posted @   无关风月7707  阅读(78)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示