studio setsupportactionbar programacion móviles from desarrollo curso change aplicaciones android json parsing gson retrofit

android - setsupportactionbar - Convertidor personalizado para la modificación



programacion android pdf 2018 (1)

Estoy tratando de usar 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 convertidor 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.

al intentar hacer esta llamada api

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

Supongo que el convertidor está anulando la solicitud de la llamada de API, ¿cómo puedo evitar eso y pasar el cuerpo de solicitud definido en el servicio de actualizació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", } ] }


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 }

Luego, 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 se me ocurra en este momento 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 cadenas. Cualquier otro tipo de campo usará el proceso de deserialización predeterminado.