Manually analyze part of the answer when using Retrofit

I work with a REST API that returns a JSON document that starts as follows and includes a โ€œcollectionโ€ of elements with string identifiers of type โ€œABCโ€. Pay attention to the "routes" field, which contains a series of fields "ABC", "ABD", "ABE", etc. However, the routes are not presented as an array in json, so all of these

{ "status":true, "page":1, "per_page":500, "total_count":1234, "total_pages":8, "total_on_page":500, "routes":{ "ABC":[ { "value":22313, <......> 

I use Retrofit, and the problem is that the route field is not an array (although conceptually this is true) and Retrofit / Gson require me to create a model object for routes with field vars abc, abd, etc. this is not practical as the data changes. For various reasons, changing the server API is difficult, so I'm looking for work on this Android client.

I believe these are the parameters:

  • Intercept the JSON document before it gets to Gson, and adjust the document, perhaps with a custom Gson parser or by intercepting an HTTP response.

  • Bypass JSON parsing and get a JSON document from Retrofit (I still have to figure out how to do this or if possible)

  • Use some Retrofit features. I do not know how to display field names in a collection.

I would appreciate help, especially if there is a quick and easy way to resolve this.

+5
source share
2 answers

It turns out that by default, using Gons to use Gson makes it easy to add a custom deserializer to handle the part of the JSON document that was the problem.

 RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(ApiDefinition.BASE_URL) .setConverter(getGsonConverter()) .build(); public Converter getGsonConverter() { Gson gson = new GsonBuilder() .registerTypeAdapter(RouteList.class, new RouteTypeAdapter()) .create(); return new GsonConverter(gson); } public class RouteTypeAdapter implements JsonDeserializer<RouteList> { @Override public RouteList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { Gson gson = new Gson(); RouteList routeList = new RouteList(); JsonObject jsonObject = json.getAsJsonObject(); for (Map.Entry<String,JsonElement> elementJson : jsonObject.entrySet()){ RouteList wardsRoutes = gson.fromJson(elementJson.getValue().getAsJsonArray(), RouteList.class); routeList.addAll(wardsRoutes); } return routeList; } } 
+8
source

After calling RestService, do not use the model name as an argument, you should use the default Response class from the retrofit library.

RestService Method

 @FormUrlEncoded @POST(GlobalVariables.LOGIN_URL) void Login(@Field("email") String key, @Field("password") String value, Callback<Response> callback); 

Call Method in Action

 getService().Login(email, password, new MyCallback<Response>(context, true, null) { @Override public void failure(RetrofitError arg0) { // TODO Auto-generated method stub UtilitySingleton.dismissDialog((BaseActivity<?>) context); System.out.println(arg0.getResponse()); } @Override public void success(Response arg0, Response arg1) { String result = null; StringBuilder sb = null; InputStream is = null; try { is = arg1.getBody().in(); BufferedReader reader = new BufferedReader(new InputStreamReader(is)); sb = new StringBuilder(); String line = null; while ((line = reader.readLine()) != null) { sb.append(line + "\n"); result = sb.toString(); System.out.println("Result :: " + result); } } catch (Exception e) { e.printStackTrace(); } } }); 
+2
source

Source: https://habr.com/ru/post/1203612/


All Articles