programing

Gson을 사용하여 List 개체를 역직렬화하시겠습니까?

kingscode 2022. 8. 18. 21:41
반응형

Gson을 사용하여 List 개체를 역직렬화하시겠습니까?

Google Gson을 통해 목록 개체를 전송하고 싶은데 일반 유형을 역직렬화하는 방법을 모르겠습니다.

이것을 보고 시도한 것(BalusC의 답변):

MyClass mc = new Gson().fromJson(result, new List<MyClass>() {}.getClass());

에서 " new"라는List<MyClass>() {}의 메서드스텁이 퀵픽스를 사용하면 20개가 넘는 메서드 스텁이 생성됩니다.

더 쉬운 해결책이 있을 거라고 확신하지만, 찾을 수 없을 것 같아요!

이제 이런 게 있어요.

Type listType = new TypeToken<List<MyClass>>() {}.getType();

MyClass mc = new Gson().fromJson(result, listType);

저는 지만음음, 음음음음음음음 the the the the the the the the the the the the the the the the 에서 다음과 같은 .fromJson 표시:

java.lang.NullPointerException
at org.apache.harmony.luni.lang.reflect.ListOfTypes.length(ListOfTypes.java:47)
at org.apache.harmony.luni.lang.reflect.ImplForType.toString(ImplForType.java:83)
at java.lang.StringBuilder.append(StringBuilder.java:203)
at com.google.gson.JsonDeserializerExceptionWrapper.deserialize(JsonDeserializerExceptionWrapper.java:56)
at com.google.gson.JsonDeserializationVisitor.invokeCustomDeserializer(JsonDeserializationVisitor.java:88)
at com.google.gson.JsonDeserializationVisitor.visitUsingCustomHandler(JsonDeserializationVisitor.java:76)
at com.google.gson.ObjectNavigator.accept(ObjectNavigator.java:106)
at com.google.gson.JsonDeserializationContextDefault.fromJsonArray(JsonDeserializationContextDefault.java:64)
at com.google.gson.JsonDeserializationContextDefault.deserialize(JsonDeserializationContextDefault.java:49)
at com.google.gson.Gson.fromJson(Gson.java:568)
at com.google.gson.Gson.fromJson(Gson.java:515)
at com.google.gson.Gson.fromJson(Gson.java:484)
at com.google.gson.Gson.fromJson(Gson.java:434)

는 잡는다JsonParseExceptions ★★★★★★★★★★★★★★★★★」result는 늘이 아닙니다.

listType디버거를 사용하여 다음 정보를 얻습니다.

  • list Type
    • args = ListOfTypes
      • list = null
      • resolvedTypes = Type[ 1 ]
    • loader = PathClassLoader
    • ownerType0 = null
    • ownerTypeRes = null
    • rawType = Class (java.util.ArrayList)
    • rawTypeName = "java.util.ArrayList"

...getClass호출이 제대로 작동하지 않았습니다.안해주 주실? ???

Gson 사용자 가이드를 확인했습니다.범용 유형을 Json으로 구문 분석할 때 발생하는 런타임 예외에 대해 설명합니다.위 예시와 같이 "잘못"(위에는 표시되지 않음)을 실행했지만 예외는 전혀 발생하지 않았습니다.그래서 사용자 가이드에 제시된 대로 시리얼화를 변경했습니다.하지만 도움이 되진 않았어

편집:

해결했습니다. 아래 답변을 참조하십시오.

일반 수집을 역직렬화하는 방법:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

...

Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> yourClassList = new Gson().fromJson(jsonArray, listType);

해 주셨기 이 코멘트가 어떻게 있는지 .TypeToken이치노 ★★★new TypeToken<...>() {}.getType() 타임유형사이)을합니다.< ★★★★★★★★★★★★★★★★★」>합니다.java.lang.reflect.Type★★★★★★★★★★★★★★★와 달리Classraw 수 raw(원래형)는 raw(원래)는 raw(원래) 유형입니다.Type오브젝트는 범용 타입의 파라미터화된 인스턴스화를 포함하여 Java 언어의 모든 타입을 나타낼 수 있습니다.

TypeToken클래스 자체에 퍼블릭컨스트럭터가 없습니다.직접 작성하면 안 되기 때문입니다. 서브클래스를 어나니머스 서브클래스{}(미국의)

, 「」는TypeToken 수 없다, 할 없다)new TypeToken<List<T>>() {}.getType() 파라미터의 " " " " 입니다.T

