Spring Boot Session 会话管理

Spring Boot Session

会话管理是用于安全控制一个用户或者实体对基于网络的应用/服务的多个请求的过程。

HTTP用于网站和浏览器之间的交流,而会话则是同一个用户创建的一系列的HTTP请求和事务。

会话管理的实现规定了用户、网络应用之间共享和持续交换会话ID的过程。

由于HTTP协议的无状态,为了跟踪客户的行为,我们需要会话管理。会话管理是一个网络容器框架,用于为特定的用户储存会话数据

我们可以通过以下方法处理会话:

  1. Cookies

    网站发送的数据被储存在用户的本地浏览器中

  2. 隐藏的表达字段

    在隐藏的数据中,对用户不可见也不可修改,当用户提交表单时,隐藏数据会被发送。

  3. URL重写

    修改URL的参数

  4. HttpSession(网络会话)

    允许数据与单个访问者绑定

在分布式环境中,我们可以通过以下方式管理会话:

  • 粘性会话(Sticky Session)

    在这种类型的会话中,负载均衡将把通过一个客户的请求路由到同一个节点,如果这个节点发生故障,则会话会丢失。

  • 复制会话(Session Replication)

    为了克服粘性会话的问题,会话复制将会话数据复制到多个服务器,当任何节点发生故障后,会话数据可以转移到另外的节点。

  • 持久数据储存中的会话数据(Session Data in a Persistent DataStore)

    还有一种情况下,会话数据并不会储存在服务器中,取而代之的是,它会被储存在数据库里,并且拥有唯一id SESSION_ID

Spring Session

Spring Session包含下述组件:

  • Spring Session Core

    Spring Session的核心APIs

  • Spring Session Data Redis

    提供Redis数据库会话管理的会话存储库

  • Spring Session JDBC

    提供关系数据库会话管理的会话存储库

  • Spring Session Hazelcast

    提供Hazelcast会话管理的会话存储库

默认情况下,Apache Tomcat在内存中储存HTTP会话管理的对象。为了管理Spring Boot 会话管理,HTTPSession会被用于通过Spring Session JDBC在持久层中存储会话信息。

maven中导入

<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-core</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-jdbc</artifactId>
		</dependency>

创建Controller

为了处理用户的请求,处理用户的数据并将数据存储在会话的 NOTES_SESSION 属性中。

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class SpringBootSessionController {
    @PostMapping("/addNote")
    public String addNote(@RequestParam("note") String note, HttpServletRequest request) {
        //get the notes from request session
        List<String> notes = (List<String>) request.getSession().getAttribute("NOTES_SESSION");
        //check if notes is present in session or not
        if (notes == null) {
            notes = new ArrayList<>();
            // if notes object is not present in session, set notes in the request session
            request.getSession().setAttribute("NOTES_SESSION", notes);
        }
        notes.add(note);
        request.getSession().setAttribute("NOTES_SESSION", notes);
        return "redirect:/home";
    }
    @GetMapping("/home")
    public String home(Model model, HttpSession session) {
        List<String> notes = (List<String>) session.getAttribute("NOTES_SESSION");
        model.addAttribute("notesSession", notes!=null? notes:new ArrayList<>());
        return "home";
    }
    @PostMapping("/invalidate/session")
    public String destroySession(HttpServletRequest request) {
        //invalidate the session , this will clear the data from configured database (Mysql/redis/hazelcast)
        request.getSession().invalidate();
        return "redirect:/home";
    }
}

为了验证,我们可以创建一个html:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spring Boot Session Management Example</title>
</head>
<body>
	<div>
		<form th:action="@{/addNote}" method="post">
			<textarea name="note" cols="40" rows="2"></textarea>
			<br> <input type="submit" value="Add Note" />
		</form>
	</div>
	<div>
		<form th:action="@{/invalidate/session}" method="post">
			<input type="submit" value="Destroy Session" />
		</form>
	</div>
	<div>
		<h2>Notes</h2>
		<ul th:each="note : ">
			<li th:text="">note</li>
		</ul>
	</div>

</body>
</html>

在页面上添加note到session中后,数据库中会创建两个表:

  1. spring_session
  2. spring_session_attributes

点击Destroy Session后,数据库中spring_session_attributes的数据将被清除。

上一篇:Notes真的无处不在


下一篇:基于AndroidPn二次开发的可行性