Convertidor personalizado para Retrofit 2

Tengo que manejar respuestas dinámicas de JSON.

Antes, estaba usando clases y anotaciones de la siguiente manera:

public class ChatResponse { @SerializedName("status") private int status; @SerializedName("error") private String error; @SerializedName("response") private Talk response; public int getStatus() { return status; } public String getError() { return error; } public Talk getResponse() { return response; } } 

Cuando el estado es 1 (éxito), se onResponse y puedo obtener un objeto ChatResponse. Pero, cuando el estado es 0, la respuesta es falsa en la representación JSON y falla (se onFailure ).

Quiero crear mi convertidor personalizado, y esta pregunta tiene un buen ejemplo, pero ese ejemplo es para Retrofit 1.

Tengo que crear una clase que amplíe Converter.Factory , pero no sé cómo anular los métodos de esta clase.

En realidad, tengo el siguiente:

 @Override public Converter fromResponseBody(Type type, Annotation[] annotations) { return super.fromResponseBody(type, annotations); } @Override public Converter toRequestBody(Type type, Annotation[] annotations) { return super.toRequestBody(type, annotations); } 

¿Cómo puedo analizar la respuesta JSON por mi cuenta en este momento?

Gracias por adelantado.

Estaba buscando un ejemplo simple sobre cómo implementar un convertidor personalizado para Retrofit 2, y no encontré nada bueno ( hay un ejemplo pero, al menos para mí, eso es demasiado complicado para mi propósito).

Pero finalmente, encontré una solución. Esta solución es usar GSON deserializers . Así que no necesitamos un convertidor personalizado, solo tenemos que personalizar el GSON converter .

Aquí hay un gran tutorial . Y aquí está mi código para analizar el JSON descrito en mi pregunta:

  • Deserializador de inicio de sesión : define cómo analizar el JSON como un objeto de nuestra clase objective (usando condicionales y todo lo que necesitamos).
  • Convertidor GSON personalizado : crea un convertidor GSON que utiliza nuestro deserializador personalizado

comstackr estas dos bibliotecas para retrofit2

 compile 'com.squareup.retrofit2:retrofit:2.1.0' compile 'com.squareup.retrofit2:converter-gson:2.0.2' import com.lendingkart.prakhar.lendingkartdemo.retrofitPOJOResponse.DocsNameResponse; import com.lendingkart.prakhar.lendingkartdemo.retrofitrequests.DocName; import retrofit2.Call; import retrofit2.Retrofit; import retrofit2.converter.gson.GsonConverterFactory; import retrofit2.http.Body; import retrofit2.http.Multipart; import retrofit2.http.POST; import retrofit2.http.Part; import retrofit2.http.PartMap; public interface APIInterface { String ENDPOINT = "https://app.xxxxxxxxx.com/"; @POST("lkart/api/docs") Call DOCS_NAME_RESPONSE_CALL(@Body DocName docName); public static final Retrofit retrofit = new Retrofit.Builder() .baseUrl(APIInterface.ENDPOINT) .addConverterFactory(GsonConverterFactory.create()) .build(); } 

llama como estos a donde quieras

  String doc_name = "Loans/jdfjdanklnadkm;cnak_"; APIInterface apiInterface = APIInterface.retrofit.create(APIInterface.class); Call DocsCall = apiInterface.DOCS_NAME_RESPONSE_CALL(new DocName(doc_name)); DocsCall.enqueue(new Callback() { @Override public void onResponse(Call call, Response response) { Log.d("APIResult", String.valueOf(response.body().getData().get(3).getName())); } @Override public void onFailure(Call call, Throwable t) { Log.d("APIError", t.getMessage()); } }); 

y dos archivos para la solicitud y respuesta son

DocName

 public class DocName { private String name; public DocName(String name) { this.name = name; } /** * @return The name */ public String getName() { return name; } /** * @param name The name */ public void setName(String name) { this.name = name; } } 

