๐Ÿ’ป ๊ฐœ๋ฐœ ์ผ์ง€/SpringBoot

[SpringBoot] CustomJsonDeserializer ๊ตฌํ˜„ํ•˜๊ธฐ (String to List<Object>)

์ ์ด 2023. 1. 12. 18:44
๋ฐ˜์‘ํ˜•

์œ„์™€ ๊ฐ™์€ ํ˜•ํƒœ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜

๊ธฐ๋Œ€ํ•œ ๊ฐ์ฒด ํ˜•์‹์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

Payload(id = "...", payload = List(Map("..." to "...")) 

 

์•„๋ž˜ ์ฝ”๋“œ๋กœ ํŒŒ์‹ฑ ์ง„ํ–‰

/* build.gradle.kts */
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")

/* parsing logic */
jacksonObjectMapper().readValue(msg, PayLoad::class.java)

 

ํ•˜์ง€๋งŒ 

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<java.util.Map<java.lang.String,java.lang.Object>>` from String value (token `JsonToken.VALUE_STRING`)

 

์ด๋ ‡๊ฒŒ ํŒŒ์‹ฑ์—๋Ÿฌ๊ฐ€ ๋–จ์–ด์ง„๋‹ค ใ… ใ… 

 

์—ฌ๋Ÿฌ ์‚ฝ์งˆ์„ ํ•ด๋ณด๋‹ˆ, 

ํ˜„์žฌ๋Š” payload value๊ฐ’์ด String ๊ทธ ์ž์ฒด๋กœ ๋“ค์–ด์˜ค๋Š” ์ค‘์ด์—ˆ๋‹ค.

 

์ฆ‰, ์œ„๊ฐ€ ์•„๋‹ˆ๋ผ

์ด๋Ÿฐ ํ˜•์‹์ด์–ด์•ผ List์™€ Map์„ ์ •ํ™•ํžˆ ์ธ์‹ ํ•  ์ˆ˜ ์žˆ๋‹ค.


๋งŒ์•ฝ, Request๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค๋ฉด ์ธ์‹ํ•  ์ˆ˜ ์žˆ๋„๋ก JsonDeserializer๋ฅผ ๊ตฌํ˜„ํ•˜์ž!

 

์šฐ์„  ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ , JsonDeserializer๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค. ์ด๋•Œ ์ œ๋„ค๋ฆญ ํƒ€์ž…์€ ์ž์‹ ์ด ์ตœ์ข…์ ์œผ๋กœ ์–ป๊ณ ์žํ•˜๋Š” ๊ฐ์ฒด ํƒ€์ž…์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค!

ํ˜„์žฌ์˜ ๊ฒฝ์šฐ List<Map<?, ?> ํ˜•์‹์„ ์–ป๊ณ ์ž ํ•˜๋ฏ€๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ์ž‘์„ฑ

class PayloadDeserializer: JsonDeserializer<List<Map<String, Any?>>>() 

 

๊ทธ๋Ÿฌ๋ฉด ์ธํ…”๋ฆฌ์ œ์ด๊ฐ€ ์ž๋™์œผ๋กœ overrideํ•  ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•ด์ค€๋‹ค.

์ „๋‹ฌ๋ฐ›์€ String์€ JsonParser์— text๋กœ ์กด์žฌํ•˜๊ณ  ์žˆ๋‹ค. 

 

ํ˜„์žฌ๋Š” Text๋ฅผ ํ•œ๋ฒˆ ๋” ํŒŒ์‹ฑ ํ•ด์ฃผ๊ณ  ์ด๋ฅผ List<Map<>> ํ˜•ํƒœ๋กœ ์บ์ŠคํŒ…ํ•œ ๊ฐ’์„ ๋ฐ›๋„๋ก ํ•˜์˜€๋‹ค. 

override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): List<Map<String, Any?>> {
    val listString = jacksonObjectMapper().readValue(p?.text, List::class.java)
    return listString as List<Map<String, Any?>>
}

 

์™„์„ฑ๋œ Deserializer๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

class PayloadDeserializer: JsonDeserializer<List<Map<String, Any?>>>() {
    override fun deserialize(p: JsonParser?, ctxt: DeserializationContext?): List<Map<String, Any?>> {
        val listString = jacksonObjectMapper.readValue(p?.text, List::class.java)
        return listString as List<Map<String, Any?>>
    }
}

 

์ด์ œ ํ•ด๋‹น ํ•„๋“œ์— ์ ์šฉ์‹œํ‚จ๋‹ค.

@JsonDeserialize(using = PayloadDeserializer::class) 

์–ด๋…ธํ…Œ์ด์…˜๋งŒ ๋ถ™์—ฌ์ฃผ๋ฉด ๋œ๋‹ค!

data class PayloadRequest (
    val footprintId: String,
    @JsonDeserialize(using = PayloadDeserializer::class)
    val payload: List<Map<String, Any?>>
)

 

์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•˜๋ฉด, ์•„์ฃผ ๊น”๋”ํ•˜๊ฒŒ ์›ํ•˜๋Š” ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค!!!!!

๋ฐ˜์‘ํ˜•