Gson으로 JSON 배열을 구문 분석하는 방법


84

JSON 배열을 구문 분석하고 gson을 사용하고 싶습니다. 첫째, JSON 출력을 기록 할 수 있으며 서버가 클라이언트에 명확하게 응답합니다.

내 JSON 출력은 다음과 같습니다.

 [
      {
           id : '1',
           title: 'sample title',
           ....
      },
      {
           id : '2',
           title: 'sample title',
           ....
     },
      ...
 ]

구문 분석을 위해이 구조를 시도했습니다. 단일 arrayArrayList모든 JSONArray 에 의존하는 클래스 .

 public class PostEntity {

      private ArrayList<Post> postList = new ArrayList<Post>();

      public List<Post> getPostList() { 
           return postList; 
      }

      public void setPostList(List<Post> postList) { 
           this.postList = (ArrayList<Post>)postList; 
      } 
 }

수업 후 :

 public class Post {

      private String id;
      private String title;

      /* getters & setters */
 }

gson no error, no warning and no log를 사용하려고 할 때 :

 GsonBuilder gsonb = new GsonBuilder();
 Gson gson = gsonb.create();

 PostEntity postEnt;
 JSONObject jsonObj = new JSONObject(jsonOutput);
 postEnt = gson.fromJson(jsonObj.toString(), PostEntity.class);

 Log.d("postLog", postEnt.getPostList().get(0).getId());

무엇이 잘못 되었나요? 어떻게 해결할 수 있나요?

답변:


248

JSONArray직접 구문 분석 할 수 Post있으며 PostEntity한 번 더 클래스 를 래핑 할 필요가 없으며 새로운 JSONObject().toString()것도 필요하지 않습니다 .

Gson gson = new Gson();
String jsonOutput = "Your JSON String";
Type listType = new TypeToken<List<Post>>(){}.getType();
List<Post> posts = gson.fromJson(jsonOutput, listType);

도움이되기를 바랍니다.


PostEntity 클래스를 삭제하고 대신 스 니펫을 시도했습니다. 여전히 변하지 않습니다. 감사.
Ogulcan Orhan 2011

마침내 정확하고 효율적으로 작동했습니다. 다시 한번 감사드립니다.
Ogulcan Orhan 2011

안녕하세요. 중첩 된 json 배열 데이터를 다음과 같이 구문 분석하는 방법 .... [{ "firstName": "Bidhan", "lastName": "Chatterjee"}, [{ "type": "personal", "number": "09832209761" }, { "type": "fax", "number": "91-342-2567692"}]]
KK_07k11A0585

TypeToken을 사용하면 이점이 있습니까? 내 테스트에서 gson은 TypeToken을 사용하지 않고 List <Object> 필드를 처리하는 것 같습니다.
greg7gkb

이것은 나를 위해 정말 helpfull입니다
bhavesh kaila

6

좀 더 일반적인 방법으로 객체 배열을 구문 분석하는 방법을 찾고있었습니다. 내 공헌은 다음과 같습니다.

CollectionDeserializer.java:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;

public class CollectionDeserializer implements JsonDeserializer<Collection<?>> {

    @Override
    public Collection<?> deserialize(JsonElement json, Type typeOfT,
            JsonDeserializationContext context) throws JsonParseException {
        Type realType = ((ParameterizedType)typeOfT).getActualTypeArguments()[0];

        return parseAsArrayList(json, realType);
    }

