简体   繁体   中英

Handle inconsistent API response with Retrofit

I'm facing an issue in new project. I'm connecting to API that could response two different data types in one response based on some server logic. I'm using Retrofit on Android and I was wondering if there's some "easy" way to handle that cases before retrofit object parse, eg. some kind of parser/serializer that would check what type has specific JSON field? I dunno.

Here are possible responses:

error response:

{
  "ReturnCode": "error",
  "ReturnCodeNumber": 444,
  "ReturnMessage": "Invalid Request",
  "ReturnData": ""
}

data response:

{
  "ReturnCode": "ok",
  "ReturnCodeNumber": 0,
  "ReturnMessage": "success",
  "ReturnData": [
    {

    }
  ]
}

Retrofit API request:

@FormUrlEncoded
@POST("url")
Observable<ApiResponse<List<Data>>> requestData()

API response class has exposed fields of above response and parameterized T for returnData .

So is it possible to somehow wrap it in some serializer class?

You will have to write custom deserializer or register a type adapter as explained in this -

https://sites.google.com/site/gson/gson-user-guide#TOC-Custom-Serialization-and-Deserialization

Try to do by using TypeAdapterFactory . Sample of that class as shown below.

public class ItemTypeAdapterFactory implements TypeAdapterFactory {
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
        final TypeAdapter<JsonElement> elementAdapter = gson.getAdapter(JsonElement.class);

        return new TypeAdapter<T>() {
            public void write(JsonWriter out, T value) throws IOException {
                delegate.write(out, value);
            }

            public T read(JsonReader in) throws IOException {
                JsonElement jsonElement = elementAdapter.read(in);
                if (jsonElement.isJsonObject()) {
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    if (jsonObject.has("data") && jsonObject.get("data").isJsonObject()) {
                        jsonElement = jsonObject.get("data");
                    }
                }
                return delegate.fromJsonTree(jsonElement);
            }
        }.nullSafe();
    }
}

And this Gson into RestAdapter

final Gson gson = new GsonBuilder().registerTypeAdapterFactory(new ItemTypeAdapterFactory()).create();
final Client client = new OkClient(new OkHttpClient());
final RestAdapter restAdapter = new RestAdapter.Builder().setClient(client).setLogLevel(RestAdapter.LogLevel.FULL).setConverter(new GsonConverter(gson)).setEndpoint(context.getString(R.string.base_url)).build();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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