1

サーバーの JSON 応答を GSON ライブラリで解析します。バックエンドの担当者から、「何らかの理由で JSON で変数の型を指定できない」と言われることがあります (古い php、やり方がわからない、などなど)。GSON は、そのオブジェクト モデルで強い型付けを好みます。そのため、オブジェクトを文字列として解析できません。

GSON 待機:

{
    "service":{
        "description":null,
        "name":"Base",
        "id":"4c7a90410529"
    }
}

しかし、それは(空のデータ)を取得します:

"service": ""

そして、私は得る

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1396

そのような応答を解析するためのベスト プラクティスは何ですか?

別の質問: オブジェクトを作成するにはどうすればよいですか? 時々整数または文字列として返される整数変数を認識できますか? 同じサーバー側の問題。

"data": "1"

また

"data": 1

私は知っています-Javaでは特定の型を使用する必要があります。しかし、時には譲歩する価値があります、
ありがとう

編集: Java 開発者の回答に基づく私のソリューション。
ServiceDeserializer クラスは、内部値に応じてすべてのオブジェクトを逆シリアル化します。

public class ServiceDeserializer implements JsonDeserializer<ServiceState>{

    @Override
    public ServiceState deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        String name = "";
        String uuid = "";
        String description = "";

        if (json.isJsonObject()) {
            JsonObject obj = json.getAsJsonObject();

            if (!obj.get("name").isJsonNull()) {
                name = obj.get("name").getAsString();
            }
            if (!obj.get("uuid").isJsonNull()) {
                uuid = obj.get("uuid").getAsString();
            }
            if (!obj.get("description").isJsonNull()) {
                description = obj.get("description").getAsString();
            }
        }
        return new ServiceState(name, uuid, description);
    }

}

そして、ServiceState の型アダプターを使用した GSON コンストラクター。

Gson gson = new GsonBuilder()
    .registerTypeAdapter(ServiceState.class, new ServiceDeserializer())
    .create();
4

4 に答える 4

0

あなたの json は無効であり、Json パーサーは構文的に正しくない json を解析できません:

   "service": {
        "description": null,
        "name": "Base",
        "id": "4c7a90410529"
    }

ここに記載されているように、中括弧でカプセル化する必要があります。

{
    "service": {
        "description": null,
        "name": "Base",
        "id": "4c7a90410529"
    }
}
于 2013-10-03T16:37:03.660 に答える
0

json 構造体が で囲まれています{}。あなたの応答にはそれが欠けているようです。文字列の先頭と末尾に and を手動で追加して、有効な json 構造にすることが{できます。}

これが完了したら、Gson を使用して json 応答を通常どおり解析できます。

そのような応答を解析するためのベスト プラクティスは何ですか?

十分な Json パーサーを使用してください。それだけで十分です。また、json 応答をレベルごとに手動で解析することを避けるために、応答とまったく同じ構造を表すクラスを作成するようにしてください。

于 2013-10-03T16:37:12.113 に答える
0

厳密に固執したい場合はgson、カスタムdeserializerを提供できます。serviceがベース文字列のプロパティであるか、json他の に埋め込まれていることがわかっているpropertyため、デシリアライザーを使用して、問題のあるコンポーネントを段階的に解析し、それに応じて処理できます。

 public class MyJsonDeserializer implements JsonDeserializer<YourParsedData> {

   @Override 
   public YourParsedData deserialize(final JsonElement je, final Type type, final JsonDeserialization Context jdc) throws JsonParseException
   {
      final JsonObject obj = je.getAsJsonObject(); //our original full json string
      final JsonElement serviceElement = obj.get("service");


     //here we provide the functionality to handle the naughty element. It seems emtpy string is returned as a JsonPrimitive... so one option
     if(serviceElement instanceOf JsonPrimitive)
     {
       //it was empty do something
     }

     return YourParsedData.create(); //provide the functionality to take in the parsed data
   }
 }

カスタム デシリアライザーは次のように呼び出されます。

 final Gson gson = new GsonBuilder().registerTypeAdapter(YourParsedData.class, new MyJsonDeserializer()).create();
 gson.fromJson("{service: ''}", YourParsedData.class);

私はこれらすべてを入力したので、構文を見逃していたら申し訳ありません。

于 2013-10-03T19:24:58.577 に答える