Session
什么是Session:
- 服务器会给每一个用户(浏览器) 创建一个Session对象;
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在;
- 用户登陆之后,整个网站它都可以访问。
Session和Cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
- Session是把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源)
- Session对象由服务创建
使用场景:
- 保存一个登陆用户的信息;
- 购物车信息;
- 整个网站中经常会使用的数据,将其保存在Session中
路径
依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
Tomcat设置
使用Session
为了看起来舒服,我的java类均命名为了aXX_SessionDemo
,但为了描述方便,均以SessionDemoX描述,请自行对应。
SessionDemo1
package com.huangdekai.JavaWeb;
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;
/**
* @Autord: HuangDekai
* @Date: 2020/4/21 1:19
* @Version: 1.0
* @since: jdk11
*/
public class a01_SessionDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决乱码问题
req.setCharacterEncoding("utf-16");
resp.setCharacterEncoding("utf-16");
resp.setContentType("text/html;charset=utf-16");
// 获取Session
HttpSession session = req.getSession();
// 给Session存东西
session.setAttribute("name","杜撰");
// 获取SessionId
String sessionId = session.getId();
// 判断Session是否为新创建的
if (session.isNew()) {
resp.getWriter().write("新创建的Session的id为:"+ sessionId);
} else {
resp.getWriter().write("已存在Session,id为:"+ sessionId);
}
}
@Override
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
写Servlet:
<servlet>
<servlet-name>SessionDemo01</servlet-name>
<servlet-class>com.huangdekai.JavaWeb.a01_SessionDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo01</servlet-name>
<url-pattern>/session01</url-pattern>
</servlet-mapping>
访问:
SessionDemo2
可以看到,我们在SessionDemo1中存放了一个key:value(L:29),现在我们从同一个浏览器的另外一个页面取出来:
package com.huangdekai.JavaWeb;
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;
/**
* @Autord: HuangDekai
* @Date: 2020/4/21 12:05
* @Version: 1.0
* @since: jdk11
*/
public class a02_SessionDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决中文乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-16");
resp.setContentType("text/html;charset=utf-16");
// 获取Session
HttpSession session = req.getSession();
// 从Session中取值
String name = (String) session.getAttribute("name");
// 将其打印到前端
PrintWriter writer = resp.getWriter();
writer.write("用户名为: "+name);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Servlet:
<servlet>
<servlet-name>SessionDemo02</servlet-name>
<servlet-class>com.huangdekai.JavaWeb.a02_SessionDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo02</servlet-name>
<url-pattern>/session02</url-pattern>
</servlet-mapping>
重启Tomcat,访问session02:
当然,没有访问session01,并没有储存值在里面,先访问session01
再访问session02:
这就是不同于ServeletContext的跨页面传送值的一个方法。
当然了,session不仅仅可以传输字符串,比如还可以传输一个对象,可以将SessionDemo1第29行里的value改为对象就行。当然,java万物皆对象,只要稍作修改即可,不再赘述。
注销Session
注销Session的值:
创建一个SessionDemo03:
package com.huangdekai.JavaWeb;
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;
/**
* @Autord: HuangDekai
* @Date: 2020/4/21 12:47
* @Version: 1.0
* @since: jdk11
*/
public class a03_SessionDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
// 手动注销session
// 注销某条信息,session还存在
session.removeAttribute("name");
// 注销Session
//session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置Servlet:
<servlet>
<servlet-name>SessionDemo03</servlet-name>
<servlet-class>com.huangdekai.JavaWeb.a03_SessionDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo03</servlet-name>
<url-pattern>/session03</url-pattern>
</servlet-mapping>
重启Tomcat,访问session01给Session赋值:
访问session02:
访问session03,因为前端没有写东西,空白一片:
再访问session02:
可以看到其Session的值没有了,此时再访问session01:
可以发现Session的id没变,依旧还是那个Session
手动注销Session
将SessionDemo3的第23行注释掉,并去掉第26行的注释,使得第26的代码启用。
重新启动Tomcat,访问session01:
访问session02:
访问session03:
再访问session02(chrome浏览器的状况,其他浏览器可能不相同):
再访问session01:
可以发现,已经不是原来的那个Session了。
只要浏览器运行,就会有Session,再session03中我们注销了一个Session,那么浏览器会创建一个新的Session。
如果你访问session03后立刻访问session01,还会发现如下变化:
重新回顾一下SessionDemo01的代码可以发现session.isNew()
返回了true
,这也说明了只要没关闭浏览器而注销了Session,浏览器会为我们新创建一个Session,这个Session是空的。
自动注销Session
应用场景:比如登陆多久之后不再登陆,自动退出账户登陆之类。
在web.xml里写如下代码
<!-- 设置session默认的失效时间 -->
<session-config>
<!-- 表示一分钟后session失效 -->
<session-timeout>1</session-timeout>
</session-config>
重启Tomcat,访问session01:
等一分钟,一分钟之后我们先看看session02(自动注销的时间之后,之前访问值不为空,另外,再次:此为Chrome浏览器的结果,其他浏览器可能不一样):
再访问session01:
可以看到Session确实是被注销了。
最后附上我的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>SessionDemo01</servlet-name>
<servlet-class>com.huangdekai.JavaWeb.a01_SessionDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo01</servlet-name>
<url-pattern>/session01</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SessionDemo02</servlet-name>
<servlet-class>com.huangdekai.JavaWeb.a02_SessionDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo02</servlet-name>
<url-pattern>/session02</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>SessionDemo03</servlet-name>
<servlet-class>com.huangdekai.JavaWeb.a03_SessionDemo</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SessionDemo03</servlet-name>
<url-pattern>/session03</url-pattern>
</servlet-mapping>
<!-- 设置session默认的失效时间 -->
<session-config>
<!-- 表示一分钟后session失效 -->
<session-timeout>1</session-timeout>
</session-config>
</web-app>