37
36

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.

Spring Sessionでデータベースにセッション情報を格納する

Posted at

Spring Sessionとは

HttpSessionの機能を上書きして、RedisやRDBMSなどでセッション情報を管理することができます。
通常はアプリケーションサーバでセッション情報を管理していますが、複数台のサーバを用意してロードバランスしながら運用している場合、複数サーバ間でセッション情報を同期する(セッションレプリケーション)、もしくはユーザとサーバが1対1となるようにロードバランスする(スティッキーセッション)といった必要があり、何かと面倒です。

そこで、セッション情報をアプリケーションサーバ以外の場所に切り出してしまおう、というときにSpring Sessionはいい感じに使えます。

Spring Sessionを使う

プロジェクトの作成

Spring InitializrでSpring Bootプロジェクトを作成します。
https://start.spring.io/

今回はDependenciesとして以下を追加しました。

  • Web
  • Thymeleaf
  • Session
  • JDBC
  • PostgreSQL
  • Lombok

セッション情報を格納するRDBMSはPostgreSQLにしています。

application.properties

application.properties
spring.session.store-type=jdbc
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.datasource.driver-class-name=org.postgresql.Driver

spring.session.store-typeをjdbcにしておけば、SpringSession関連の設定が勝手に行われる感じです。
いやーSpringBootって便利ですね。
(datasourceの設定は環境に合わせて指定してください。)

データベースのセットアップ

自動的にセットアップする方法もありそうな気がしますが、やり方がよくわからないので、セッション情報を格納するためのテーブルを作成します。
SpringSessionJdbc内にsqlファイルが存在するのでそれを実行すればOKです。
https://github.com/spring-projects/spring-session/tree/master/spring-session-jdbc/src/main/resources/org/springframework/session/jdbc

※上記はGitHubのmasterなので、バージョンによってはSQLが異なる可能性があります。

セッションを操作してみる

以下のようなControllerクラスを作成してセッション情報を操作してみました。

HelloController.java
@Controller
public class HelloController {

    @Autowired
    SessionData sessionData;

    @GetMapping(value = "/")
    public String index() {
        return "index";
    }

    @GetMapping(value="/set")
    public String set(){
        sessionData.setStr1("hogehoge");
        sessionData.setStr2("fugafuga");
        sessionData.setStr3("piyopiyo");
        return "redirect:/";
    }
}
SessionData.java
@Data
@Component
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class SessionData implements Serializable{
    private static final long serialVersionUID = 1L;
    String str1;
    String str2;
    String str3;
}
index.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">

<head>
    <meta charset="UTF-8" />
    <title>Hello Thymeleaf</title>
</head>

<body>
    <div>
        str1:
        <span th:text="${@sessionData.str1}">aaa</span>
    </div>
    <div>
        str2:
        <span th:text="${@sessionData.str2}">aaa</span>
    </div>
    <div>
        str3:
        <span th:text="${@sessionData.str3}">aaa</span>
    </div>
    <form th:action="@{/set}" method="get">
        <button>set</button>
    </form>
</body>

</html>

実装についてはいつも通りセッションを操作すればOKです。
データベースを確認すると、そこにセッション情報が保持されていることがわかります。

なお、データはSerializeして格納するため、セッション情報はSerializableを実装する必要があります。


以上のように、簡単にセッション情報をRDBMSに格納することが出来ます。
個人的には情報をJSONにして格納してしてくれたほうが色々取り回しやすいかなーと思いました。
データ変換部分をカスタマイズできるらしいのですが、データ型を変更するとなると大変そうなので諦めました。
(DBのスキーマも変わるので、ほぼ作り変えないといけない。)

なお、Redisを利用する実装にはJSONでデータを格納する方法が提供されているようです。

37
36
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
37
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?