1

GSON カスタム シリアライゼーション機能を使用したい場合があります。

class Student{
   public String name;
   public int rollNumber;

   public Student(String name, int rollNumber){
        this.name = name;
        this.rollNumber = rollNumber;
   }

   public int getRollNumber(){
       return this.rollNumber;
   }

   public String getName(){
       return this.name;
   }


}
class School{

    public Student[] students;

    public School(Student[] students){
          this.students = students;
    }


   public Students[] getStudents(){
       return this.students;
   }

}

今私がするとき

private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create();

Student[] students = new Student[2];

students[0] = new Student("sam", 1);

students[1] = new Student("tom", 2);

School school = new School(students);

GSON.toJson(school);

次のような出力が得られます。

[{"name":"sam","rollNumer":1},{"name":"tom","rollNumer":2}]

しかし、私はそれが欲しい:

["student":{"name":"sam","rollNumer":1},"student":{"name":"tom","rollNumer":2}]

GSON カスタム シリアライゼーションを使用してこれを達成するにはどうすればよいですか?

私はこれこれを試しました。しかし、あまり役に立ちませんでした。

4

3 に答える 3

4

これ

["student":{"name":"sam","rollNumer":1},"student":{"name":"tom","rollNumer":2}]

は有効な JSON ではありません ( jsonlintなどのオンライン ツールを使用して自分で確認できます)。JSON 仕様の詳細を参照してください。

オブジェクトの定義:

オブジェクトは、名前と値のペアの順序付けられていないセットです。オブジェクトは { (左中かっこ) で始まり、} (右中かっこ) で終わります。各名前の後には : (コロン) が続き、名前と値のペアは , (コンマ) で区切られます。

配列の定義:

配列は、順序付けられた値のコレクションです。配列は [ (左角括弧) で始まり、] (右角括弧) で終わります。値は、(コンマ) で区切られます。

値の定義:

値は、二重引用符で囲まれた文字列、数値、true、false、null、またはオブジェクトまたは配列にすることができます。これらの構造は入れ子にすることができます。

出力では JSON 配列が定義されていますが、その配列内のオブジェクトが中かっこで適切に囲まれていません。正しい表現は次のようになります。

[{"student":{"name":"sam","rollNumer":1}}, {"student":{"name":"tom","rollNumer":2}}]

これは、この単純な Gson で生成できますTypeAdapter:

class StudentAdapter extends TypeAdapter<Student> {

    @Override
    public void write(final JsonWriter writer, final Student student)
            throws IOException {
        if (student == null) {
            writer.nullValue();
            return;
        }

        writer.beginObject();
        writer.name("student");
        writer.beginObject();
        writer.name("name");
        writer.value(student.getName());
        writer.name("rollNumber");
        writer.value(student.getRollNumber());
        writer.endObject();
        writer.endObject();
    }

    @Override
    public Student read(final JsonReader reader) throws IOException {
        if (reader.peek() == JsonToken.NULL) {
            reader.nextNull();
            return null;
        }

        final Student student = new Student();
        reader.beginObject();
        reader.nextName(); // discard the 'student' wrapper property
        reader.beginObject();
        while (reader.hasNext()) {
            final String attrName = reader.nextName();
            if ("name".equals(attrName)) {
                student.setName(reader.nextString());
            } else if ("rollNumber".equals(attrName)) {
                student.setRollNumber(reader.nextInt());
            }
        }
        reader.endObject();
        reader.endObject();

        return student;
    }
}

試験方法:

@Test
public void testWriteSchoolsAsJSONWithGsonAndCustomOutput()
        throws Exception {
    final Gson gson = new GsonBuilder().registerTypeAdapter(Student.class,
            new StudentAdapter()).create();

    Student[] students = new Student[2];
    students[0] = new Student("sam", 1);
    students[1] = new Student("tom", 2);

    School school = new School(students);

    final String outputJson = gson.toJson(school);
    System.out.println(outputJson);

    school = gson.fromJson(outputJson, School.class);
    System.out.println(school);
}

そして「関連する」出力:

{"students":[{"student":{"name":"sam","rollNumber":1}},{"student":{"name":"tom","rollNumber":2}}]}
于 2013-05-09T14:21:12.860 に答える
1

クラスに応じて正しい結果が得られます。

Student次のようなオブジェクトがあります。

{"name":"sam", "rollNumer":1}

簡単です.JSONのオブジェクト{}はプロパティ/値のペアで囲まれ、含まれています...

次に、JSON の配列は[]、コンマで区切られた多数のオブジェクト/値で囲まれ、含まれています。の配列があるためStudent、上記のようなオブジェクトがいくつかあり、コンマで区切られ、すべてが で囲まれてい[]ます。

そして、これはまさにあなたが持っているものです...すべてが理にかなっています!

"student"Studentオブジェクトの前に JSON を含める必要がありますが、この文字列は何"student"ですか? それはどこから来たのですか?実際、クラスのどこにもそのような文字列はありません。では、Gson (または任意のライブラリ) で JSON にどのように含めますか?

その文字列が本当に必要な場合は、何らかの方法でクラスに含める必要があります。私が思いついた最も簡単な方法はMap、次のように配列の代わりに a を使用することです。

public Map<String, Student> students;

次に、生徒を次のようにマップに追加します。

Student student = new Student("sam", 1);
students.put("student", student);
//add other students...

"student"これで、マップ内のキーとして学生に関連付けられた文字列が得られたことに注意してください...

これで、多かれ少なかれ希望する結果が得られますが、正確ではありません! {}全体がではなく で囲まれる[]ため、 aMapは配列ではなくオブジェクトであるため...

{"student":{"name":"sam","rollNumer":1}},{"student":{"name":"tom","rollNumer":2}}

残念ながら、あなたが望むとおりの応答を取得することはできません(私が理解している限り)...

于 2013-05-09T14:21:45.753 に答える
1

まず、 ["student":{"name":"sam","rollNumer":1},"student":{"name":"tom","rollNumer":2} として出力を取得することはできません] オブジェクトをオブジェクトの配列ではなくjsonに変換しようとしているためです。

あなたのコードを試してみましたが、次の出力が得られます

{"生徒":[{"名前":"サム","ロール番号":1},{"名前":"トム","ロール番号":2}]}

コードは次のとおりです。

    Student[] students = new Student[2];

    students[0] = new Student("sam", 1);

    students[1] = new Student("tom", 2);

    School school = new School(students);

    Gson gson = new GsonBuilder().disableHtmlEscaping().create();

    System.out.println(gson.toJson(school));
于 2013-05-09T13:06:33.953 に答える