GSON에서의 범용 타입의 시리얼화 해제
Android 응용 프로그램에서 Json 역직렬화 구현에 문제가 있습니다(Gson 라이브러리 사용).
나는 이렇게 수업을 만들었다.
public class MyJson<T>{
public List<T> posts;
}
디시리얼라이제이션 콜은 다음과 같습니다.
public class JsonDownloader<T> extends AsyncTask<Void, Void, MyJson<T>> {
...
protected MyJson<T> doInBackground(Void... params) {
...
Reader reader = new InputStreamReader(content);
GsonBuilder gson = new GsonBuilder();
Type collectionType = new TypeToken<MyJson<T>>() {}.getType();
result = gson.create().fromJson(reader, collectionType);
...
}
}
문제는 콜 후 result.posts 목록에는 MyJson 객체가 아닌 LinkedTreeMap 객체의 배열(정확한 값을 사용하여 문제가 Diserialization)이 1개 포함되어 있다는 것입니다.T 대신 MyObject를 사용하면 모든 것이 정상적으로 실행되고 MyObject가 정확합니다.
그럼 커스텀 디시리얼라이저를 작성하지 않고 디시리얼라이제이션콜을 실장하는 방법이 있을까요?
다음 유형을 지정해야 합니다.T
비직렬화 당시.어떻게 할까요?List
의posts
만약의 경우에 만들어지다Gson
무엇을 알 수 없었다Type
인스턴스화할 수 있을까요?머무를 수 없다T
영원히.그래서, 당신은 타입을 제공하게 될 것이다.T
로서Class
파라미터를 지정합니다.
자, 이제 가정해 봅시다.posts
이었다String
당신은 직렬을 해제할 것이다.MyJson<String>
(또한 추가했습니다)String json
단순화를 위한 파라미터.reader
이전과 같이) :
doInBackground(String.class, "{posts: [\"article 1\", \"article 2\"]}");
protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {
GsonBuilder gson = new GsonBuilder();
Type collectionType = new TypeToken<MyJson<T>>(){}.getType();
MyJson<T> myJson = gson.create().fromJson(json, collectionType);
System.out.println(myJson.getPosts()); // ["article 1", "article 2"]
return myJson;
}
마찬가지로, 의 시리얼화를 해제하려면MyJson
의Boolean
물건들
doInBackground(Boolean.class, "{posts: [true, false]}");
protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {
GsonBuilder gson = new GsonBuilder();
Type collectionType = new TypeToken<MyJson<T>>(){}.getType();
MyJson<T> myJson = gson.create().fromJson(json, collectionType);
System.out.println(myJson.getPosts()); // [true, false]
return myJson;
}
나는 추측했다.MyJson<T>
예를 들면
public class MyJson<T> {
public List<T> posts;
public List<T> getPosts() {
return posts;
}
}
그래서, 만약 당신이 탈직렬화를 찾고 있다면List<MyObject>
다음과 같이 메서드를 호출합니다.
// assuming no Void parameters were required
MyJson<MyObject> myJson = doInBackground(MyObject.class);
해봤어?
gson.create().fromJson(reader, MyJson.class);
편집
이 게시물을 읽은 후, 당신은 다음을 사용하고 있는 것 같습니다.Type
정답입니다.나는 당신의 문제가 의 사용이라고 믿는다.T
자바에는 타입 삭제 기능이 있다는 것을 기억해야 합니다.즉, 실행 시 의 모든 인스턴스가T
로 대체되다Object
따라서 실행 시 GSON을 전달한 내용은MyJson<Object>
만약 당신이 이것을 콘크리트 수업으로 대신하려고 했다면<T>
효과가 있을 거라고 믿어요.
Google Gson - 목록 역직렬화 <class> 객체?(유형)
그래서 위의 답변은 나에게 효과가 없었습니다. 시행착오 끝에 제 코드는 이렇게 끝났습니다.
public class AbstractListResponse<T> {
private List<T> result;
public List<T> getResult() {
return this.result;
}
}
여기서 중요한 것은 왼쪽의 '< T >'를 포함한 메서드의 시그니처입니다.
protected <T> AbstractListResponse<T> parseAbstractResponse(String json, TypeToken type) {
return new GsonBuilder()
.create()
.fromJson(json, type.getType());
}
Gson을 호출하면 메서드는 범용 객체의 TypeToken을 수신합니다.
TypeToken<AbstractListResponse<MyDTO>> typeToken = new TypeToken<AbstractListResponse<MyDTO>>() {};
AbstractListResponse<MyDTO> responseBase = parseAbstractResponse(json, typeToken);
마지막으로 TypeToken은 MyDTO를 사용할 수도 있고 MyDTO만을 사용할 수도 있습니다.
나처럼 코틀린과 싸우고 있는 사람이라면, 난 이렇게 일할 수 있어.
val type = object : TypeToken<MyJson<MyObject>>() { }.type
val response = gson.fromJson<MyJson<MyObject>>(reader, type)
범용 함수를 호출하려면 콜사이트에서 함수 이름 뒤에 type 인수가 필요합니다(여기 참조).
gson 2.8.0 이상을 사용하는 경우 다음 방법을 사용할 수 있습니다.TypeToken#getParametized((Type rawType, Type... typeArguments))
예:
protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) {
GsonBuilder gson = new GsonBuilder();
Type collectionType = TypeToken.getParameterized(MyJson.class, type).getType();
MyJson<T> myJson = gson.create().fromJson(json, collectionType);
System.out.println(myJson.getPosts()); // [true, false]
return myJson;
}
당신 경우엔 이게 통할 것 같아요
의 답변을 사용하여 코틀린에서 (단, 사소한할 수 ). 코틀린에서는 을 알고 있습니다.BaseDB<T>
Table<T>
, 테이블에는 ''가 List<T>
fun parse(jsonString: String): Table<T> {
//this gets the class for the type T
val classT: Class<*> = (javaClass
.genericSuperclass as ParameterizedType).actualTypeArguments[0] as Class<*>
val type = TypeToken.getParameterized(Table::class.java, classT).type
return GsonHelper.gson.fromJson<Table<T>>(jsonString, type)
}
언급URL : https://stackoverflow.com/questions/18397342/deserializing-generic-types-with-gson
'programing' 카테고리의 다른 글
Angular & Express를 사용하여 사용자를 로그인하는 적절한 방법은 무엇입니까? (0) | 2023.03.27 |
---|---|
리모트 wp-admin이 localhost로 리다이렉트 되는 이유는 무엇입니까? (0) | 2023.03.27 |
스프링 보안 설정 - Http Security vs Web Security (0) | 2023.03.27 |
JsonObject 속성을 통해 반복 (0) | 2023.03.27 |
Jest와 효소의 차이점은 무엇입니까? (0) | 2023.03.27 |