android json converter retrofit2

android - Convertidor personalizado para Retrofit 2



json converter (4)

Tengo que manejar una respuesta JSON dinámica.

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 extienda Converter.Factory , pero no sé cómo anular los métodos de esta clase.

En realidad tengo el siguiente:

@Override public Converter<ResponseBody, ?> fromResponseBody(Type type, Annotation[] annotations) { return super.fromResponseBody(type, annotations); } @Override public Converter<?, RequestBody> 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.


Encontré que la solución @JCarlos es precisa, rápida y correcta. Necesitaba implementar un 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<Date> { 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() }


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 . Por lo tanto, 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:


compila 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<DocsNameResponse> DOCS_NAME_RESPONSE_CALL(@Body DocName docName); public static final Retrofit retrofit = new Retrofit.Builder() .baseUrl(APIInterface.ENDPOINT) .addConverterFactory(GsonConverterFactory.create()) .build(); }

llama así a donde quieras

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

y dos archivos para la solicitud y la 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 formato escrito a continuación seleccionando 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<Datum> 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<Datum> getData() { return data; } /** * @param data The data */ public void setData(List<Datum> 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; } } }


Here hay un ejemplo.

Dentro de poco:

Gson gson = new GsonBuilder() .registerTypeAdapter(MyClass.class, new MyClassTypeAdapter()) .create(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.github.com") .addConverterFactory(GsonConverterFactory.create(gson)) .build();