Jackson 을 이용한 object serializing, deserializing 에서, 프로퍼티의 값을 원하는대로 바꿔 사용할 수 있다.
1. 원본 프로퍼티에는 @JsonIgnore 를 지정한다.
2. serializing 에 사용될 값에는 @JsonProperty fun 을 사용한다.
3. deserializing 에 사용될 값에는 @set:JsonProperty 를 사용한다.
예:
Item 객체를 포함하는 MySomething 객체 인스턴스를 Json <-> Object 변환 시, Item 을 그대로 내보내기보다는 item 의 id 만을 내보내고, 받고 싶은 경우:
class MySomething {
@JsonIgnore
lateinit var item: Item
@JsonProperty("itemRef")
fun itemId() = item.id
@set:JsonProperty("itemRef")
lateinit var itemRef: String
}
* item: Item 프로퍼티에 lateinit 을 사용하는 이유:
serializing 에서는 val 를 사용해도 상관 없겠지만, deserializing 에서는 val 를 사용할 수 없다. Json 에서 이 프로퍼티는 다음과 같이 변환될 것인데, deserializing 에서 이걸 가지고 다시 Item 으로 변환할 수 없다.(따로 deserializer 를 정의하면 가능하겠지만 이는 논외로 한다.)
"itemRef":"<item_id>"
위의 이유로 deserializing 시에 item 프로퍼티는 초기화되지 못하여(위의 "itemRef" 는 itemRef: String 프로퍼티에 세팅된다.) val 사용 시 deserializing 에서의 인스턴스 생성 시점에 예외가 발생한다.
* itemRef: String 프로퍼티에 lateinit 을 사용하는 이유:
위와 비슷하다. itemRef 는 deserializing 을 위한 것으로, 이외의 상황에서 사용되진 않는다고 상정했기 때문에 평소에는 굳이 초기화할 필요 없도록 남겨두고 위해서이다. (val 를 사용하면 반드시 초기화해야 하고, json 변환이 필요하지 않은 상황에도 영향을 주게 된다.)
* fun itemId() 를 사용하는 이유:
아래와 같이 사용해도 serializing 시에 같은 결과가 나온다:
@get:JsonProperty("xxxRef")
val itemId = item.id
하지만 이렇게하면 deserializing 시에 item property not initialized exception 을 만나게 된다. 이는 코틀린에 관한 것인데, val 프로퍼티는 인스턴스 생성 과정에서 시점에 초기화가 이루어진다. val itemId 프로퍼티 초기화 시 item.id 를 참조하게 되는데, item 프로퍼티는 아직 초기화되지 못한 상태이다. 때문에 예외가 발생한다. 이를 방지하고자 fun 을 사용한다.
'기술 일반 > 일반' 카테고리의 다른 글
CLOB 컬럼 핸들링 중 인코딩 문제 (0) | 2019.03.08 |
---|---|
유니코드와 UTF-8, UTF-16 (0) | 2017.04.07 |