web-dev-qa-db-ja.com

Gsonおよび配列を含むオブジェクトの配列の逆シリアル化

Gsonを使用して、Webサービスから返されたJSON文字列をデシリアライズしようとしています

構造はTypeDTO[]として返されます。

TypeDTOは次のようなものです

int id;
String name;
ArrayList<ItemDTO> items[] 

そしてItemDTOは

int id;
String name;
Boolean valid;

次のようにコードを呼び出すと

Gson gson = new Gson();
TypeDTO[] mytypes = (TypeDTO[]) gson.fromJson(reply, TypeDTO[].class);

オブジェクト内のすべてがヌルです

ただし、使用する場合

JSONArrayおよびJSONObjectを使用して、org.json jarからそれらを1つずつ引き出します。正常に機能し、それに応じてフィールドに入力されます。

私が間違っていることに関するアイデアはありますか? Gsonは非常に高速ですか?それとも、私はすでに働いているものに固執する方が良いですか?

ありがとう、デビッド

63
DavieDave

元の質問の例Javaデータ構造は、コメントのJSON構造の説明と一致しません。

JSONは次のように記述されます

「{object}の配列を持つ{objectの配列」」。

質問で説明されているタイプに関して、Gsonで簡単にデシリアライズするためにJSON構造に一致するJavaデータ構造に変換されたJSONは

「{ItemDTOオブジェクト}の配列を持つ{TypeDTOオブジェクトの配列”」。

しかし、質問で提供されるJavaデータ構造はこれではありません。代わりに

「{ItemDTOオブジェクト}の配列の配列を持つ{TypeDTOオブジェクトの配列”」。

2次元配列!= 1次元配列。

この最初の例は、Gsonを使用して、「{object}の配列と{object}の配列を持つ」JSON構造を単純に逆シリアル化およびシリアル化する方法を示しています。

input.jsonの内容:

[
  {
    "id":1,
    "name":"name1",
    "items":
    [
      {"id":2,"name":"name2","valid":true},
      {"id":3,"name":"name3","valid":false},
      {"id":4,"name":"name4","valid":true}
    ]
  },
  {
    "id":5,
    "name":"name5",
    "items":
    [
      {"id":6,"name":"name6","valid":true},
      {"id":7,"name":"name7","valid":false}
    ]
  },
  {
    "id":8,
    "name":"name8",
    "items":
    [
      {"id":9,"name":"name9","valid":true},
      {"id":10,"name":"name10","valid":false},
      {"id":11,"name":"name11","valid":false},
      {"id":12,"name":"name12","valid":true}
    ]
  }
]

Foo.Java:

import Java.io.FileReader;
import Java.util.ArrayList;

import com.google.gson.Gson;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class);
    System.out.println(gson.toJson(myTypes));
  }
}

class TypeDTO
{
  int id;
  String name;
  ArrayList<ItemDTO> items;
}

class ItemDTO
{
  int id;
  String name;
  Boolean valid;
}

この2番目の例では、代わりに実際に「{ItemDTOオブジェクト}の配列の配列を持つ{TypeDTOオブジェクトの配列」であるJSON構造を使用して、元々提供されたJavaデータ構造.

input.jsonの内容:

[
  {
    "id":1,
    "name":"name1",
    "items":
    [
      [
        {"id":2,"name":"name2","valid":true},
        {"id":3,"name":"name3","valid":false}
      ],
      [
        {"id":4,"name":"name4","valid":true}
      ]
    ]
  },
  {
    "id":5,
    "name":"name5",
    "items":
    [
      [
        {"id":6,"name":"name6","valid":true}
      ],
      [
        {"id":7,"name":"name7","valid":false}
      ]
    ]
  },
  {
    "id":8,
    "name":"name8",
    "items":
    [
      [
        {"id":9,"name":"name9","valid":true},
        {"id":10,"name":"name10","valid":false}
      ],
      [
        {"id":11,"name":"name11","valid":false},
        {"id":12,"name":"name12","valid":true}
      ]
    ]
  }
]

Foo.Java:

import Java.io.FileReader;
import Java.util.ArrayList;

import com.google.gson.Gson;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class);
    System.out.println(gson.toJson(myTypes));
  }
}

class TypeDTO
{
  int id;
  String name;
  ArrayList<ItemDTO> items[];
}

class ItemDTO
{
  int id;
  String name;
  Boolean valid;
}

残りの2つの質問について:

gsonは非常に高速ですか?

他の逆シリアル化/シリアル化APIとは比較されません。 Gsonは伝統的に amongstslowest でした。 Gsonの現在および次のリリースでは、パフォーマンスの大幅な改善が報告されていますが、これらの主張をサポートするための最新のパフォーマンステストデータは探していません。

とはいえ、Gsonがあなたのニーズに十分な速さであれば、JSONの逆シリアル化が非常に簡単になるので、おそらくそれを使用するのが理にかなっています。より良いパフォーマンスが必要な場合は、ジャクソンを使用する方が適切な場合があります。 Gsonの便利さの多く(おそらくすべて)を提供します。

それとも、私はすでに働いているものに固執する方が良いですか?

しません私はほとんどの場合、次のような簡単なコード行を1つ持っています

TypeDTO[] myTypes = gson.fromJson(new FileReader("input.json"), TypeDTO[].class);

...一度に1つのコンポーネントを1つのコンポーネントにマップするために必要な30行のコードよりも、簡単に複雑なデータ構造にデシリアライズします。

115

JSONデータが配列オブジェクトで始まる場合、このようにBeanクラスを使用します。それはあなたを助けます。

Users[] bean = gson.fromJson(response,Users[].class);

ユーザーは私のBeanクラスです。

応答は私のJSONデータです。

0
nagabrahmam