본문 바로가기

개발중/Spring Boot & Redis

Spring Boot 2.x.x에서 3.x.x로 업그레이드 후 Redis에 Java 객체 저장 문제 발생

728x90
반응형


문제: 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을 활용해 깔끔하게 해결하면서, 애플리케이션의 세션 관리 기능을 원활하게 유지할 수 있게 되었습니다. 

이 경험은 비슷한 문제에 직면할 수 있는 다른 개발자들에게도 유용한 참고자료가 될 것입니다.


728x90
반응형