Spring Sessionを使う
Spring Sessionを使ってHttpSessionをRedisで管理してみる
セットアップ
build.gradle
- dependenciesにspring-boot-starter-data-redisとspring-session-data-redisを追加する
plugins { id 'org.springframework.boot' version '2.5.0' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '11' repositories { mavenCentral() } dependencies { compileOnly 'org.projectlombok:lombok' implementation 'org.slf4j:slf4j-api' implementation 'ch.qos.logback:logback-core' implementation 'ch.qos.logback:logback-classic' implementation 'com.google.guava:guava:30.1.1-jre' implementation 'org.apache.commons:commons-lang3' implementation 'commons-beanutils:commons-beanutils:1.9.2' implementation 'com.amazonaws:aws-java-sdk-dynamodb:1.12.9' implementation 'org.springframework.boot:spring-boot-starter' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.1.4' implementation 'org.springframework:springloaded:1.2.8.RELEASE' implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.springframework.session:spring-session-data-redis' runtimeOnly 'mysql:mysql-connector-java' testImplementation 'org.springframework.boot:spring-boot-starter-test' } test { useJUnitPlatform() }
/src/main/resources/application.yml
- spring.session.store-type、spring.redis.host=localhost、spring.redis.portの定義を追加
server: servlet: context-path: /sample spring: messages: basename: "application-messages,ValidationMessages" encoding: "UTF-8" datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:33060/sample username: mysql-app password: mysql-app thymeleaf: cache: false session: store-type: redis ←追加 redis: host: localhost ←追加 port: 16379 ←追加 mybatis: configuration: map-underscore-to-camel-case: true logging: level: org: springframework: WARN com: example: demo: domain: mapper: DEBUG
/src/main/java/com/example/demo/web/controller/SessionCheckController.java
package com.example.demo.web.controller; import java.net.UnknownHostException; import java.time.LocalDateTime; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.example.demo.web.dto.form.SessionInfo; @RestController public class SessionCheckController { private final SessionInfo sessionInfo; @Autowired public SessionCheckController(SessionInfo sessionInfo) { this.sessionInfo = sessionInfo; } @GetMapping("/session/accept") public String start(HttpServletRequest request) throws UnknownHostException { if (sessionInfo.getStartedAt() == null) { sessionInfo.setClientIp(request.getRemoteAddr()); sessionInfo.setStartedAt(LocalDateTime.now()); sessionInfo.setMessage("Session start."); } else { sessionInfo.setMessage("Session is continuing."); } return String.format("[Message: %s] [Host: %s] [Started At: %s]", sessionInfo.getMessage(), sessionInfo.getClientIp(), sessionInfo.getStartedAt()); } @GetMapping("/session/invalidate") public String invalidate(HttpSession session) { session.invalidate(); return "Session invalidate."; } }
/src/main/java/com/example/demo/web/dto/form/SessionInfo.java
package com.example.demo.web.dto.form; import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.SessionScope; @Component @SessionScope public class SessionInfo implements Serializable { /** * SerialVersionUID. */ private static final long serialVersionUID = -6228456085202936272L; private String clientIp; private String startedAt; private String message; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getClientIp() { return clientIp; } public void setClientIp(String host) { this.clientIp = host; } public String getStartedAt() { return startedAt; } public void setStartedAt(String startedAt) { this.startedAt = startedAt; } public void setStartedAt(LocalDateTime startedAt) { this.startedAt = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss").format(startedAt); } }
/src/main/java/com/example/demo/WebConfiguration.java
- springSessionDefaultRedisSerializerメソッドを追加。オブジェクトをJSON形式に変換してRedisに登録する
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.example.demo.interceptor.RequestHandlerInterceptor; @Configuration public class WebConfiguration implements WebMvcConfigurer { @Autowired private RequestHandlerInterceptor requestHandlerInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(requestHandlerInterceptor); } @Bean public RedisSerializer<Object> springSessionDefaultRedisSerializer() { return new GenericJackson2JsonRedisSerializer(); } }