Convertidor personalizado para reequipamiento

Estoy intentando utilizar un convertidor personalizado para Retrofit

RestAdapter.Builder builder = new RestAdapter.Builder() .setEndpoint(BuildConfig.BASE_SERVER_ENDPOINT) .setClient(new OkClient(client)).setConverter(new CitationResponseConverter()) .setLogLevel(RestAdapter.LogLevel.FULL); 

A continuación es mi conversor personalizado

 public class CitationResponseConverter implements Converter { @Override public Object fromBody(TypedInput typedInput, Type type) throws ConversionException { try { InputStream in = typedInput.in(); // convert the typedInput to String String string = fromStream(in); in.close(); // we are responsible to close the InputStream after use if (String.class.equals(type)) { return string; } else { return new Gson().fromJson(string, type); // convert to the supplied type, typically Object, JsonObject or Map<String, Object> } } catch (Exception e) { // a lot may happen here, whatever happens throw new ConversionException( e); // wrap it into ConversionException so retrofit can process it } } @Override public TypedOutput toBody(Object object) { return null; } private static String fromStream(InputStream in) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(in)); StringBuilder out = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { out.append(line); out.append("\r\n"); } return out.toString(); } } 

Estoy teniendo el siguiente error

 retrofit.RetrofitError: method POST must have a request body. 

Mientras trataba de hacer esta api llamada

  @POST("/service/citations") Observable<CitationMain> getCitations(@Body CitationRequestBody body); 

Supongo que el convertidor está anulando la solicitud de la llamada api, ¿cómo puedo evitar eso y pasar el cuerpo de solicitud definido en el servicio de adaptación.

Respuesta:

 { "citations": [ { "coverdatestart": "2015-05-01", "coverimage": [ "09699961/S0969996115X00040/cov200h.gif", "09699961/S0969996115X00040/cov150h.gif" ], "pubyear": "2015", "refimage": [ "09699961/S0969996115X00040/S0969996115000522/gr1-t.gif", "09699961/S0969996115X00040/S0969996115000522/gr1.jpg" ], "volissue": "Volume 77", "volume": "77" }, { "pubdatetxt": "19700101", "refimage": "mma:otto_4_9781455748600/9781455748600_0020", } ] } 

Yo haría algo así:

 public class StringList extends ArrayList<String> { // Empty on purpose. The class is here only to be recognized by Gson } public class CitationMain { @SerializedName("field_name_here") StringList values; // Your other fields } 

A continuación, al crear el RestAdapter:

 public class StringListDeserializer implements JsonDeserializer<StringList> { @Override public StringList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { StringList value = new StringList(); if (json.isJsonArray()) { for (JsonElement element : json.getAsJsonArray()) { value.add(element.getAsString()); } } else { value.add(json.getAsString()); } return value; } } 

Y entonces:

 Gson gson = new GsonBuilder() .registerTypeAdapter(StringList.class, new StringListDeserializer()) .create(); RestAdapter.Builder builder = new RestAdapter.Builder() //... .setConverter(new GsonConverter(gson)); 

No es ideal, ya que el objeto es personalizado, pero cualquier otra solución que pueda pensar ahora es mucho más compleja.

El deserializador aquí está registrado específicamente para los campos declarados como StringList , y manejará el caso de una sola cadena, así como el caso de una matriz de cadena. Cualquier otro tipo de campo utilizará el proceso predeterminado de deserialización.

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.