상세한 것에 대하여는, 클래스의 메뉴얼을 참조해 주세요.

또 다른 방법은 어레이를 유형으로 사용하는 것입니다.예를 들어 다음과 같습니다.

MyClass[] mcArray = gson.fromJson(jsonString, MyClass[].class);

이렇게 하면 Type 객체에 대한 번거로움이 없어집니다.또, 정말로 리스트가 필요한 경우는, 다음의 방법으로 어레이를 리스트로 변환할 수 있습니다.

List<MyClass> mcList = Arrays.asList(mcArray);

IMHO 이게 훨씬 더 읽기 쉬워요.

리스트로 (의 제한을 해 주세요.Arrays.asList() ), 하다, 하다, 하다, 하다, 하다.

List<MyClass> mcList = new ArrayList<>(Arrays.asList(mcArray));

Gson 2.8 이후 다음과 같은 util 함수를 생성할 수 있습니다.

public <T> List<T> getList(String jsonArray, Class<T> clazz) {
    Type typeOfT = TypeToken.getParameterized(List.class, clazz).getType();
    return new Gson().fromJson(jsonArray, typeOfT);
}

사용 예:

String jsonArray = ...
List<User> user = getList(jsonArray, User.class);

이 투고를 참조해 주세요.GSON 인수로서의 Java 타입

내게 더 좋은 해결책이 있어목록 래퍼 클래스는 래퍼에 정확한 유형의 목록을 저장할 수 있도록 합니다.

public class ListOfJson<T> implements ParameterizedType
{
  private Class<?> wrapped;

  public ListOfJson(Class<T> wrapper)
  {
    this.wrapped = wrapper;
  }

  @Override
  public Type[] getActualTypeArguments()
  {
      return new Type[] { wrapped };
  }

  @Override
  public Type getRawType()
  {
    return List.class;
  }

  @Override
  public Type getOwnerType()
  {
    return null;
  }
}

그 후, 코드는 다음과 같이 간단합니다.

public static <T> List<T> toList(String json, Class<T> typeClass)
{
    return sGson.fromJson(json, new ListOfJson<T>(typeClass));
}

같은 결과를 얻기 위한 또 다른 방법인 셈이죠가독성을 위해 사용합니다.

이 읽기 어려운 문장 대신:

Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> list = new Gson().fromJson(jsonArray, listType);

개체 목록을 확장하는 빈 클래스를 만듭니다.

public class YourClassList extends ArrayList<YourClass> {}

JSON을 해석할 때 사용합니다.

List<YourClass> list = new Gson().fromJson(jsonArray, YourClassList.class);

Kotlin의 경우:

import java.lang.reflect.Type
import com.google.gson.reflect.TypeToken
...
val type = object : TypeToken<List<T>>() {}.type

또는 다음과 같은 유용한 기능을 제공합니다.

fun <T> typeOfList(): Type {
    return object : TypeToken<List<T>>() {}.type
}

다음으로, 사용 방법:

val type = typeOfList<YourMagicObject>()
public static final <T> List<T> getList(final Class<T[]> clazz, final String json)
{
    final T[] jsonToObject = new Gson().fromJson(json, clazz);

    return Arrays.asList(jsonToObject);
}

예:

getList(MyClass[].class, "[{...}]");

원래 질문에 대한 답변이므로 doc_180의 답변을 수락했습니다만, 만약 누군가가 다시 이 문제에 직면하게 되면 질문의 나머지 절반도 답하겠습니다.

제가 설명한 NullPointerError는 목록 자체와는 관계가 없으며 내용과는 관련이 없습니다.

"MyClass" 클래스에는 "no args" 생성자가 없었고 슈퍼 클래스 생성자도 없었습니다.MyClass와 그 슈퍼클래스에 심플한 "MyClass()" 컨스트럭터를 추가하자 doc_180의 제안대로 List serialization과 deserialization을 포함한 모든 것이 정상적으로 동작했습니다.

다음은 동적으로 정의된 유형으로 작동하는 솔루션입니다.은 '어레이드'를 입니다.Array.newInstance().

public static <T> List<T> fromJsonList(String json, Class<T> clazz) {
    Object [] array = (Object[])java.lang.reflect.Array.newInstance(clazz, 0);
    array = gson.fromJson(json, array.getClass());
    List<T> list = new ArrayList<T>();
    for (int i=0 ; i<array.length ; i++)
        list.add(clazz.cast(array[i]));
    return list; 
}

