본문 바로가기

프로그래밍/Android

[Android] gson , 복합적인 요소의 파싱

간단히 예를 들어보자.

단일 string, string 배열 두가지 형태가 전달되는 경우

{
    "item":[
        {"name":"kim", "phone":"1234"},
        {"name":"park", "phone":["12345","67890"]}
    ]
}

 

POJO 클래스의 구성 자체에 문제가 생긴다.

public class Item implements Serializable {
    private static final long serialVersionUID = -11111L;

    public String name;

    // 어느거?
    public String phone;
    public List<String> phone;
}

 

이와 같은 경우 별도의 serializer, deserializer 를 구성해 주어야 한다.

public class Item implements Serializable {
    private static final long serialVersionUID = -11111L;

    public String name;
    
    
    // 별도로 파싱할 요소에 JsonAdapter 어노테이션을 붙여 해당 인터페이스를 정의해 준다.
    @JsonAdapter(ItemJsonAdapter.class)
    public List<String> phone;
    
    
    private static class ItemJsonAdapter implements JsonSerializer<List<String>>, JsonDeserializer<List<String>> {
    
        @Override
        public List<String> deserialize( JsonElement json, Type typeOfT, jsonDeserializationContext context) throws JsonParseException {
            List<String> result;
            
            // 입력 형식이 배열이면 그냥 파싱하고, 배열이 아닌 경우 String 으로 파싱해 배열로 만들어 준다.
            if( json.isJsonArray() ) {
                result = context.deserialize( json, typeOfT );
            } else {
                result = new ArrayList<>();
                result.add( context.deserialize( json, String.class));
            }
            return result;
        }
        
        @Override
        public JsonElement serialize(List<String> src, Type typeOfSrc, JsonSerializationContext context ) {
            if( src.size() == 1 ) {
                return context.serialize( src.get(0), String.class );
            } else {
                return context.serialize( src );
            }
        }
    }
}

 

간단한 테스트 코드

@Test
public void test_Message() {
    string json = "{\"item\":[{\"name\":\"kim\", \"phone\":\" .... 이하생략";
    try {
        Gson gson = new Gson();
        List<Item> items = gson.fromJson( json, Item.class );
        
        assertEquals( 1, items.get(0).phone.size() );
        assertEquals( 2, items.get(1).phobe.size() );
        
        String json2 = gson.toJson( items );
        assertNotNull( json2 );
        
     } catch( Exception e ) {
     }
}

 

Retrofit을 사용하는 경우

.addConverterFactory(GsonConverterFactory.create()) 를 사용하는 경우 자동으로 위 내용이 적용된다.

 

'프로그래밍 > Android' 카테고리의 다른 글

[Android] EGL : 4 - 안드로이드 렌더링  (2) 2020.03.02
[Android] EGL : 3 - 쉐이더  (0) 2020.03.02
[Android] EGL : 2 - 텍스처  (0) 2020.03.02
[Android] EGL : 1 - 기본 구성  (0) 2020.03.02
안드로이드 ndk 테스트 코드  (0) 2020.02.20
[Android] gradle android 빌드 구성  (0) 2019.09.17
[Android] ConstraintSet  (0) 2019.08.22
Gradle Kotlin, AndroidX 설정  (0) 2019.08.17
[Android] androidX Camera  (0) 2019.07.15
[Android] Retrofit  (0) 2019.04.11