import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.KotlinModule
fun main(args: Array<String>) {
val testData = TestData("name", "code", false)
println(testData)
val objectMapper = ObjectMapper().registerModule(KotlinModule())
val res = objectMapper.writeValueAsString(testData)
println(res)
val data = objectMapper.readValue(res, TestData::class.java)
println(data)
}
data class TestData(
val name: String,
val aCode: String,
val isUse: Boolean
)
위의 코드를 실행하면 다음과 같은 에러가 발생합니다.
TestData(name=name, aCode=code, isUse=false)
{"name":"name","acode":"code","use":false}
Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `TestData` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
at [Source: (String)"{"name":"name","acode":"code","use":false}"; line: 1, column: 2]
at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67)
at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1589)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1055)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1297)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:326)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:159)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4202)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3205)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3173)
at MainKt.main(Main.kt:9)
Process finished with exit code 1
출력된 결과를 확인해 보면 TestData
의 데이터는 잘 들어갔지만 json으로 변환하는 과정에서 뭔가 문제가 생긴 것을 확인할 수 있습니다.
TestData(name=name, aCode=code, isUse=false)
{"name":"name","acode":"code","use":false}
aCode 는 acode 로, isUse 는 use 로 바뀌어서 변환되었습니다.
코틀린 코드를 자바 코드로 변환해보면
위와 같은 메소드를 생성하여 값을 반환하게 되어 있습니다.
jackson 의 코드를 살펴보면
properties 를 _props
의 값으로 주게되는데 이때
getACode
, isUse
메소드로 값을 가져온 결과가 acode, use 로 보여집니다.
aCode 의 경우
jackson 은 자바빈 네이밍 컨벤션을 따르며 그에 따라 객체 프로퍼티의 값을 가져옵니다.
그러므로 프로퍼티의 처음 두자리는 대문자로 시작하지 않는 것이 좋습니다
http://futuretask.blogspot.com/2005/01/java-tip-6-dont-capitalize-first-two.html
https://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/
isUse 의 경우
메소드에서 get
, set
, is
의 뒤에 오는 것을 json 의 키로 사용합니다.
따라서 isUse 가 use 로 변경된 것입니다.
그대로 사용하려면?
위의 두 경우에서 그대로 key 값이 들어가길 원한다면 @JsonProperty
를 사용합니다.
data class TestData(
val name: String,
@get:JsonProperty("aCode")
val aCode: String,
@get:JsonProperty("isUse")
val isUse: Boolean
)
getter
에 @JsonProperty
를 추가하고 사용할 이름을 입력합니다.
자바 코드에서 @JsonProperty
가 잘 적용된 것을 확인할 수 있습니다.
이제 다시 실행시키면 원하던 결과가 출력됩니다.
출처
Uploaded by Notion2Tistory v1.1.0