redis로 spring session 저장

mjdevv·2024년 1월 26일
0

Spring

목록 보기
3/4
post-thumbnail

redis/spring session 연동 문제발생... 😒😒

아래와 같은 redis와 스프링 세션 연동 작업을 하다가 연결이 안 되는 문제가 발생 했다.

  1. build.gralde
	//redis
	implementation 'org.springframework.boot:spring-boot-starter-data-redis'
	implementation 'org.springframework.boot:spring-session-data-redis'
  1. redis / spring session 연동 테스트를 위한 컨트롤러
@RestController
public class AuthController {
    // Create Jackson ObjectMapper

    String HOME_VIEW_COUNT = "HOME_VIEW_COUNT";

    @GetMapping("/")
    public String hello(Principal principal, HttpSession session) throws JsonProcessingException {
        incrementCount(session , HOME_VIEW_COUNT);
        return "hello this is session ";// + principal.getName();
    }

    @GetMapping("/count")
    public String count(HttpSession session){
        return "HOME_VIEW_COUNT : " + session.getAttribute(HOME_VIEW_COUNT);
    }

    private void incrementCount(HttpSession session, String attr){
        var homeViewCount = session.getAttribute(attr) == null ? 0 : (Integer) session.getAttribute(attr);
        session.setAttribute(attr, homeViewCount += 1);
    }

}

3.application.properties

#### Spring Session
#### spring.session.jdbc.initialize-schema = none
spring.session.store-type=redis

#### Redis
spring.redis.host=localhost
spring.redis.port=6379

이슈발생

[2]의 Spring 공식문서 9.2.1 Connecting to Redis 항목에서는 application.properties에 커넥션 정보만 추가해주면 자동으로 연결 된다고 한다. 하지만 정작 날아오는 세션 값을 보니 톰캣의 jsessionid가 리턴 됐다.


해결

spring session과 연동이 안 돼서 톰캣의 jsessionid가 리턴 된 것 같은데 대체 왜 spring session이 연동이 안 됐을까.

1. 테스트 코드로 Redis connection을 먼저 확인

 	@Test
    @DisplayName("redis connection 테스트")
    public void redisConnectionTest(){
        ////redis connection infor
        String redisHost = "localhost";
        int redisPort = 6379;
        String redisPassword = null;

        RedisClient redisClient = null;
        StatefulRedisConnection<String, String> connection = null;

        //// connect
        redisClient = RedisClient.create("redis://" + redisHost + ":" + redisPort);
        connection = redisClient.connect();

        //// 패스워드 체크
        //if (redisPassword != null && !redisPassword.isEmpty()) {
        //  connection.sync().auth(redisPassword);
        //}

        //// 테스트 go go
        String serverInfo = connection.sync().info();

        String testKey = "test_key";
        String testValue = "test_value";

        connection.sync().set(testKey, testValue);
        String retrievedValue = connection.sync().get(testKey);

        //// assert
        assert connection.isOpen() : "Connection to Redis failed";

        //// Close the connection when done
        if (connection != null) connection.close();
        if (redisClient != null) redisClient.shutdown();

    }

테스트는 통과 했고,

로컬에 기동 된 레디스에 값도 잘 들어간다. 즉, redis에 직접 연결은 된다. spring session에서 접근이 안 되는 것 같은데 테스트 해보자.

2. Spring Session 연동 테스트

test를 위한 컨트롤러 추가

  @Controller
  @EnableRedisHttpSession
  public class TestSessionController {
      @GetMapping("/setTestSessionAttribute")
      @ResponseBody
      public String setSessionAttribute(HttpSession session) {
          session.setAttribute("test_key", "test_value");
          return "Session attribute set";
      }
  }

spring session test 케이스

@SpringBootTest
@AutoConfigureMockMvc
public class RedisSpringSessionConnection {
    @Autowired
    private MockMvc mockMvc;

    @Test
    public void testSetAndGetSessionAttribute() throws Exception {
        // Set session attribute
        ResultActions setResult = mockMvc.perform(get("/setTestSessionAttribute"));

        setResult.andExpect(status().isOk())
                .andExpect(content().string("Session attribute set"));
    }
}

[2]의 9.2.1 Connecting to Redis에서는 application.properties에 커넥션 정보만 추가해주면 자동으로 연결 된다고 하는데, 위 테스트가 계속 깨져서 확인해보니 RedisConnectionFactory를 찾을 수 없다는 에러가 뜬다.

그래서 아래 RedisConfig를 추가해줬다.

redis config 파일

@Configuration
@EnableRedisHttpSession
public class RedisConfig {
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory();
    }
}

이제 spring-session 값이 redis에 들어가는 걸 확인 할 수 있다. 마지막으로 클라이언트로 날아오는 쿠키값을 확인해보면,

JSessionid에서 spring session의 디폴트값인 session으로 바뀌어 있고,

외부 저장소 레디스에 세션이 저장 되어 서버를 재기동 해도 view_count가 그대로 나온다.


REFERENCE

[1] https://docs.spring.io/spring-session/reference/guides/boot-redis.html
[2] https://docs.spring.io/spring-boot/docs/3.2.0/reference/htmlsingle/#data.nosql.redis.connecting

profile
방구석 언어기술자

0개의 댓글

관련 채용 정보