2011-01-31 3 views
4

AndroidプロジェクトにGoogleのGSONを使用して、自分のWebサーバーからJSONをリクエストしたいと考えています。 JSONは...どちらかが返されますGSON:変換するオブジェクトの種類を知っていますか?

1)既知のタイプ(例えばの正常な応答:常にオンになります

{ 
    "id":1, 
    "username":"bob", 
    "created_at":"2011-01-31 22:46:01", 
    "PhoneNumbers":[ 
     { 
      "type":"home", 
      "number":"+1-234-567-8910" 
     }, 
     { 
      "type":"mobile", 
      "number":"+1-098-765-4321" 
     } 
    ] 
} 

2)不成功の応答:クラス「ユーザー」)下の同じ基本構造を使用します。

{ 
    "error":{ 
     "type":"Error", 
     "code":404, 
     "message":"Not Found" 
    } 
} 

私はGSONは上記errorキー/値ペアの有無に応じて、正しい型に変換したいと思います。私がこれを行うと考えることができる最も実用的な方法は次のとおりですが、より良い方法があれば私は興味があります。

final String response = client.get("http://www.example.com/user.json?id=1"); 
final Gson gson = new Gson(); 

try { 
    final UserEntity user = gson.fromJson(response, UserEntity.class); 
    // do something with user 
} catch (final JsonSyntaxException e) { 
    try { 
     final ErrorEntity error = gson.fromJson(response, ErrorEntity.class); 
     // do something with error 
    } catch (final JsonSyntaxException e) { 
     // handle situation where response cannot be parsed 
    } 
} 

最初のキャッチ状態では、私はキーerrorはJSONレスポンスに存在するかどうかをテストするかどうかはわかりませんので、これは、しかし実際には擬似コードです。だから私の質問は2倍だと思います:

  1. 私はキーの存在をテストし、それに基づいて解析する方法を決定するためにGSONを使用できますか?
  2. GSONで同様の状況にある他の人たちがこれをやっているのですか、それとも良い方法がありますか?

答えて

5

通常は、サーバーにJSONエラー応答とともに実際のエラーコードを返すことをお勧めします。次に、エラーコードを取得した場合はErrorEntity、応答コードを取得する場合はUserEntityとなります。明らかに、これはURLを文字列に変換するだけではなく、サーバーとの通信の詳細をもう少し扱う必要があります。それはどうですか?

つまり、別のオプションは、カスタム値JsonDeserializerと、値またはエラーのいずれかを返すクラスを使用することです。

public class ValueOrErrorDeserializer<V> implements JsonDeserializer<ValueOrError<V>> { 
    public ValueOrError<V> deserialize(JsonElement json, Type typeOfT, 
            JsonDeserializationContext context) { 
    JsonObject object = json.getAsJsonObject(); 
    JsonElement error = object.get("error"); 
    if (error != null) { 
     ErrorEntity entity = context.deserialize(error, ErrorEntity.class); 
     return ValueOrError.<V>error(entity); 
    } else { 
     Type valueType = ((ParameterizedType) typeOfT).getActualTypeArguments()[0]; 
     V value = (V) context.deserialize(json, valueType); 
     return ValueOrError.value(value); 
    } 
    } 
} 

あなたは、このような何かを行うことができると思います:

String response = ... 
ValueOrError<UserEntity> valueOrError = gson.fromJson(response, 
    new TypeToken<ValueOrError<UserEntity>>(){}.getType()); 
if (valueOrError.isError()) { 
    ErrorEntity error = valueOrError.getError(); 
    ... 
} else { 
    UserEntity user = valueOrError.getValue(); 
    ... 
} 

私はそのコードを試したことがない、と私はまだHTTPエラーコードを使用してお勧めしますが、それが与えますJsonDeserializerを使用してJSONの処理方法を決定する方法の例を示します。

+0

エラーコードの変更は、Webアプリケーションの設定方法が簡単でなければなりません。私は周りにおもちゃにして、結果のJSONの "エラー"キーを削除するか、上記のようなものを使用して私のためにうまくいくかどうかを把握する必要があります。あなたの詳細な回答には大変感謝しています。私は本当に感謝しています! –

+0

フォローアップのために、エラー応答が予想されるときは常にWebサーバーがHTTPステータス200を返していないことを確認しました。JSONエラー応答をカプセル化した「エラー」キーを含まないように変更しました。コード "、"メッセージ "を使用します。私はそれが望むようにすべてが今働いています。助けてくれてありがとう! –

+0

ほぼですが、JsonDeserializerはインターフェイスなので、実装する必要があります。拡張する必要はありません。 –

関連する問題