gson TypeToken 사용
clasa Box<T> {
public T item;
}
class Doll {
public int price;
public String concept;
}
class Food {
public int price;
public int sugar;
}
...
class Test {
@Test
public void test() throws Exception {
// json : {"item":{"price":800,"concept":"party"}}
Gson gson = new Gson();
// 이건 아주 잘 됨.
Box<Doll> box = gson.fromJson(json, new TypeToken<Box<Doll>>(){}.getType());
Assert.assertEquals("party", box.item.concept);
}
}
예를들어 위와 같은 상황이 있다.
Box 클래스에서 Item 클래스를 프로퍼티로 포함하고 있는 구조인데,
json 파싱을 통해 Box 클래스의 객체로 받고자 한다.
의도치 않게 다양한 삽질을 하게 되었는데 결과만 공유.
되는거 - TypeToken.getParameterized 활용
private <T> T convert(String json, Class<T> clazz) {
Box<T> response = gson.fromJson(json, TypeToken.getParameterized(Box.class, clazz).getType());
return response.item;
}
- 제너릭 타입을 많이 혹은 복잡하게 갖는 클래스라면, getParameterized 활용을 검토해보는 것도 좋을 것 같다.
망한거 - new TypeToken<A<B>>
- 실패 코드 1
// 이건 잘 되는 것 같지만..
// response.item 은 com.google.gson.internal.LinkedTreeMap 객체로 생성된다.
// 즉, TypeToken<Box<T>> 에서 T 를 제대로 넘기지 못하는 듯.
private <T> Box<T> convert(String json) {
Box<T> response = gson.fromJson(json, new TypeToken<Box<T>>(){}.getType());
return response;
}
- 실패 코드 2
private <T> T convert(String json) {
Box<T> response = gson.fromJson(json, new TypeToken<Box<T>>(){}.getType());
return response.item; // 여전히 com.google.gson.internal.LinkedTreeMap 타입임.
}
...
@Test
public void test() throws Exception {
...
Doll doll = convert(json); // 실패 발생!
...
}
- 오류
java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to com.kong.Doll
- 원인은 이거를 참고.
https://stackoverflow.com/questions/20773850/gson-typetoken-with-dynamic-arraylist-item-type
'dev' 카테고리의 다른 글
텔레그램 챗봇 만들기 - 1. 챗봇 플랫폼 고르기 (0) | 2018.02.22 |
---|---|
무료 클라우드 서버 살펴보기 - ncloud toastcloud aws (0) | 2018.02.18 |
cygwin을 알아보자 (0) | 2018.02.13 |
bithumb api 테스트 해보기 - public api 편 (0) | 2018.02.12 |
elastic search query string (0) | 2018.02.12 |