문제: Spring Boot 2.x.x에서 3.x.x로 업그레이드 후 Redis에 Java 객체 저장 문제 발생
Spring Boot를 2.x.x 버전에서 3.x.x 버전으로 업그레이드하면서 AuthUser 객체의 직렬화 및 역직렬화 과정에서 문제가 발생했습니다.
업그레이드 이전에는 이러한 이슈가 없었으나, 새 버전에서는 AuthUser 객체를 Redis에 저장하고 불러오는 과정에서 역직렬화를 할 수 없다는 오류가 발생했습니다.
해결 방법: Jackson Mix-In과 ObjectMapper 설정
이 문제를 해결하기 위해, Jackson 라이브러리의 Mix-In 기능을 활용했습니다.
Mix-In을 사용하면 기존 클래스를 수정하지 않고도 직렬화 및 역직렬화 규칙을 적용할 수 있습니다.
AuthUser 클래스에 대한 Mix-In을 다음과 같이 정의했습니다:
public abstract class AuthUserMixin {
@JsonCreator
public AuthUserMixin(@JsonProperty("id") Long id,
@JsonProperty("email") String email,
@JsonProperty("name") String name) {}
}
위 Mix-In 정의는 AuthUser 객체가 직렬화 및 역직렬화될 때 필요한 필드를 명시적으로 지정합니다.
이를 통해 JSON으로부터 객체를 올바르게 생성할 수 있게 도와줍니다.
Redis 설정 업데이트
또한, Spring의 RedisTemplate와 함께 사용할 ObjectMapper를 설정하는 부분에 이 Mix-In을 등록했습니다.
ObjectMapper는 Spring Security와 관련된 모듈들을 불러오고, AuthUser에 대한 Mix-In을 추가하여 직렬화/역직렬화 규칙을 적용합니다.
private ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModules(SecurityJackson2Modules.getModules(this.loader));
mapper.addMixIn(AuthUser.class, AuthUserMixin.class);
return mapper;
}
@Bean
public RedisSerializer<Object> springSessionDefaultRedisSerializer() {
return new GenericJackson2JsonRedisSerializer(objectMapper());
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
RedisSerializer<Object> serializer = springSessionDefaultRedisSerializer();
redisTemplate.setHashValueSerializer(serializer);
redisTemplate.setValueSerializer(serializer);
return redisTemplate;
}
Jackson Mix-In에 대한 이해
Jackson Mix-In은 복잡한 직렬화 및 역직렬화 요구사항을 처리하는 데 유용한 기능입니다.
이 기능을 사용하여 클래스에 직접 어노테이션을 추가하지 않고도 필요한 직렬화 또는 역직렬화 동작을 제어할 수 있습니다.
Mix-In 기능은 특히 코드 변경 없이 외부 라이브러리나 수정할 수 없는 클래스에 대해 특정 직렬화 동작을 적용하고자 할 때 매우 유용합니다.
Mix-In의 작동 원리
Mix-In은 타깃 클래스에 대해 원하는 어노테이션을 "혼합"하여 적용합니다.
이는 원본 클래스를 변경하지 않고도 특정 직렬화/역직렬화 규칙을 적용할 수 있는 강력한 방법을 제공합니다.
Jackson은 Mix-In을 사용하여 타깃 클래스의 인스턴스를 직렬화하거나 역직렬화할 때 Mix-In에 명시된 어노테이션을 참조합니다.
Mix-In 클래스 정의
public abstract class MyClassMixIn {
@JsonIgnore
public int age; // 직렬화에서 이 필드를 제외합니다.
}
ObjectMapper에 Mix-In 등록
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(MyClass.class, MyClassMixIn.class);
이 설정을 통해 MyClass 객체를 직렬화할 때 age 필드는 JSON 결과에 포함되지 않습니다.
이러한 방식으로 다양한 직렬화 옵션을 클래스에 적용할 수 있으며, 이는 코드의 재사용성과 유지 관리의 용이성을 증가시킵니다.
결과 및 결론
이러한 변경을 통해 AuthUser 객체의 직렬화 및 역직렬화 문제를 성공적으로 해결할 수 있었습니다.
Spring Boot 3.x.x로의 업그레이드 과정에서 발생한 호환성 문제를 Jackson Mix-In을 활용해 깔끔하게 해결하면서, 애플리케이션의 세션 관리 기능을 원활하게 유지할 수 있게 되었습니다.
이 경험은 비슷한 문제에 직면할 수 있는 다른 개발자들에게도 유용한 참고자료가 될 것입니다.
'개발중 > Spring Boot & Redis' 카테고리의 다른 글
Spring Boot 3.x 및 Security 6.x를 이용한 중복 로그인 관리 방법 (0) | 2024.05.03 |
---|---|
Spring Boot와 Redis를 사용한 데이터 저장 및 관리 (0) | 2024.05.03 |
Spring boot 3.2.2 & Redis & GenericJackson2JsonRedisSerializer (0) | 2024.04.15 |
클래스 변경과 직렬화: Spring Redis 환경에서의 serialVersionUID 관리 (0) | 2023.11.17 |
로컬에서는 Spring Session, 배포에서는 Redis: 세션 저장소 분리 전략 (0) | 2023.09.20 |