Session详解(重点)

什么是Session:

(1)服务器会给每一个用户(浏览器)创建一个Session对象

 比如我们现在都去访问百度,我们使用双核浏览器和谷歌浏览器同时访问百度这个网址,百度那边会有两个session,因为浏览器不一样,但是只要在一个浏览器里面一直用百度的话,就没有区别。我们用两个浏览器相当于是模拟两个客户端。

 (2)一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在。

(3)用户登录之后,整个网站它都可以访问。(保存用户的信息、保存购物车的信息)

比如我们登录csdn之后,csdn网站上的内容都可以进行点击,不用重复登录。可以访问该用户权限下的所有网页。

如果退出用户之后,其中的好多页面都需要我们进行登录之后才可以使用。

 Session和Cookie的区别:

首先我们进行创建一个session类:然后再按住ctrl键的同时点击HttpSession。我们进入Session的源码界面,点开Struct进行查看:

 进入源码界面如下所示:

 我们进行分析源码:
得到一个唯一的标识符:

 public String getId();

获得ServletContext:(web对象几乎都可以获得ServletContext,ServletContext代表整个web服务)

public ServletContext getServletContext();

得到一个节点:(获得这个名字)

public Object getAttribute(String name);

有get就有set:(设置值的方法)

 public void setAttribute(String name, Object value);

移除一个指定的属性:

public void removeAttribute(String name);

判断是否是新的:

 public boolean isNew();

注销:

  public void invalidate();

 setAttribute可以存很多东西 ,Object代表对象,可以存一个对象。

我们设计代码如下所示:

我们在设计代码的过程中,需要重写doGet和doPost方法,因为httpServlet中的doGet和doPost方法只有原生的req和resp,实现页面的数据交互的本质是重写方法,操作req和resp。

package com.rgf.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;

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
        HttpSession session = req.getSession();
        //给Session中存东西
        session.setAttribute("name","蕾峰编程");

        //获取session的ID
        String sessionId = session.getId();

        //判断Session是不是新创建的
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+sessionId);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
        }


    }

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

我们进行设计web.xml:

 <servlet>
        <servlet-name>SessionDemo01</servlet-name>
        <servlet-class>com.rgf.servlet.SessionDemo01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SessionDemo01</servlet-name>
        <url-pattern>/s1</url-pattern>
    </servlet-mapping>

运行之后界面如下所示:

 session之所以已经存在了,是因为tomcat启动的时候自动访问了该站点,所以就已经存在了

我们点开开开发者工具进行查看:

我们发现在请求的时候我们带了一个Cookie, 

session其实是浏览器访问此服务器任何一个页面的时候都自动创建的,所以我们在访问了其他页面后,在访问session页会发现已存在。

我们进行单独对象进行分包的时候,一个实体类,两个关键词。即为entity(又叫pojo)最原始的java类

我们进行分包如下所示:

 我们点击Compact Middle Packages,如下所示:

之后我们创建pojo包,在该包下进行创建实体类:

 之后我们再创建一个类,进行提取session里面的东西:由于我们已经再SessionDemo01里面已经在session里面添加了东西,现在我们利用sessionDemo02进行提取session里面的东西:

我们所设计的代码如下所示:

package com.rgf.servlet;

import sun.net.httpserver.HttpServerImpl;

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;

public class SessionDemo02 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
        HttpSession session = req.getSession();
        //从Session中取出东西,我们将其new一个对象,然后出现Object,我们进行强制转换,点击alt+enter。
        String name = (String) session.getAttribute("name");

        System.out.println(name);


    }

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

我们在web.xml里面进行注册:

 <servlet>
        <servlet-name>SessionDemo02</servlet-name>
        <servlet-class>com.rgf.servlet.SessionDemo02</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SessionDemo02</servlet-name>
        <url-pattern>/s2</url-pattern>
    </servlet-mapping>

我们进行运行之后,发现如下所示:

出现空白,这个时候我们在控制台进行查看的时候,发现输出为null。

我们先进行访问 http://localhost:9571/Cookie_war/s1 的时候,之后再进行访问http://localhost:9571/Cookie_war/s2的时候,这个时候我们发现控制台输出我们在s1里面的session存入的东西。

 我们进行创建了Person类,如下所示:

package com.rgf.pojo;

public class Person {
    private  String name;
    private int age;
    //有参无参构造:Constructor
    //有参构造:
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
//无参构造:Select None
    public Person() {
    }

    //ctrl+o为重写方法
//鼠标右键Generate,进行重写get和set方法。
    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;
    }
    //为了调试输出方面,还会加toString:
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}



我们在sessionDemo01该类里面存入session的代码修改如下所示:

 //        //给Session中存入东西
        session.setAttribute("name",new Person("蕾峰编程",22));

之后再SessionDemo02里面往出取session的代码如下所示:

   Person person = (Person) session.getAttribute("name");
       // public String toString()返回该对象的字符串表示。
        // 通常,ToString方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。
        System.out.println(person.toString());

session不仅可以存字符串,也可以存用户的信息。

