SpringBootでredisを使用する準備
アプリ側の設定
build.gradleに依存関係を追記
dependencies {
implementation "org.springframework.boot:spring-boot-starter-data-redis"
implementation "org.springframework.session:spring-session-data-redis"
}
application.ymlにセッション関係の記述を追記
必須の記述
spring:
session:
store-type:redis
必要に応じた設定
spring:
session:
store-type:redis
redis:
host: localhost
port: 6379
password: example_pass
database: 0
redisのホストやポートを変更する場合は、上記の要領で設定してください。
この記述はなくても、localhost:6379をデフォルトの接続先として接続しに行ってくれます。
redisの起動
dockerまたはローカルにredisをインストールして起動します。
ここでは、dockerの例を示します。(dockerがお手軽です)
version: "3"
services:
session: # サービス名
container_name: session # コンテナ名
image: redis:7.0-rc1 # イメージ名
ports:
- 6379:6379
上記の要領でコンテナを定義し、docker-compose up -d
により起動します。
サービス名やコンテナ名は任意のものでOKです。
イメージ名は単に"redis"でもOKです。
SpringBootからredisにセッション情報が追加されたことを確認する
redisを起動した後、./gradlew bootRun
などでSpringBootを起動し、想定しているセッション機能が正常に動いていることを確認してください。
redisにセットされている情報については、redis-cliで確認します。
$ docker exec -it session /bin/sh
# redis-cli
$ docker exec -it session /bin/sh
でredisコンテナに入ります。
"session" はコンテナ名またはコンテナIDにしてください。
# redis-cli
でredis-cliを起動します。
dockerのredisイメージにはインストールされています。
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> keys *
1) "spring:session:expirations:1645267680000"
2) "spring:session:sessions:f95b467a-3c1f-43e9-bcf8-04adf65b24e6"
3) "spring:session:sessions:expires:f95b467a-3c1f-43e9-bcf8-04adf65b24e6"
keys *
でredisに登録されているキーの一覧を表示します。
最初は (empty array)
ですが、
アプリでセッションがセットされると、次のようなセッションのキーが登録されていることがわかります。
1) "spring:session:expirations:1645267680000"
2) "spring:session:sessions:f95b467a-3c1f-43e9-bcf8-04adf65b24e6"
3) "spring:session:sessions:expires:f95b467a-3c1f-43e9-bcf8-04adf65b24e6"
(2)がユーザーの個別のセッションです。
(1)(3)はセッションの有効期限のようです。
get キー名
で値を見ることができます。
127.0.0.1:6379> get spring:session:sessions:f95b467a-3c1f-43e9-bcf8-04adf65b24e6
(error) WRONGTYPE Operation against a key holding the wrong kind of value
しかし、(2)をgetしようとしたところ、エラーが発生。
(このエラーについては、下記エラーのWRONGTYPEを参照)
127.0.0.1:6379> hgetall "spring:session:sessions:5fee809a-d936-4e34-8490-221db8519a22"
1) "sessionAttr:SESSION_LOGIN_DATETIME"
2) "\xac\xed\x00\x05sr\x00\rjava.time.Ser\x95]\x84\xba\x1b\"H\xb2\x0c\x00\x00xpw\x0e\x05\x00\x00\a\xe6\x02\x13\x15.84\xaf\x1f x"
3) "maxInactiveInterval"
4) "\xac\xed\x00\x05sr\x00\x11java.lang.Integer\x12\xe2\xa0\xa4\xf7\x81\x878\x02\x00\x01I\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\a\b"
5) "lastAccessedTime"
6) "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01\x7f\x12\x05it"
7) "creationTime"
8) "\xac\xed\x00\x05sr\x00\x0ejava.lang.Long;\x8b\xe4\x90\xcc\x8f#\xdf\x02\x00\x01J\x00\x05valuexr\x00\x10java.lang.Number\x86\xac\x95\x1d\x0b\x94\xe0\x8b\x02\x00\x00xp\x00\x00\x01\x7f\x12\x05aa"
このように、get キー
ではなく、hgetall キー
により中身を見ることができます。
SpringBoot-redisで遭遇するエラー
RedisConnectionFailureException: Unable to connect to Redis
redisを使おうとgradle bootRun
した時に発生します。
Caused by: org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException: Unable to connect to localhost/<unresolved>:6379
理由:redisが起動していない。
対策:redisを起動する。
WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get "spring:session:sessions:5fee809a-d936-4e34-8490-221db8519a22"
(error) WRONGTYPE Operation against a key holding the wrong kind of value
理由:キーが保有しているバリュー(値)を取得するコマンドが間違っている。
対策:バリューの形に応じた取得コマンドを使用する。