一. 会话跟踪技术
HTTP无状态:服务器无法判断两次请求是否是同一客户端发出的,还是不同客户端发出的
通过会话跟踪技术可以解决HTTP无状态的问题。
当Client1发出request1时,Server会检查request1的SessionID,如果request1没有SessionID,则Server知道这是Client1的第一次请求,则Server会给Client1分发一个SessionID;当Client1发出request2时,Server会检查request2的SessionID,通过检查SessionID,则Server知道这是来自Client1的请求。
当Client2发出request时,Server会检查request的SessionID,通过检查SessionID,则Server知道这是来自Client2的请求。
会话跟踪技术:客户端第一次发请求给服务器,服务器获取session,如果获取不到,则创建新的session响应给客户端;客户端再次发送请求时,会将sessionId带给服务器,服务器就能根据sessionId判断这一次请求是否跟上一次请求来自同一个客户端。
package ServletStudy;
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 TestSession extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session,如果获取不到,则创建一个新的
HttpSession session = req.getSession();
System.out.println(session.getId()); //同一客户端的多次请求sessionId相同
}
}
<?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">
<servlet>
<servlet-name>TestSession</servlet-name>
<servlet-class>ServletStudy.TestSession</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestSession</servlet-name>
<url-pattern>/testSession</url-pattern>
</servlet-mapping>
</web-app>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action = "http://localhost:8080/WebStudy_war_exploded/testSession" method = "post">
<input type = "submit" value = "提交"/>
</form>
</body>
</html>
常用的API:
req.getSession():获取当前的会话,没有则创建一个新的会话
req.getSession(true):获取当前的会话,没有则创建一个新的会话
req.getSession(false):获取当前的会话,没有则返回null,不会创建一个新的会话
req.getSession().getId():获取sessionId
req.getSession().isNew():判断当前session是否是新的
req.getSession().getMaxInactiveInterval():seesion非激活间隔时长(即该会话的持续时间,默认是3分钟)
req.getSession().setMaxInactiveInterval():设置seesion非激活间隔时长
req.getSession().invalidate():强制让会话立即失效
二. session保存作用域
req.getSession().setAttribute("key","value"):向当前session保存作用域中保存一个数据("key","value")
req.getSession().getAttribute("key"):从当前session保存作用域中获取指定"key"对应的"value"
一个客户端对应一个会话保存作用域,即使不是该客户端的同一个请求,也能获得session保存作用域中的值。其他客户端不能获得该客户端在session保存作用域中的值。
package ServletStudy;
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 TestSession1 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.setAttribute("name","Tom");
}
}
package ServletStudy;
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 TestSession2 extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
System.out.println(session.getAttribute("name"));
}
}
<?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">
<servlet>
<servlet-name>TestSession1</servlet-name>
<servlet-class>ServletStudy.TestSession1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestSession1</servlet-name>
<url-pattern>/testSession1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>TestSession2</servlet-name>
<servlet-class>ServletStudy.TestSession2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestSession2</servlet-name>
<url-pattern>/testSession2</url-pattern>
</servlet-mapping>
</web-app>
客户端首先访问TestSession1设置session保存作用域,然后访问TestSession2,可以获得其中的值Tom。
另一个客户端直接访问TestSession2,则返回null。