10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SpringBoot2+SpringSessionにてデータベースを利用する

Posted at

実はいろいろと情報が錯綜していたため、動作するまでに一手間がかかりました(´・ω・)

目的

SpringBoot2+SpringSessionを利用してセッション情報をデータベースで管理する

動作環境+バージョン情報

以下で動作確認をしています。

  • SpringBoot 2.0.5.RELEASE。
  • Oracle XE
  • SpringBoot-starter
    • web
    • session-core
    • session-jdbc
  • HikariCP

SpringSessionJdbcに必要なライブラリ依存関係は、Appendixのmaven(pom.xml)に記載しております。バージョンを略記しているものは、SpringBoot2.0.5管理下にあるものを使います。

下準備

SpringSessionでデータベース利用に必要なもの

maven(pom.xml)のとおり、最低限以下が必要です。

  • spring-boot-starter
    • web
    • session-core
    • session-jdbc
  • 接続プール (今回はSpringBoot2から推奨されている HikariCP を利用しています)
  • 設定ファイルにデータベース接続プールの設定と、SpringSessionの設定を記載

利用するためのConfigクラス

@EnableJdbcHttpSession を宣言します。SpringBootでアプリケーションを作るときはよくConfigureクラスなどで作ります。もしアプリケーション内でJDBCの設定がない場合は、JDBCのトランザクション設定を書きます。以下はJavaConfigの例。

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.session.jdbc.config.annotation.web.http.EnableJdbcHttpSession;
import org.springframework.transaction.PlatformTransactionManager;

/**
 * @author A-pZ
 */
@EnableJdbcHttpSession
public class JdbcHttpSessionConfig {
	@Bean
	public PlatformTransactionManager transactionManager(DataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}
}

JDBC設定

JDBCの設定は、Appendixの設定(application.yml) を参考にしてください。

HTTPセッションを利用するController

では具体的に、HttpSessionを利用するControllerです。

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @author A-pZ
 */
@Controller
public class SampleController {
	@GetMapping("")
	public String start(HttpSession session) {
		session.setAttribute("sample", "sample");
		return "index";
	}
}

このController実行後の画面(index.html)は、特に何もしない静的HTMLのThymeleafテンプレートを出力させます(JSPでも良いでしょう)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
</head>
<body>
	index.html
</body>
</html>

動作後、セッションを扱っているデータベースのレコードを見ると、

spring-session-jdbc.png

このようにセッション情報がデータベースに格納されていることがわかります。

Appendix

maven(pom.xml)

Oracle JDBCドライバは別途ローカルリポジトリか、ローカル環境のNexusなどのリポジトリへ登録してください。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.github.alphapz.springsample</groupId>
	<artifactId>spring-session-sample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>spring-session-sample</name>
	<description>spring-session-sample</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.4.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-core</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>oracle.jdbc</groupId>
			<artifactId>ojdbc7</artifactId>
			<version>12.1.0.2.0</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.session</groupId>
			<artifactId>spring-session-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-configuration-processor</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>com.zaxxer</groupId>
			<artifactId>HikariCP</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

設定(application.yml)

SpringSessionJdbcを動作させるための最低限の設定です。

spring:
  session:
    timeout: 300
    jdbc:
      initialize-schema: always
      table-name: SPRING_SESSION
  datasource:
    url: jdbc:oracle:thin:@127.0.0.1:1521:xe
    username: springsession
    password: springsession
    tomcat:
      data-source: com.zaxxer.hikari.HikariDataSource

投入SQL(Oracle DB)

CREATE TABLE SPRING_SESSION (
	PRIMARY_ID CHAR(36) NOT NULL,
	SESSION_ID CHAR(36) NOT NULL,
	CREATION_TIME NUMBER(19,0) NOT NULL,
	LAST_ACCESS_TIME NUMBER(19,0) NOT NULL,
	MAX_INACTIVE_INTERVAL NUMBER(10,0) NOT NULL,
	EXPIRY_TIME NUMBER(19,0) NOT NULL,
	PRINCIPAL_NAME VARCHAR2(100 CHAR),
	CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);

CREATE UNIQUE INDEX SPRING_SESSION_IX1 ON SPRING_SESSION (SESSION_ID);
CREATE INDEX SPRING_SESSION_IX2 ON SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX SPRING_SESSION_IX3 ON SPRING_SESSION (PRINCIPAL_NAME);

CREATE TABLE SPRING_SESSION_ATTRIBUTES (
	SESSION_PRIMARY_ID CHAR(36) NOT NULL,
	ATTRIBUTE_NAME VARCHAR2(200 CHAR) NOT NULL,
	ATTRIBUTE_BYTES BLOB NOT NULL,
	CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
	CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);

ハマリポイント

JDBCを利用したSpringSessionを有効化するためには、実はかなり設定する箇所が減っており、@EnableJdbcHttpSessionで必要なSpringBean定義は、TransactionManager から DataSource を渡すだけで済みます。

実はこのDataSource設定を何らかのJavaConfigで記載したときには、Beanの優先度をつけるか、Qualifierで別名をつけないと、起動時エラーになります。なお、旧来のSpringBootで利用しているDataSource設定の記述をすると、DataSourceの設定方法が変わったため、これまた実行時エラーになります。(データソースの型が解決できない、または、ymlから読み込んだが型に変換できない、など…)

10
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?