web-dev-qa-db-ja.com

POJOのArrayListをシリアル化するGsonの問題

シリアル化のニーズにsimpleXMLを使用することを計画していましたが、何か新しいことを学ぶためにJSONを試してみることにしました。

これは、Gson 1.7.1を使用してテストPOJOのArrayListをシリアル化しようとするために使用しているコードです。

注:コードを簡素化するために、文字列 "s"のリーダー/ライターを削除しました。

package test;

import Java.io.IOException;
import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.List;

import com.google.gson.Gson;

public class TestGsonSerialDeserialList {
    public static void main(String[] args) throws IOException{
        Gson gson = new Gson();

        //Make Serial 
        String s;
        List<TestObject> list = Collections.synchronizedList(new ArrayList<TestObject>() );
        list.add(new TestObject());
        list.add(new TestObject());

        s = gson.toJson(list, ArrayList.class);
        System.out.println(s);

        //Eat Serial
        List<TestObject> list2 = Collections.synchronizedList(gson.fromJson(s, ArrayList.class) );
        System.out.println(list2.get(0) );
        System.out.println(list2.get(1) );
    }
}

私が得る出力は次のとおりです。

[{"objectID":1,"i1":12345,"name":"abcdefg","s":["a","b","c"]},{"objectID":2,"i1":12345,"name":"abcdefg","s":["a","b","c"]}]
Java.lang.Object@5c74c3aa
Java.lang.Object@75d9fd51

私の初心者の目にはこれは正しいようです。オブジェクトのDeSerializedリストには、TestObjectのIシリアル化ではなく、基本的なオブジェクトのみが含まれます。誰でも私にこの仕事をするために何かできることを説明できますか?

編集:

テストに修正:ColinDに感謝

package test;

import Java.io.FileInputStream;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStreamReader;
import Java.io.OutputStreamWriter;
import Java.io.Reader;
import Java.io.Writer;
import Java.lang.reflect.Type;
import Java.util.ArrayList;
import Java.util.Collections;
import Java.util.List;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class TestGsonSerialDeserialList {
    public static void main(String[] args) throws IOException{
        System.out.println("--- Serialize / Deserialize Started ---");
        String fileName = "json\\testList.json";

        Gson gson = new Gson();
        Type listOfTestObject = new TypeToken<List<TestObject>>(){}.getType();

        //Make Serial 
        Writer osWriter = new OutputStreamWriter( new FileOutputStream(fileName));
        List<TestObject> list = Collections.synchronizedList(new ArrayList<TestObject>() );
        list.add(new TestObject());
        list.add(new TestObject());
        list.add(new TestObject());
        list.add(new TestObject());
        gson.toJson(list, osWriter);
        osWriter.close();


        //Eat Serial
        Reader isReader = new InputStreamReader( new FileInputStream((fileName) ) );
        List<TestObject> list2 = Collections.synchronizedList(
            (List<TestObject>)gson.fromJson(isReader, listOfTestObject) 
        );
        isReader.close();
        System.out.println(list2.get(0) );
        System.out.println(list2.get(1) );
        System.out.println(list2.get(2) );
        System.out.println(list2.get(3) );
        System.out.println("--- Serialize / Deserialize Ended ---");
    }
}

出力:

--- Serialize / Deserialize Started ---
ID#: 1, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@95c083
ID#: 2, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@6791d8c1
ID#: 3, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@182d9c06
ID#: 4, i1: 12345, name: abcdefg, s[]: [Ljava.lang.String;@5a5e5a50
--- Serialize / Deserialize Ended ---

EDIT2:

正直なところ、理由はわかりませんが、TestObjectに埋め込まれた単純なString []をArrayListに置き換えると、正しくシリアル化が開始されました。

--- Serialize / Deserialize Started ---
ID#: 1, i1: 12345, name: abcdefg, s[]: [a, b, c]
ID#: 2, i1: 12345, name: abcdefg, s[]: [a, b, c]
ID#: 3, i1: 12345, name: abcdefg, s[]: [a, b, c]
ID#: 4, i1: 12345, name: abcdefg, s[]: [a, b, c]
--- Serialize / Deserialize Ended ---
68
RogueDeus

使用しているListの特定のジェネリックタイプ(またはそれで使用するジェネリックタイプ)に関するGson情報を提供する必要があります。特にJSONを逆シリアル化する場合、各配列要素を逆シリアル化するオブジェクトのタイプを決定できるようにするために、その情報が必要です。

Type listOfTestObject = new TypeToken<List<TestObject>>(){}.getType();
String s = gson.toJson(list, listOfTestObject);
List<TestObject> list2 = gson.fromJson(s, listOfTestObject);

これは Gsonユーザーガイド に記載されています。

163
ColinD