[IDLE-561] 웹소켓 직렬화/역직렬화 이슈 해결 및 채팅방 생성 케이스 보완#268
Conversation
Walkthrough이 PR에서는 채팅방 생성 로직, 검색 기능, 웹소켓 설정, 및 데이터 직렬화 관련 클래스에 변경이 이루어졌습니다.
Changes
Sequence Diagram(s)sequenceDiagram
participant U as 사용자
participant CRS as ChatRoomService
participant CRR as ChatRoomRepository
U->>CRS: create(carerId, centerId) 호출
CRS->>CRR: findByCarerIdAndCenterId(carerId, centerId) 호출
alt 채팅방 존재
CRR-->>CRS: 기존 ChatRoom 반환
CRS-->>U: 기존 ChatRoom ID 반환
else 채팅방 부재
CRS->>CRR: 새 ChatRoom 저장 호출
CRR-->>CRS: 새 ChatRoom ID 반환
CRS-->>U: 새 ChatRoom ID 반환
end
Tip ⚡💬 Agentic Chat (Pro Plan, General Availability)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (2)
idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/config/WebSocketConfig.kt (1)
39-47: 애플리케이션 전체에서 일관된 ObjectMapper 설정 확인 필요이 클래스에서 ObjectMapper 구성을 변경했지만, 애플리케이션의 다른 부분에서도 동일한 설정이 필요할 수 있습니다. 애플리케이션 전체에서 ObjectMapper 구성이 일관되게 유지되는지 확인하는 것이 좋습니다. 가능하다면 Bean으로 등록하여 재사용하는 것을 고려해보세요.
- val objectMapper = ObjectMapper() - .registerModule(JavaTimeModule()) - .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) - - val converter = MappingJackson2MessageConverter() - converter.objectMapper = objectMapper + // 애플리케이션 전체에서 사용할 ObjectMapper Bean 주입받기 + @Autowired + private lateinit var objectMapper: ObjectMapper + + // 메서드 내에서 + val converter = MappingJackson2MessageConverter() + converter.objectMapper = objectMapper관련하여 애플리케이션에서 ObjectMapper를 Bean으로 등록하는 구성 클래스를 만들 수 있습니다:
@Configuration class JacksonConfig { @Bean fun objectMapper(): ObjectMapper { return ObjectMapper() .registerModule(JavaTimeModule()) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) } }idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/chat/ReadChatMessagesReqeust.kt (1)
7-10: JSON 직렬화/역직렬화 문제 해결을 위한 적절한 어노테이션Kotlin 데이터 클래스에
@JsonCreator와@JsonProperty어노테이션을 추가하여 웹소켓 통신 시 발생할 수 있는 직렬화/역직렬화 문제를 해결한 것은 좋은 접근입니다. PR 목적에 부합하는 변경입니다.다만, 9번 줄에서
@JsonProperty("opponentId")와val opponentId사이에 공백이 누락되어 있습니다. 가독성을 위해 공백을 추가하는 것이 좋겠습니다.- @JsonProperty("opponentId")val opponentId: UUID + @JsonProperty("opponentId") val opponentId: UUID
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
idle-application/src/main/kotlin/com/swm/idle/application/chat/domain/ChatRoomService.kt(1 hunks)idle-domain/src/main/kotlin/com/swm/idle/domain/chat/repository/ChatRoomRepository.kt(1 hunks)idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/config/WebSocketConfig.kt(2 hunks)idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/chat/ReadChatMessagesReqeust.kt(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Build and analyze
🔇 Additional comments (8)
idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/config/WebSocketConfig.kt (5)
3-5: 적절한 직렬화를 위한 필수 모듈 임포트 추가JavaTimeModule 및 SerializationFeature를 가져오는 임포트를 추가한 것은 LocalDateTime과 같은 Java 시간 클래스의 직렬화/역직렬화 문제를 해결하기 위한 적절한 접근 방식입니다.
35-35: 메서드 시그니처 변경에 대한 주의메서드 매개변수 타입을
MutableList<MessageConverter>에서MutableList<MessageConverter?>로 변경하셨네요.
이는 null 가능한 MessageConverter를 허용하기 위한 것으로 보이지만, 코드에서 null 체크를 하지 않고 있습니다. 실제로 null 값이 전달될 가능성이 있는지 확인해보세요.
37-37: 더 깔끔한 코드 스타일 적용이전의
also블록 대신 직접 할당 방식을 사용하여 코드가 더 간결해졌습니다.
39-41: LocalDateTime 직렬화 문제 해결ObjectMapper에 JavaTimeModule을 등록하고 WRITE_DATES_AS_TIMESTAMPS를 비활성화한 것은 LocalDateTime의 직렬화 문제를 효과적으로 해결합니다. 이로써 날짜가 타임스탬프가 아닌 ISO 형식으로 올바르게 직렬화됩니다.
43-47: 코드 구조 개선이전 구현에서 인라인
also블록을 사용하던 방식에서 명시적인 설정 방식으로 변경하여 코드의 가독성과 유지보수성이 향상되었습니다.idle-domain/src/main/kotlin/com/swm/idle/domain/chat/repository/ChatRoomRepository.kt (1)
14-14: 적절한 레포지토리 메서드 추가
findByCarerIdAndCenterId메서드 추가는 Spring Data JPA 메서드 명명 규칙을 잘 따르고 있으며, 채팅방 생성 로직 개선에 필요한 적절한 기능입니다. 반환 타입이ChatRoom?로 설정되어 있어 해당 조합의 채팅방이 없을 경우를 고려하고 있습니다.idle-application/src/main/kotlin/com/swm/idle/application/chat/domain/ChatRoomService.kt (1)
13-16: 채팅방 생성 로직 개선기존에 항상 새로운 채팅방을 생성하던 로직에서, 동일한 carerId와 centerId 조합의 채팅방이 이미 존재하는지 확인 후 존재하면 해당 채팅방 ID를 반환하도록 변경한 것은 중복 채팅방 생성을 방지하는 좋은 개선입니다. Elvis 연산자(
?:)를 사용하여 간결하게 구현한 점도 좋습니다.idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/chat/ReadChatMessagesReqeust.kt (1)
3-4: Jackson 어노테이션 적절히 추가웹소켓 직렬화/역직렬화 이슈 해결을 위해 필요한 Jackson 어노테이션을 추가한 것은 적절합니다.
|



1. 📄 Summary
2. 💡 알게된 점, 궁금한 점
Java에서 record를 DTO로 사용할 땐 WebSocket에서 직렬화/역직렬화 문제가 발생하지 않았지만,
Kotlin의 data class를 사용하니 역직렬화 오류가 발생했습니다.
이는 기본적으로 자바의 Record는 기본 생성자를 컴파일 시점에서 생성해주지만,
Kotlin의 data class는 기본 생성자(default constructor) 가 명시적으로 존재하지 않으며!
null-safety, val/var, companion 등 다양한 기능을 포함해서 동작합니다.
이에따라 Jackson이 역직렬화 시 적절한 생성자나 프로퍼티 주입 정보를 찾지 못해 예외를 발생시키게 됐습니다.
따라서 @JsonCreator와 @JsonProperty를 사용해 생성자 기반 역직렬화 방식으로 명확히 지정해주거나,
jackson-module-kotlin을 반드시 등록해줘야 안정적으로 처리할 수 있다는 걸 알게 되었습니다.
Summary by CodeRabbit
New Features
Refactor