(この投稿は、以下に提供されるサンプルの回答を含む正規の質問であることを意図しています。)
を使用して、一部のJSONコンテンツをカスタムPOJOタイプに逆シリアル化しようとしていGson#fromJson(String, Class)
ます。
このコード
import com.google.gson.Gson;
public class Sample {
public static void main(String[] args) {
String json = "{\"nestedPojo\":[{\"name\":null, \"value\":42}]}";
Gson gson = new Gson();
gson.fromJson(json, Pojo.class);
}
}
class Pojo {
NestedPojo nestedPojo;
}
class NestedPojo {
String name;
int value;
}
フォロー例外をスローします
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:200)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:103)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:196)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.google.gson.Gson.fromJson(Gson.java:775)
at com.google.gson.Gson.fromJson(Gson.java:724)
at com.google.gson.Gson.fromJson(Gson.java:696)
at com.example.Sample.main(Sample.java:23)
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:387)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:189)
... 7 more
GsonがJSONテキストをPOJOタイプに適切に変換できないのはなぜですか?
例外メッセージの状態として
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 16 path $.nestedPojo
逆シリアル化中に、GsonはJSONオブジェクトを予期していましたが、JSON配列を見つけました。あるものから別のものに変換できなかったため、この例外をスローしました。
ここでは、JSON形式について説明します。つまり、オブジェクト、配列、文字列、数値null
、およびブール値のtrue
とを定義しfalse
ます。
Gson(およびほとんどのJSONパーサー)では、次のマッピングが存在します。JSON文字列はJavaにマップされますString
。JSON番号はJava Number
タイプにマップされます。JSON配列はCollection
型または配列型にマップされます。JSONオブジェクトは、Java Map
タイプ、または通常、カスタムPOJOタイプ(前述していません)にマップされます。null
はJavaにマッピングされnull
、ブール値はJava true
およびにマッピングされますfalse
。
Gsonは、提供されたJSONコンテンツを反復処理し、要求された対応する型に逆シリアル化しようとします。コンテンツが一致しないか、予期されたタイプに変換できない場合、対応する例外がスローされます。
あなたの場合、あなたは次のJSONを提供しました
{
"nestedPojo": [
{
"name": null,
"value": 42
}
]
}
ルートでは、nestedPojo
これは、JSON配列であるという名前のメンバーを含むJSONオブジェクトです。そのJSON配列には、単一の要素、2つのメンバーを持つ別のJSONオブジェクトが含まれています。以前に定義されたマッピングを考えると、このJSON nestedPojo
はsome Collection
またはarray型の名前のフィールドを持つJavaオブジェクトにマップすることが予想されます。その型は、name
およびという名前の2つのフィールドをvalue
それぞれ定義します。
しかし、あなたはあなたのPojo
タイプをフィールドを持つものとして定義しました
NestedPojo nestedPojo;
それは配列型でも型でもありませんCollection
。Gsonは、このフィールドに対応するJSONをデシリアライズできません。
代わりに、3つのオプションがあります。
予想されるタイプに一致するようにJSONを変更してください
{
"nestedPojo": {
"name": null,
"value": 42
}
}
Pojo
型Collection
または配列型を期待するように型を変更してください
List<NestedPojo> nestedPojo; // consider changing the name and using @SerializedName
NestedPojo[] nestedPojo;
NestedPojo
独自の解析ルールを使用して、カスタムデシリアライザを作成して登録します。例えば
class Custom implements JsonDeserializer<NestedPojo> {
@Override
public NestedPojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
NestedPojo nestedPojo = new NestedPojo();
JsonArray jsonArray = json.getAsJsonArray();
if (jsonArray.size() != 1) {
throw new IllegalStateException("unexpected json");
}
JsonObject jsonObject = jsonArray.get(0).getAsJsonObject(); // get only element
JsonElement jsonElement = jsonObject.get("name");
if (!jsonElement.isJsonNull()) {
nestedPojo.name = jsonElement.getAsString();
}
nestedPojo.value = jsonObject.get("value").getAsInt();
return nestedPojo;
}
}
Gson gson = new GsonBuilder().registerTypeAdapter(NestedPojo.class, new Custom()).create();
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加