Spring Session - HttpSession (快速入門)

本指南說明如何使用 Spring Session 以透明方式運用 Redis 來支援 Web 應用程式的 HttpSession,並使用 Java 設定。

您可以在 httpsession 範例應用程式中找到已完成的指南。

更新相依性

在使用 Spring Session 之前,您必須更新您的相依性。如果您使用 Maven,則必須新增下列相依性

pom.xml
<dependencies>
	<!-- ... -->

	<dependency>
		<groupId>org.springframework.session</groupId>
		<artifactId>spring-session-data-redis</artifactId>
		<version>3.3.3</version>
		<type>pom</type>
	</dependency>
	<dependency>
		<groupId>io.lettuce</groupId>
		<artifactId>lettuce-core</artifactId>
		<version>6.3.2.RELEASE</version>
	</dependency>
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-web</artifactId>
		<version>6.1.14</version>
	</dependency>
</dependencies>

由於我們使用的是 SNAPSHOT 版本,因此我們需要確保新增 Spring Snapshot Maven 儲存庫。您的 pom.xml 中必須包含以下內容

pom.xml
<repositories>

	<!-- ... -->

	<repository>
		<id>spring-snapshot</id>
		<url>https://repo.spring.io/libs-snapshot</url>
	</repository>
</repositories>

Spring Java 設定

新增必要的相依性後,我們可以建立 Spring 設定。Spring 設定負責建立一個 Servlet 篩選器,該篩選器會將 HttpSession 實作替換為由 Spring Session 支援的實作。若要執行此操作,請新增下列 Spring 設定

@Configuration(proxyBeanMethods = false)
@EnableRedisHttpSession (1)
public class Config {

	@Bean
	public LettuceConnectionFactory connectionFactory() {
		return new LettuceConnectionFactory(); (2)
	}

}
1 @EnableRedisHttpSession 註解會建立一個名為 springSessionRepositoryFilter 的 Spring Bean,該 Bean 實作 Filter。此篩選器負責替換 HttpSession 實作,使其由 Spring Session 支援。在此範例中,Spring Session 由 Redis 支援。
2 我們建立一個 RedisConnectionFactory,將 Spring Session 連接到 Redis 伺服器。我們將連線設定為連線到預設埠 (6379) 上的 localhost。如需有關設定 Spring Data Redis 的詳細資訊,請參閱參考文件

Java Servlet 容器初始化

我們的 Spring 設定 建立了一個名為 springSessionRepositoryFilter 的 Spring Bean,該 Bean 實作 FilterspringSessionRepositoryFilter Bean 負責將 HttpSession 替換為由 Spring Session 支援的自訂實作。

為了讓我們的 Filter 發揮作用,Spring 需要載入我們的 Config 類別。最後,我們需要確保 Servlet 容器 (即 Tomcat) 對每個請求都使用我們的 springSessionRepositoryFilter。幸運的是,Spring Session 提供了一個名為 AbstractHttpSessionApplicationInitializer 的公用程式類別,讓這兩個步驟都變得容易。以下範例示範了如何操作

src/main/java/sample/Initializer.java
public class Initializer extends AbstractHttpSessionApplicationInitializer { (1)

	public Initializer() {
		super(Config.class); (2)
	}

}
我們的類別名稱 (Initializer) 並不重要。重要的是我們擴充了 AbstractHttpSessionApplicationInitializer
1 第一個步驟是擴充 AbstractHttpSessionApplicationInitializer。這樣做可確保名為 springSessionRepositoryFilter 的 Spring Bean 已向 Servlet 容器註冊以處理每個請求。
2 AbstractHttpSessionApplicationInitializer 也提供了一種機制,可確保 Spring 載入我們的 Config

httpsession 範例應用程式

執行 httpsession 範例應用程式

您可以透過取得原始碼並調用下列命令來執行範例

$ ./gradlew :spring-session-sample-javaconfig-redis:tomcatRun
為了讓範例能夠運作,您必須在 localhost 上安裝 Redis 2.8+ 並使用預設埠 (6379) 執行它。或者,您可以更新 RedisConnectionFactory 以指向 Redis 伺服器。另一種選擇是使用 Docker 在 localhost 上執行 Redis。請參閱 Docker Redis 儲存庫 以取得詳細指示。

您現在應該可以透過 localhost:8080/ 存取應用程式

探索 httpsession 範例應用程式

現在您可以嘗試使用此應用程式。若要執行此操作,請填寫具有下列資訊的表單

  • 屬性名稱: username

  • 屬性值: rob

現在按一下設定屬性按鈕。您現在應該會在表格中看到顯示的值。

它是如何運作的?

我們在下列清單中所示的 SessionServlet 中與標準 HttpSession 互動

src/main/java/sample/SessionServlet.java
@WebServlet("/session")
public class SessionServlet extends HttpServlet {

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		String attributeName = req.getParameter("attributeName");
		String attributeValue = req.getParameter("attributeValue");
		req.getSession().setAttribute(attributeName, attributeValue);
		resp.sendRedirect(req.getContextPath() + "/");
	}

	private static final long serialVersionUID = 2878267318695777395L;

}

我們不是使用 Tomcat 的 HttpSession,而是將值保存在 Redis 中。Spring Session 會在您的瀏覽器中建立一個名為 SESSION 的 Cookie。該 Cookie 包含您 Session 的 ID。您可以檢視 Cookie (ChromeFirefox)。

您可以使用 redis-cli 移除 Session。例如,在以 Linux 為基礎的系統上,您可以輸入下列內容

	$ redis-cli keys '*' | xargs redis-cli del
Redis 文件中有關於安裝 redis-cli 的指示。

或者,您也可以刪除明確的金鑰。在您的終端機中輸入下列內容,請務必將 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e 替換為您 SESSION Cookie 的值

	$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e

現在您可以造訪 localhost:8080/,並查看我們新增的屬性不再顯示。