DocNameResponse Puede usar http://www.jsonschema2pojo.org/ para convertir su JSON al siguiente formato escrito eligiendo SourceType: JSON y Annotation Style: GSON

 import com.google.gson.annotations.Expose; import com.google.gson.annotations.SerializedName; import java.util.List; public class DocsNameResponse { @SerializedName("message") @Expose private String message; @SerializedName("statusCode") @Expose private Integer statusCode; @SerializedName("data") @Expose private List data = null; @SerializedName("list") @Expose private Object list; @SerializedName("cscStatus") @Expose private Boolean cscStatus; @SerializedName("status") @Expose private Object status; @SerializedName("eligibleStatus") @Expose private Boolean eligibleStatus; @SerializedName("pwd") @Expose private Object pwd; @SerializedName("uname") @Expose private Object uname; @SerializedName("assignedToList") @Expose private Object assignedToList; /** * @return The message */ public String getMessage() { return message; } /** * @param message The message */ public void setMessage(String message) { this.message = message; } /** * @return The statusCode */ public Integer getStatusCode() { return statusCode; } /** * @param statusCode The statusCode */ public void setStatusCode(Integer statusCode) { this.statusCode = statusCode; } /** * @return The data */ public List getData() { return data; } /** * @param data The data */ public void setData(List data) { this.data = data; } /** * @return The list */ public Object getList() { return list; } /** * @param list The list */ public void setList(Object list) { this.list = list; } /** * @return The cscStatus */ public Boolean getCscStatus() { return cscStatus; } /** * @param cscStatus The cscStatus */ public void setCscStatus(Boolean cscStatus) { this.cscStatus = cscStatus; } /** * @return The status */ public Object getStatus() { return status; } /** * @param status The status */ public void setStatus(Object status) { this.status = status; } /** * @return The eligibleStatus */ public Boolean getEligibleStatus() { return eligibleStatus; } /** * @param eligibleStatus The eligibleStatus */ public void setEligibleStatus(Boolean eligibleStatus) { this.eligibleStatus = eligibleStatus; } /** * @return The pwd */ public Object getPwd() { return pwd; } /** * @param pwd The pwd */ public void setPwd(Object pwd) { this.pwd = pwd; } /** * @return The uname */ public Object getUname() { return uname; } /** * @param uname The uname */ public void setUname(Object uname) { this.uname = uname; } /** * @return The assignedToList */ public Object getAssignedToList() { return assignedToList; } /** * @param assignedToList The assignedToList */ public void setAssignedToList(Object assignedToList) { this.assignedToList = assignedToList; } public class Datum { @SerializedName("id") @Expose private Object id; @SerializedName("name") @Expose private String name; @SerializedName("applicationId") @Expose private Object applicationId; @SerializedName("userId") @Expose private Object userId; @SerializedName("documentName") @Expose private String documentName; @SerializedName("documentType") @Expose private Object documentType; @SerializedName("freshloan") @Expose private Object freshloan; /** * @return The id */ public Object getId() { return id; } /** * @param id The id */ public void setId(Object id) { this.id = id; } /** * @return The name */ public String getName() { return name; } /** * @param name The name */ public void setName(String name) { this.name = name; } /** * @return The applicationId */ public Object getApplicationId() { return applicationId; } /** * @param applicationId The applicationId */ public void setApplicationId(Object applicationId) { this.applicationId = applicationId; } /** * @return The userId */ public Object getUserId() { return userId; } /** * @param userId The userId */ public void setUserId(Object userId) { this.userId = userId; } /** * @return The documentName */ public String getDocumentName() { return documentName; } /** * @param documentName The documentName */ public void setDocumentName(String documentName) { this.documentName = documentName; } /** * @return The documentType */ public Object getDocumentType() { return documentType; } /** * @param documentType The documentType */ public void setDocumentType(Object documentType) { this.documentType = documentType; } /** * @return The freshloan */ public Object getFreshloan() { return freshloan; } /** * @param freshloan The freshloan */ public void setFreshloan(Object freshloan) { this.freshloan = freshloan; } } } 

Encontré que la solución @JCarlos es precisa, rápida y correcta. Necesitaba implementar convertidor de fecha personalizado para Retrofit 2 en Android. Parece que necesita registrar un nuevo tipo de serializador en GSonConverterFactory. La implementación se realiza en Kotlin Lang.

 class RetrofitDateSerializer : JsonSerializer { override fun serialize(srcDate: Date?, typeOfSrc: Type?, context: JsonSerializationContext?): JsonElement? { if (srcDate == null) return null val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss") val formatted = dateFormat.format(srcDate) return JsonPrimitive(formatted) } } 

y el registro:

 private fun buildGsonConverterFactory(): GsonConverterFactory { val gsonBuilder = GsonBuilder() // Custom DATE Converter for Retrofit gsonBuilder.registerTypeAdapter(Date::class.java, RetrofitDateSerializer()) return GsonConverterFactory.create(gsonBuilder.create()) } @Provides @Singleton internal fun providesRetrofit(applicationContext: Context): Retrofit { return Retrofit.Builder() .baseUrl(GluApp.Static.BASE_REST_URL_ADDR) .addConverterFactory( buildGsonConverterFactory()) .build() }