[#35] 결제 스키마 재정의 & 예약 조회 페이지 개선 #36

Merged
pricelees merged 37 commits from refactor/#35 into main 2025-08-22 06:43:16 +00:00
2 changed files with 52 additions and 1 deletions
Showing only changes of commit af81260355 - Show all commits

View File

@ -1,6 +1,9 @@
package roomescape.common.config package roomescape.common.config
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonParser
import com.fasterxml.jackson.databind.*
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer
@ -9,6 +12,8 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer
import com.fasterxml.jackson.module.kotlin.kotlinModule import com.fasterxml.jackson.module.kotlin.kotlinModule
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
import roomescape.common.exception.CommonErrorCode
import roomescape.common.exception.RoomescapeException
import java.time.LocalDate import java.time.LocalDate
import java.time.LocalTime import java.time.LocalTime
import java.time.format.DateTimeFormatter import java.time.format.DateTimeFormatter
@ -20,6 +25,7 @@ class JacksonConfig {
fun objectMapper(): ObjectMapper = ObjectMapper() fun objectMapper(): ObjectMapper = ObjectMapper()
.registerModule(javaTimeModule()) .registerModule(javaTimeModule())
.registerModule(kotlinModule()) .registerModule(kotlinModule())
.registerModule(longIdModule())
private fun javaTimeModule(): JavaTimeModule = JavaTimeModule() private fun javaTimeModule(): JavaTimeModule = JavaTimeModule()
.addSerializer( .addSerializer(
@ -38,4 +44,35 @@ class JacksonConfig {
LocalTime::class.java, LocalTime::class.java,
LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm")) LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm"))
) as JavaTimeModule ) as JavaTimeModule
private fun longIdModule(): SimpleModule {
val simpleModule = SimpleModule()
simpleModule.addSerializer(Long::class.java, LongToStringSerializer())
simpleModule.addDeserializer(Long::class.java, StringToLongDeserializer())
return simpleModule
}
}
class LongToStringSerializer : JsonSerializer<Long>() {
override fun serialize(value: Long?, gen: JsonGenerator, serializers: SerializerProvider) {
if (value == null) {
gen.writeNull()
} else {
gen.writeString(value.toString())
}
}
}
class StringToLongDeserializer : JsonDeserializer<Long>() {
override fun deserialize(p: JsonParser, ctxt: DeserializationContext): Long? {
val text = p.text
if (text.isNullOrBlank()) {
return null
}
return try {
text.toLong()
} catch (_: NumberFormatException) {
throw RoomescapeException(CommonErrorCode.INVALID_INPUT_VALUE)
}
}
} }

View File

@ -52,4 +52,18 @@ class JacksonConfigTest(
}.message shouldContain "Text '$hour:$minute:$sec' could not be parsed" }.message shouldContain "Text '$hour:$minute:$sec' could not be parsed"
} }
} }
context("Long 타입은 문자열로 (역)직렬화된다.") {
val number = 1234567890L
val serialized: String = objectMapper.writeValueAsString(number)
val deserialized: Long = objectMapper.readValue(serialized, Long::class.java)
test("Long 직렬화") {
serialized shouldBe "$number"
}
test("Long 역직렬화") {
deserialized shouldBe number
}
}
}) })