2.
JsonParseException
어떤 상황에서 발생한 버그인가?
이전 포스트에서 결정한 랭킹 조회 알고리즘을 코드로 작성하고 테스트를 해 보던 와중 발생한 버그이다.
일단 스케줄러를 이용해서 일정 시간마다 resolution 테이블에서 likeCount 내림차순으로 10개를 가져온다.
이 후 해당 값을 redis에 List 형으로 저장한 후, 랭킹 조회 api가 호출될 시 redis에서 랭킹 데이터를 가져오는 방식이였다.
조회 api는 오직 redis만 바라보고 있어야 하기 때문에(RDB에 접근하는 코드가 있어서는 안된다.) redis에 저장된 데이터의 value가 바로 Response로 반환할 수 있어야 하는 값이어야 한다고 생각했다. 따라서 스케쥴러를 이용해 redis에 데이터를 집어넣는 과정에서 value의 데이터 타입을 responseDTO로 설정했다. 아래는 그 코드이다.
@Scheduled(fixedRate = 120000)
fun getResolutionTop10(){
redisTemplate.delete("ranking")
resolutionRepository.getResolutionRanking()
.forEach{
redisTemplate.opsForList().rightPush("ranking", SimpleResolutionResponse.from(it))
}
}
이 코드에서 DTO를 value에 넣기 위해서 직렬화 방식을 GenericJackson2JsonRedisSerializer를 사용했다.
이는 객체를 JSON 형태롤 직렬화/역직렬화 하는 방식의 직렬화 알고리즘이다.
RedisConnection 클래스에서 설정할 수 있다.
@Bean
fun redisTemplate(): RedisTemplate<*,*>{
return RedisTemplate<Any, Any>().apply{
this.connectionFactory = lettuceConnectionFactory()
this.keySerializer = StringRedisSerializer()
this.valueSerializer = GenericJackson2JsonRedisSerializer()
this.hashKeySerializer = StringRedisSerializer()
this.hashValueSerializer = StringRedisSerializer()
}
}
이 후 Service 단에서 redis의 데이터를 조회할 때 계속해서 역직렬화 오류가 발생했기에 계속해서 방법을 찾아가며 다양한 방법을 시도했었다.
마지막으로 시도한 방식이 바로 Service에서 직접 ObjectMapper를 이용해 JSON 형태를 바꿔주는 방법이였다.
override fun getResolutionRanking(): List<SimpleResolutionResponse> {
val resolutionRanking = redisTemplate.opsForList().range("ranking", 0, -1)
val objectMapper = ObjectMapper()
return resolutionRanking?.map {
objectMapper.readValue(it.toString(), SimpleResolutionResponse::class.java)
} ?: emptyList()
}
이 방법도 안되면 어떻게 해야 하나 막막했다. 별별 방법을 많이 시도했기 때문이였다.
이 때 발생한 오류 코드가 아래와 같다.
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'SimpleResolutionResponse': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (String)"SimpleResolutionResponse(title=string, category=string, likeCount=1)"; line: 1, column: 25]
어떻게 해결했나?
에러 메세지를 살펴보니 String형 데이터를 JSON으로 역직렬화 하는 부분에 있어서 오류가 발생한다고 한다.
응? 난 String형 데이터를 준 적이 없는데.... 혹시 it.toString() 이 부분이 문제인가? 하는 생각이 들었다.
혹시 몰라서 objectMapper 부분을 삭제하고 테스트 해 봤다.
그랬더니...

잘 작동한다!!
결론적으로 말하면 GenericJackson2JsonRedisSerializer는 아무 잘못 없었다.
계속 직렬화/역직렬화 부분에서 오류가 발생하다 보니 정말 여러 방법을 시도해 봤다.
하지만 버그를 잡기위해 다양한 방법을 시도한게 오히려 다른 버그를 낳게 된 것 같다.
A+B도 시도해보고 C+D도 시도해 봤는데 정답은 A+D였던 상황인것이다.
'캠프 개발일지' 카테고리의 다른 글
개발일지 - 16일차: 버그 해결 및 원인 분석(1) (2) | 2024.03.15 |
---|---|
개발일지 - 15일차: 목표 랭킹 알고리즘 수정 및 오류 직면 (2) | 2024.03.14 |
개발일지 - 14일차: 랭킹 시스템 구현 (1) | 2024.03.13 |
개발일지 - 9일차: 좋아요 기능 추가 (0) | 2024.03.06 |
개발일지 - 8일차: daily Check 추가 (4) | 2024.03.05 |