refactor: JacksonConfig 모듈 분리

This commit is contained in:
이상진 2025-09-27 18:53:44 +09:00
parent bcaffb6718
commit 2506105c56
9 changed files with 952 additions and 931 deletions

View File

@ -0,0 +1,11 @@
plugins {
id("org.springframework.boot")
kotlin("plugin.spring")
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
testImplementation("io.kotest:kotest-runner-junit5:5.9.1")
}

View File

@ -1,4 +1,4 @@
package com.sangdol.roomescape.common.config package com.sangdol.common.config
import com.fasterxml.jackson.core.JsonGenerator import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind.DeserializationFeature import com.fasterxml.jackson.databind.DeserializationFeature
@ -23,6 +23,9 @@ class JacksonConfig {
companion object { companion object {
private val ISO_OFFSET_DATE_TIME_FORMATTER: DateTimeFormatter = private val ISO_OFFSET_DATE_TIME_FORMATTER: DateTimeFormatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX") DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX")
private val LOCAL_TIME_FORMATTER: DateTimeFormatter =
DateTimeFormatter.ofPattern("HH:mm")
} }
@Bean @Bean
@ -43,11 +46,11 @@ class JacksonConfig {
) )
.addSerializer( .addSerializer(
LocalTime::class.java, LocalTime::class.java,
LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm")) LocalTimeSerializer(LOCAL_TIME_FORMATTER)
) )
.addDeserializer( .addDeserializer(
LocalTime::class.java, LocalTime::class.java,
LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm")) LocalTimeDeserializer(LOCAL_TIME_FORMATTER)
) as JavaTimeModule ) as JavaTimeModule
private fun dateTimeModule(): SimpleModule { private fun dateTimeModule(): SimpleModule {

View File

@ -1,4 +1,4 @@
package com.sangdol.roomescape.common.config package com.sangdol.common.config
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.exc.InvalidFormatException import com.fasterxml.jackson.databind.exc.InvalidFormatException
@ -6,11 +6,15 @@ import io.kotest.assertions.throwables.shouldThrow
import io.kotest.core.spec.style.FunSpec import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.kotest.matchers.string.shouldContain import io.kotest.matchers.string.shouldContain
import java.time.* import java.time.LocalDate
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.OffsetDateTime
import java.time.ZoneOffset
class JacksonConfigTest( class JacksonConfigTest : FunSpec({
private val objectMapper: ObjectMapper = JacksonConfig().objectMapper()
) : FunSpec({ val objectMapper: ObjectMapper = JacksonConfig().objectMapper()
context("날짜는 yyyy-mm-dd 형식이다.") { context("날짜는 yyyy-mm-dd 형식이다.") {
val date = "2025-07-14" val date = "2025-07-14"

View File

@ -35,7 +35,6 @@ dependencies {
// Kotlin // Kotlin
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("io.github.oshai:kotlin-logging-jvm:7.0.3") implementation("io.github.oshai:kotlin-logging-jvm:7.0.3")
// Test // Test
@ -53,6 +52,9 @@ dependencies {
// etc // etc
implementation("org.apache.poi:poi-ooxml:5.2.3") implementation("org.apache.poi:poi-ooxml:5.2.3")
// submodules
implementation(project(":common:config"))
} }
tasks.jar { tasks.jar {

View File

@ -4,7 +4,9 @@ import org.springframework.boot.Banner
import org.springframework.boot.SpringApplication import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.autoconfigure.SpringBootApplication
@SpringBootApplication @SpringBootApplication(
scanBasePackages = ["com.sangdol.roomescape", "com.sangdol.common"]
)
class RoomescapeApplication class RoomescapeApplication
fun main(args: Array<String>) { fun main(args: Array<String>) {

View File

@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.node.ArrayNode import com.fasterxml.jackson.databind.node.ArrayNode
import com.fasterxml.jackson.databind.node.ObjectNode import com.fasterxml.jackson.databind.node.ObjectNode
import com.fasterxml.jackson.databind.node.TextNode import com.fasterxml.jackson.databind.node.TextNode
import com.sangdol.roomescape.common.config.JacksonConfig import com.sangdol.common.config.JacksonConfig
private const val MASK: String = "****" private const val MASK: String = "****"
private val SENSITIVE_KEYS = setOf("password", "accessToken", "phone") private val SENSITIVE_KEYS = setOf("password", "accessToken", "phone")

View File

@ -1,17 +1,17 @@
package com.sangdol.roomescape.common.log package com.sangdol.roomescape.common.log
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.sangdol.common.config.JacksonConfig
import com.sangdol.roomescape.auth.exception.AuthErrorCode
import com.sangdol.roomescape.auth.exception.AuthException
import io.kotest.core.spec.style.StringSpec import io.kotest.core.spec.style.StringSpec
import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldBe
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletRequest
import org.slf4j.MDC import org.slf4j.MDC
import com.sangdol.roomescape.auth.exception.AuthErrorCode
import com.sangdol.roomescape.auth.exception.AuthException
class ApiLogMessageConverterTest : StringSpec({ class ApiLogMessageConverterTest : StringSpec({
val converter = ApiLogMessageConverter(jacksonObjectMapper()) val converter = ApiLogMessageConverter(JacksonConfig().objectMapper())
val request: HttpServletRequest = mockk() val request: HttpServletRequest = mockk()
beforeTest { beforeTest {

View File

@ -1,6 +1,7 @@
package com.sangdol.roomescape.supports package com.sangdol.roomescape.supports
import com.fasterxml.jackson.module.kotlin.convertValue import com.sangdol.common.config.JacksonConfig
import com.sangdol.roomescape.common.exception.ErrorCode
import io.restassured.module.kotlin.extensions.Given import io.restassured.module.kotlin.extensions.Given
import io.restassured.module.kotlin.extensions.Then import io.restassured.module.kotlin.extensions.Then
import io.restassured.module.kotlin.extensions.When import io.restassured.module.kotlin.extensions.When
@ -10,8 +11,6 @@ import io.restassured.specification.RequestSpecification
import org.hamcrest.CoreMatchers.equalTo import org.hamcrest.CoreMatchers.equalTo
import org.springframework.http.HttpMethod import org.springframework.http.HttpMethod
import org.springframework.http.MediaType import org.springframework.http.MediaType
import com.sangdol.roomescape.common.config.JacksonConfig
import com.sangdol.roomescape.common.exception.ErrorCode
fun runTest( fun runTest(
token: String? = null, token: String? = null,
@ -103,10 +102,10 @@ object ResponseParser {
val objectMapper = JacksonConfig().objectMapper() val objectMapper = JacksonConfig().objectMapper()
inline fun <reified T> parseListResponse(response: List<LinkedHashMap<String, Any>>): List<T> { inline fun <reified T> parseListResponse(response: List<LinkedHashMap<String, Any>>): List<T> {
return response.map { objectMapper.convertValue<T>(it) } return response.map { objectMapper.convertValue(it, T::class.java) }
} }
inline fun <reified T> parseSingleResponse(response: LinkedHashMap<String, Any>): T { inline fun <reified T> parseSingleResponse(response: LinkedHashMap<String, Any>): T {
return objectMapper.convertValue<T>(response) return objectMapper.convertValue(response, T::class.java)
} }
} }