Volley를 더 쉽고 강력하게, Volley Extensions 를 읽다 보니 Jackson이라는 JSON parser가 성능이 좋다는 말이 나와서 예제를 만들어 봤다.
(고수들은 왜 더 쉬운 예제를 만들어주지 않는 걸까? ㅠㅠ)
일단 http://susemi99.kr/3089 와 기본적인 설정은 같고 jackson-databind 만 추가됐다.
android { ... packagingOptions{ exclude 'META-INF/LICENSE' exclude 'META-INF/NOTICE' } dexOptions { javaMaxHeapSize "4g" //specify the heap size for the dex process preDexLibraries = false //delete the already predexed libraries } } dependencies { compile fileTree(include: ['*.jar'], dir: 'libs') compile 'com.navercorp.volleyextensions:volleyer:2.0.+' compile 'com.mcxiaoke.volley:library:1.0.+' compile 'com.fasterxml.jackson.core:jackson-databind:2.6.+' }
하나의 객체만 갖고 있을 때
이런 JSON 타입일 때는
{ "name":"title1", "url":"http://google.co.kr/1" }
파싱을 해서 넣어둘 클래스를 만들고
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties(ignoreUnknown = true) public class MyItem { @JsonProperty("name") // 이름이 같을 때는 굳이 안 써도 된다. public String name; public String url; }
.withTargetClass()에 추가해서 호출하면 된다.
private void callJackson1() { Volleyer.volleyer().get("http://test.susemi99.kr/jackson1.json") .withTargetClass(MyItem.class) .withListener(listener1) .execute(); } private Response.Listener<MyItem> listener1 = new Response.Listener<MyItem>() { @Override public void onResponse(MyItem item) { textResult.setText("==== jackson1 ====\n"); textResult.append(item.name + ", " + item.url); } };
같은 종류 객체의 배열일 때
같은 종류 여러 개가 오는 경우도 있다.
[ { "name":"title1", "url":"http://google.co.kr/1" }, { "name":"title2", "url":"http://google.co.kr/2" } ]
이럴 때는 MyItem[].class를 넣으면 된다.
private void callJackson2() { Volleyer.volleyer().get("http://test.susemi99.kr/jackson2.json") .withTargetClass(MyItem[].class) .withListener(listener2) .execute(); } private Response.Listener<MyItem[]> listener2 = new Response.Listener<MyItem[]>() { @Override public void onResponse(MyItem[] items) { textResult.setText("==== jackson2 ====\n"); for (MyItem item : items) { textResult.append(item.name + ", " + item.url + "\n"); } } };
배열 형태의 top element가 있을 때
올바른 형태라고 볼 수는 없지만, 최상위에 element가 있을 때도 있다.
이런 경우는 저 result가 필요가 없지만, 그래도 top이 아닐 때를 대비해서 적어 놓는다.
{ "result":[ { "name":"title1", "url":"http://google.co.kr/1" }, { "name":"title2", "url":"http://google.co.kr/2" }, { "name":"title3", "url":"http://google.co.kr/3" }] }
이런 경우는 한 번 더 감싸야 한다.
다른 방법도 있을 것 같은 느낌이긴 한데, 못 찾겠다 ;;;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; @JsonIgnoreProperties(ignoreUnknown = true) public class MyItems { @JsonProperty("result") public ArrayList<MyItem> items; }
호출하는 방법은 비슷하다.
private void callJackson3() { Volleyer.volleyer().get("http://test.susemi99.kr/jackson3.json") .withTargetClass(MyItems.class) .withListener(listener3) .execute(); } private Response.Listener<MyItems> listener3 = new Response.Listener<MyItems>() { @Override public void onResponse(MyItems myItems) { textResult.setText("==== jackson3 ====\n"); for (MyItem item : myItems.items) { textResult.append(item.name + ", " + item.url + "\n"); } } };
객체를 가진 top element가 있을 때
최상위에 element가 있고, 그 밑에 객체가 있는 변태 형태도 가능하다.
{ "result": { "name":"title1", "url":"http://google.co.kr/1" } }
이거를 위해 또 하나의 클래스를 만든다.
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; @JsonIgnoreProperties(ignoreUnknown = true) public class MyItemParent { @JsonProperty("result") public MyItem item; }
호출 방식도 크게 다르지 않다.
private void callJackson4() { Volleyer.volleyer().get("http://test.susemi99.kr/jackson4.json") .withTargetClass(MyItemParent.class) .withListener(listener4) .execute(); } private Response.Listener<MyItemParent> listener4 = new Response.Listener<MyItemParent>() { @Override public void onResponse(MyItemParent myItemParent) { textResult.setText("==== jackson4 ====\n"); textResult.append(myItemParent.item.name + ", " + myItemParent.item.url + "\n"); } };
느낀 점
확실히 일일이 파싱을 하는 것보다 편하다.
다만 굳이 클래스를 안 만들고 한 클래스 안에서 다 해도되는 경우라면 좀 번거로워질 수 있을 것 같다.
Download Source
source : https://github.com/susemi99/VolleyerJacksonSample
Convert to JSON
다시 JSON으로 돌리고 싶다면
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter(); String json = ow.writeValueAsString(item);
이렇게 하면 된다.
도움 받은 곳 : http://stackoverflow.com/a/15786175/1025379