나는 한 가지 가능성을 더하고 싶다.TypeToken을 사용하지 않고 json 객체 배열을 ArrayList로 변환하려면 다음과 같이 진행합니다.

json 구조가 다음과 같은 경우:

{

"results": [
    {
        "a": 100,
        "b": "value1",
        "c": true
    },
    {
        "a": 200,
        "b": "value2",
        "c": false
    },
    {
        "a": 300,
        "b": "value3",
        "c": true
    }
]

}

학급 구성은 다음과 같습니다.

public class ClassName implements Parcelable {

    public ArrayList<InnerClassName> results = new ArrayList<InnerClassName>();
    public static class InnerClassName {
        int a;
        String b;
        boolean c;      
    }
}

다음과 같이 해석할 수 있습니다.

Gson gson = new Gson();
final ClassName className = gson.fromJson(data, ClassName.class);
int currentTotal = className.results.size();

이제 className 객체의 각 요소에 액세스할 수 있습니다.

Gson의 '유형' 클래스에 대한 이해는 예 2를 참조하십시오.

예 1: 이 deserilizeResturant에서는 Employee [ ]어레이를 사용하여 자세한 내용을 확인했습니다.

public static void deserializeResturant(){

       String empList ="[{\"name\":\"Ram\",\"empId\":1},{\"name\":\"Surya\",\"empId\":2},{\"name\":\"Prasants\",\"empId\":3}]";
       Gson gson = new Gson();
       Employee[] emp = gson.fromJson(empList, Employee[].class);
       int numberOfElementInJson = emp.length();
       System.out.println("Total JSON Elements" + numberOfElementInJson);
       for(Employee e: emp){
           System.out.println(e.getName());
           System.out.println(e.getEmpId());
       }
   }

예 2:

//Above deserilizeResturant used Employee[] array but what if we need to use List<Employee>
public static void deserializeResturantUsingList(){

    String empList ="[{\"name\":\"Ram\",\"empId\":1},{\"name\":\"Surya\",\"empId\":2},{\"name\":\"Prasants\",\"empId\":3}]";
    Gson gson = new Gson();

    // Additionally we need to se the Type then only it accepts List<Employee> which we sent here empTypeList
    Type empTypeList = new TypeToken<ArrayList<Employee>>(){}.getType();


    List<Employee> emp = gson.fromJson(empList, empTypeList);
    int numberOfElementInJson = emp.size();
    System.out.println("Total JSON Elements" + numberOfElementInJson);
    for(Employee e: emp){
        System.out.println(e.getName());
        System.out.println(e.getEmpId());
    }
}

Kotlin을 사용하면 모든 사용자 지정 직렬화 가능 유형에 대한 범용 MutableList 유형을 얻을 수 있습니다.

private fun <T : Serializable> getGenericList(
    sharedPreferences: SharedPreferences,
    key: String,
    clazz: KClass<T>
): List<T> {
    return sharedPreferences.let { prefs ->
        val data = prefs.getString(key, null)
        val type: Type = TypeToken.getParameterized(MutableList::class.java, clazz.java).type
        gson.fromJson(data, type) as MutableList<T>
    }
}

이 함수를 호출할 수 있습니다.

getGenericList.(sharedPrefObj, sharedpref_key, GenericClass::class)

case 가 없는 My case @uncatched_exceptions를 .List.classjava.lang.reflect.Type:

String jsonDuplicatedItems = request.getSession().getAttribute("jsonDuplicatedItems").toString();
List<Map.Entry<Product, Integer>> entries = gson.fromJson(jsonDuplicatedItems, List.class);

이 경우 Gson Utils lib를 작성했습니다.이것을 maven central repository에 추가합니다.

Map<String, SimpleStructure> expected = new HashMap<>();
expected.put("foo", new SimpleStructure("peperoni"));

String json = GsonUtils.writeValue(expected);

Map<String, SimpleStructure> actual = GsonUtils.readMap(json, String.class, SimpleStructure.class);

kays1의 답변은 마음에 들었지만 실행할 수 없었습니다.그래서 그의 콘셉트로 나만의 버전을 만들었어요.

public class JsonListHelper{
    public static final <T> List<T> getList(String json) throws Exception {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        Type typeOfList = new TypeToken<List<T>>(){}.getType();
        return gson.fromJson(json, typeOfList);
    }
}

사용방법:

List<MyClass> MyList= JsonListHelper.getList(jsonArrayString);

언급URL : https://stackoverflow.com/questions/5554217/deserialize-a-listt-object-with-gson

반응형