我们进行运行之后,如下所示:

 我们发现对象也可以往里面存,也可以从里面取出来。

我们必须先进行再SessionDemo01里面进行存之后才能再SessionDemo02里面进行取。

我们进行注销session,我们所设计的代码如下所示:
 

package com.rgf.servlet;

import com.rgf.pojo.Person;

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;

public class SessionDemo03 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
        HttpSession session = req.getSession();
        //取消掉我们所存入的name。
        session.removeAttribute("name");
        //注销掉session
        session.invalidate();

    }

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

之后在web.xml里面进行注册:

 <servlet>
        <servlet-name>SessionDemo03</servlet-name>
        <servlet-class>com.rgf.servlet.SessionDemo03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>SessionDemo03</servlet-name>
        <url-pattern>/s3</url-pattern>
    </servlet-mapping>

之后运行之后如下所示:

 我们再重新登录s1,发现如下所示:

说明以前的session已经被注销了。 

我们知道session是一个浏览器对应一个session,我们利用其他浏览器进行对比如下:

 我们发现这两个浏览器里面所使用的session的ID不同。我们再进行回车,发现他们的ID还是那个样子,没有发生变化。

我们先利用s3,进行session的注销,之后我们访问s2,发现如下所示:

 出现空指针异常,这个空指针异常是person空指针异常,是因为session中的键name不存在导致的。注销之后访问s2正常会更新ID。

我们重新访问s1后,我们发现如下所示:

我们发现这个ID与此前的不一样,一旦注销之后,浏览器就会产生一个新的session。 

我们再双核浏览器进行同样的操作:

我们发现该ID也发生了变化。 这种方式是手动注销的方式。

当用户登录的时候,如果一两天还没有用的话,我们有自定失效时间。我们在web.xml里面进行设置如下所示:

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

如果我们所设置失效时间长的话会因为如果用户量特别大,服务器上全是session,会容易崩。

我们在更好的网站一般采用cookie,cookie会持久化的保存到客户端,浏览器也有清除cookie的作用,点击设置,进入清除浏览数据,如下所示:

 但是我们建议一般不删除cookie.

我们进行测试看是否在我们所设置的session会在一分钟后失效:

 我们进行刷新如下所示:

发现出现了一个新的session。

Session和Cookie的区别:
Cookie是把用户的数据写给用户的浏览器,浏览器保存。(可以保存多个)

Session把用户的数据写到用户独占Session中,服务器端保存。(保存重要的信息,减少服务器资源的浪费)

Session对象由服务器创建

session使用场景:

(1)保存一个登录用户的信息;(用户登录之后,只要不关掉浏览器,都在session里面,都可以去享受他的服务,无论跳到哪个网页,他的信息都会存在)

(2)购物车信息

(3)在整个网站中经常会使用的数据,我们将它保存在Session中。

使用session的代码如下所示:

将东西存入session:

package com.rgf.servlet;

import com.rgf.pojo.Person;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

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
                HttpSession session = req.getSession();
        //        //给Session中存入东西
        session.setAttribute("name",new Person("蕾峰编程",22));

        //获取session的ID
        String sessionId = session.getId();

        //判断Session是不是新创建的
        if(session.isNew()){
            resp.getWriter().write("session创建成功,ID:"+sessionId);
        }else {
            resp.getWriter().write("session已经在服务器中存在了,ID:"+sessionId);
        }
//Session创建的时候做了什么事情:
        //session在创建的时候带了一个cookie,而且服务器把该cookie响应给客户端了。
        //Cookie cookie = new Cookie("JSESSIONID",sessionId);
     //   resp.addCookie(cookie);


    }

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

从session里面取东西:
 

package com.rgf.servlet;

import com.rgf.pojo.Person;
import sun.net.httpserver.HttpServerImpl;

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;

public class SessionDemo02 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
        HttpSession session = req.getSession();
        //从Session中取出东西,我们将其new一个对象,然后出现Object,我们进行强制转换,点击alt+enter。
        Person person = (Person) session.getAttribute("name");
       // public String toString()返回该对象的字符串表示。
        // 通常,ToString方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。
        System.out.println(person.toString());


    }

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

所需要存入的东西:
 

package com.rgf.pojo;

public class Person {
    private  String name;
    private int age;
    //有参无参构造:Constructor
    //有参构造:
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
//无参构造:Select None
    public Person() {
    }

    //ctrl+o为重写方法
//鼠标右键Generate,进行重写get和set方法。
    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;
    }
    //为了调试输出方面,还会加toString:
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}



手动注销session:

package com.rgf.servlet;

import com.rgf.pojo.Person;

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;

public class SessionDemo03 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
        HttpSession session = req.getSession();
        //取消掉我们所存入的name。
        session.removeAttribute("name");
        //手动注销session
        session.invalidate();

    }

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

自动注销session,会话自动过期:web.xml:

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

我们查看cookie原理如下所示:

 我们的session原理如下所示:‘

而对于ServletContext而言:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一直再追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值