* Spring BootのセッションストアをRedisにする [#cff165ee] #setlinebreak(on); #contents -- 関連 --- [[Spring BootでWebAPI作成]] --- [[AWS EC2上で Spring Bootアプリ起動]] ** はじめに [#wb1d09f8] #html(<div style="padding-left:20px">) [[RedisをWebアプリのセッションストアとして使用する]] 為の前準備。 今回使用するのは spring-data-redis https://projects.spring.io/spring-data-redis/ #html(</div>) ** Redisのインストール/アップデート [#ec9b02cf] 以下、Macの場合。 *** インストール [#z76efe09] #code(myterm2 nolinenums){{ brew install redis }} *** アップデート [#ke3c399a] #code(myterm2 nolinenums){{ #sudo xcodebuild -license accept brew update brew upgrade redis }} *** redis にパスワードを設定 [#qaadcb07] /usr/local/etc/redis.conf #code(myterm2 linenums:396){{ requirepass example_pass }} *** redis 起動 [#pfb8b8aa] #code(myterm2 nolinenums){{ redis-server /usr/local/etc/redis.conf & }} *** redis 停止 [#e34166d5] #code(myterm2 nolinenums){{ redis-cli shutdown }} *** 確認 [#x96e6779] #code(myterm2 nolinenums){{ redis-cli redis 127.0.0.1:6379> set testkey1 value1 OK redis 127.0.0.1:6379> get testkey1 "value1" }} ** Spring Bootアプリの変更 [#v46ba437] [[Spring BootでWebAPI作成]] で作成したアプリに redis に接続する処理を追加していく。 *** build.gradle の修正 [#l728bd61] build.gradle #code(mycode2 linenums:28){{ repositories { mavenCentral() maven { url("https://repo.spring.io/libs-release") /* 追加 */ } /* 古い書き方 mavenRepo url: [ "https://repo.spring.io/libs-release", ] */ } dependencies { . . compile("org.springframework.boot:spring-boot-starter-data-redis") compile("org.springframework.session:spring-session-data-redis") } }} *** application.properties の修正 [#l7d0adb4] application.properties に以下を追記。 #code(mycode2 linenums:11){{ # Redis spring.session.store-type=redis spring.redis.host=localhost spring.redis.port=6379 spring.redis.password=example_pass spring.redis.database=0 spring.redis.pool.max-idle=8 spring.redis.pool.min-idle=0 spring.redis.pool.max-active=8 spring.redis.pool.max-wait=1 }} *** Configの作成 [#n94a561b] #mycode2(mycode2 linenums){{ package com.example.demo.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @Configuration @EnableRedisHttpSession public class HttpSessionConfig { private @Value("${spring.redis.host}") String redisHost; private @Value("${spring.redis.port}") int redisPort; private @Value("${spring.redis.password}") String redisPassword; // JSONにシリアライズする場合 //@Bean //public RedisSerializer<Object> springSessionDefaultRedisSerializer() { // return new GenericJackson2JsonRedisSerializer(); //} @Bean public JedisConnectionFactory connectionFactory() { JedisConnectionFactory factory = new JedisConnectionFactory(); factory.setHostName(redisHost); factory.setPort(redisPort); factory. setPassword(redisPassword); factory.setUsePool(true); return factory; } } }} *** セッションに格納するBeanを作成 [#tfa64c2b] #code(mycode2){{ package com.example.demo.config; import java.io.Serializable; import org.springframework.stereotype.Component; import lombok.Data; @Data @Component public class SessionInfo implements Serializable { private static final long serialVersionUID = 1L; private String userId; private String userName; private String email; } }} *** コントローラの作成 [#f8514373] #code(mycode2){{ package com.example.demo.controller; import javax.servlet.http.HttpSession; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.example.demo.config.SessionInfo; @RestController @RequestMapping("/session") public class LoginSampleController { @RequestMapping(value = "/login", method = RequestMethod.POST) public String login(HttpSession httpSession, @RequestParam("userid") String userId) { SessionInfo sessionInfo = new SessionInfo(); sessionInfo.setUserId(userId); httpSession.setAttribute("user", sessionInfo); return "login OK"; } @RequestMapping(value = "/info", method = RequestMethod.GET) public String getInfo(HttpSession httpSession) { SessionInfo sessionInfo = (SessionInfo)httpSession.getAttribute("user"); if (sessionInfo == null) { return "sessionInfo is null"; } return "user is " + sessionInfo.getUserId(); } @RequestMapping(value = "/logout", method = RequestMethod.DELETE) public String logout(HttpSession httpSession) { httpSession.invalidate(); return "logout OK"; } } }} ** 動作確認 [#lf96d9aa] Redisをいったんクリアしておく #code(myterm2){{ redis-cli 127.0.0.1:6379> AUTH example_pass OK 127.0.0.1:6379> flushdb OK }} &br; APIにアクセスして確認 #code(myterm2){{ # セッションの状態を確認 curl --cookie-jar cookies.txt --cookie cookies.txt -v http://localhost:8080/session/info # ログイン curl --cookie-jar cookies.txt --cookie cookies.txt -v -XPOST --data "userid=user001" http://localhost:8080/session/login # セッションの状態を確認 curl --cookie-jar cookies.txt --cookie cookies.txt -v http://localhost:8080/session/info # ログアウト curl --cookie-jar cookies.txt --cookie cookies.txt -v -XDELETE http://localhost:8080/session/logout # セッションの状態を確認 curl --cookie-jar cookies.txt --cookie cookies.txt -v http://localhost:8080/session/info }}