简体   繁体   English

GSON:知道要转换为什么类型的对象?

[英]GSON: knowing what type of object to convert to?

I'm looking into using Google's GSON for my Android project that will request JSON from my web server. 我正在考虑将Google的GSON用于我的Android项目,该项目将从我的Web服务器请求JSON。 The JSON returned will be either... 返回的JSON将是......

1) A successful response of a known type (eg: class "User"): 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.) An unsuccessful response, which will always take on the same basic structure below. 2.)不成功的响应,它将始终采用相同的基本结构。

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

I'd like GSON to convert to the correct type depending on the existence of the error key/value pair above. 我希望GSON根据上面error键/值对的存在转换为正确的类型。 The most practical way I can think to do this is as follows, but I'm curious if there's a better way. 我能想到的最实用的方法如下,但我很好奇是否有更好的方法。

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
    }
}

This is really just pseudocode though, because in the first catch condition, I'm not sure how to test whether the key error exists in the JSON response. 这实际上只是伪代码,因为在第一个catch条件中,我不确定如何测试JSON响应中是否存在密钥error So I guess my question is twofold: 所以我想我的问题是双重的:

  1. Can I / how can I use GSON to test the existence of a key, and make a decision on how to parse based upon that? 我可以/我如何使用GSON来测试密钥的存在,并根据它来决定如何解析?
  2. Is this what others in a similar situation are doing with GSON, or is there a better way? 这是其他处于类似情况的人正在使用GSON,还是有更好的方法?

What you'd normally want to do is to have your server return an actual error code along with the JSON error response. 您通常要做的是让服务器返回实际的错误代码以及JSON错误响应。 Then you read the response as an ErrorEntity if you get an error code and as a UserEntity if you get 200. Obviously this requires a little more dealing with the details of communication with the server than just turning a URL in to a String, but that's how it is. 然后,如果你得到一个错误代码,你ErrorEntity响应读作UserEntity如果你得到200,你ErrorEntity它读作ErrorEntity 。显然,这需要更多地处理与服务器通信的细节,而不仅仅是将URL转换为String,但那是怎么样

That said, I believe another option would be to use a custom JsonDeserializer and a class that can return either a value or an error. 也就是说,我相信另一个选择是使用自定义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);
    }
  }
}

You'd then be able to do something like this: 然后你就可以做这样的事情:

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();
  ...
}

I haven't tried that code out, and I'd still recommend using the HTTP error code, but it gives you an example of how you can use a JsonDeserializer to decide what to do with some JSON. 我没有尝试过该代码,我仍然建议使用HTTP错误代码,但它给出了一个示例,说明如何使用JsonDeserializer来决定如何处理某些JSON。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM