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

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());

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



답변

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);

도움이되기를 바랍니다.


답변

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

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;
    }

}


답변

객체 배열에서 수렴하려면

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());


답변

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


답변

이 게시물의 답변 중 일부는 유효하지만 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;
}


답변

[
      {
           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));


답변

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

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

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