    /**
     * @param serializedData
     * @param type
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> ArrayList<T> parseAsArrayList(JsonElement json, T type) {
        ArrayList<T> newArray = new ArrayList<T>();
        Gson gson = new Gson();

        JsonArray array= json.getAsJsonArray();
        Iterator<JsonElement> iterator = array.iterator();

        while(iterator.hasNext()){
            JsonElement json2 = (JsonElement)iterator.next();
            T object = (T) gson.fromJson(json2, (Class<?>)type);
            newArray.add(object);
        }

        return newArray;
    }

}

JSONParsingTest.java:

public class JSONParsingTest {

    List<World> worlds;

    @Test
    public void grantThatDeserializerWorksAndParseObjectArrays(){

        String worldAsString = "{\"worlds\": [" +
            "{\"name\":\"name1\",\"id\":1}," +
            "{\"name\":\"name2\",\"id\":2}," +
            "{\"name\":\"name3\",\"id\":3}" +
        "]}";

        GsonBuilder builder = new GsonBuilder();
        builder.registerTypeAdapter(Collection.class, new CollectionDeserializer());
        Gson gson = builder.create();
        Object decoded = gson.fromJson((String)worldAsString, JSONParsingTest.class);

        assertNotNull(decoded);
        assertTrue(JSONParsingTest.class.isInstance(decoded));

        JSONParsingTest decodedObject = (JSONParsingTest)decoded;
        assertEquals(3, decodedObject.worlds.size());
        assertEquals((Long)2L, decodedObject.worlds.get(1).getId());
    }
}

World.java:

public class World {
    private String name;
    private Long id;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

}

@Miere 나는 이것이 JsonArray에서 List <World>로 어떻게 변환되는지 이해하지 못한다
ARK

기본적으로 GSON 역 직렬화 프로세스 중에 발견 된 모든 Collection에 대해 CollectionDeserializer를 사용합니다. CollectionDeserializer는 컬렉션의 일반 매개 변수를 통해 어떤 클래스가 역 직렬화해야하는 컬렉션의 개체 저장소를 나타내는 지 추론합니다. 귀하의 질문에 대한 답변이 되었기를 바랍니다. 여전히 의문이 있으시면 [gmail.com의 miere00]으로 저에게 연락하십시오.
Miere

안녕하세요 @Miere,이 솔루션은 원래 질문을 처리하지 않습니다. JSONParsingTest는 내부에 배열이있는 객체입니다. CollectionDeserializer를 사용하여 개체에 래핑 된 배열이 아닌 배열 만 구문 분석하는 방법은 무엇입니까?
zkon

5

객체 배열에서 수렴하려면

Gson gson=new Gson();
ElementType [] refVar=gson.fromJson(jsonString,ElementType[].class);

포스트 유형으로 변환하려면

Gson gson=new Gson();
Post [] refVar=gson.fromJson(jsonString,Post[].class);

객체 목록으로 읽으려면 TypeToken을 사용할 수 있습니다.

List<Post> posts=(List<Post>)gson.fromJson(jsonString, 
                     new TypeToken<List<Post>>(){}.getType());

ArrayList <Post>는 어떻습니까?
무루

3
Type listType = new TypeToken<List<Post>>() {}.getType();
List<Post> posts = new Gson().fromJson(jsonOutput.toString(), listType);

6
이것이 질문에 답할 수는 있지만 그 방법이나 이유를 설명 할 수있는 컨텍스트는 제공하지 않습니다. 답을 설명하기 위해 한두 문장을 추가해보십시오.
brandonscript

3

이 게시물의 답변 중 일부는 유효하지만 TypeToken을 사용하여 Gson 라이브러리는 응용 프로그램에 대한 비현실적인 유형의 Tree 객체를 생성합니다.

그것을 얻으려면 배열을 읽고 배열 내부의 객체를 하나씩 변환해야했습니다. 물론이 방법이 가장 빠르지는 않으며 어레이가 너무 크면 사용하지 않는 것이 좋지만 저에게는 효과적이었습니다.

프로젝트에 Json 라이브러리를 포함해야합니다. Android에서 개발하는 경우 다음이 포함됩니다.

/**
 * Convert JSON string to a list of objects
 * @param sJson String sJson to be converted
 * @param tClass Class
 * @return List<T> list of objects generated or null if there was an error
 */
public static <T> List<T> convertFromJsonArray(String sJson, Class<T> tClass){

    try{
        Gson gson = new Gson();
        List<T> listObjects = new ArrayList<>();

        //read each object of array with Json library
        JSONArray jsonArray = new JSONArray(sJson);
        for(int i=0; i<jsonArray.length(); i++){

            //get the object
            JSONObject jsonObject = jsonArray.getJSONObject(i);

            //get string of object from Json library to convert it to real object with Gson library
            listObjects.add(gson.fromJson(jsonObject.toString(), tClass));
        }

        //return list with all generated objects
        return listObjects;

    }catch(Exception e){
        e.printStackTrace();
    }

    //error: return null
    return null;
}

3
[
      {
           id : '1',
           title: 'sample title',
           ....
      },
      {
           id : '2',
           title: 'sample title',
           ....
     },
      ...
 ]

이 출력에 대한 Easy 코드 확인

 Gson gson=new GsonBuilder().create();
                List<Post> list= Arrays.asList(gson.fromJson(yourResponse.toString,Post[].class));

1

다음 코드를 사용하여 Kotlin에서 쉽게이 작업을 수행 할 수 있습니다.

val fileData = "your_json_string"
val gson = GsonBuilder().create()
val packagesArray = gson.fromJson(fileData , Array<YourClass>::class.java).toList()

기본적으로, 당신은 단지 제공 할 필요가 ArrayYourClass객체.


PrettyPrinting을 사용하는 이유는 무엇입니까?
Antroid 2011

내가 ^^ 제거하는 것을 잊었다 @antroid
xarlymg89

0

Type 객체 를 사용하지 않고도 List 값을 얻을 수 있습니다 .

EvalClassName[] evalClassName;
ArrayList<EvalClassName> list;
evalClassName= new Gson().fromJson(JSONArrayValue.toString(),EvalClassName[].class);
list = new ArrayList<>(Arrays.asList(evalClassName));

나는 그것을 테스트했고 작동하고 있습니다.


0

코 틀린 :

val jsonArrayString = "['A','B','C']"

val gson = Gson()

val listType: Type = object : TypeToken<List<String?>?>() {}.getType()

val stringList : List<String> = gson.fromJson(
                            jsonArrayString,
                            listType)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.