2011-01-31 149 views
4

我正在研究使用谷歌的GSON为我的Android项目,将从我的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 
    } 
} 

这其实只是伪代码,但因为在第一个catch条件,我不知道如何测试的关键error是否存在于JSON响应。所以我想我的问题是双重的:

  1. 我可以/我怎么能用GSON来测试一个密钥的存在,并根据这个来决定如何解析?
  2. 这是别人在类似的情况下与GSON做的事,还是有更好的办法?

回答

5

你通常想要做的是让你的服务器的JSON错误响应一起返回的实际错误代码。然后你读取响应为ErrorEntity,如果你得到一个错误代码和一个UserEntity如果你得到200显然,这需要更多一点的处理与服务器不仅仅是在为String转动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中的“错误”键或使用类似上面的类似的方法对我来说会更好。非常感谢您的详细解答,我非常感谢! – 2011-01-31 07:03:41

相关问题