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
★★★★★★★★★★★★★★★와 달리Class
raw 수 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.class
java.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
'programing' 카테고리의 다른 글
VueJS Webpack 프로젝트에서 Modernizr을 사용하는 방법 (0) | 2022.08.18 |
---|---|
Vue.js에서 v-for를 사용하여 새 div를 동적으로 생성하는 방법 (0) | 2022.08.18 |
Vuex: 기능 범위 모듈의 알 수 없는 Getter (0) | 2022.08.18 |
vuex 작업이 false를 반환할 때 이상한 콘솔 오류 발생 (0) | 2022.08.18 |
C에서 스택 트레이스를 취득하려면 어떻게 해야 합니까? (0) | 2022.08.18 |