2016-02-19 32 views
11

Devo gestire una risposta JSON dinamica.Convertitore personalizzato per Retrofit 2

Prima, usavo le classi e le annotazioni come segue:

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; 
    } 
} 

Quando lo stato è 1 (successo) la onResponse viene licenziato e posso ottenere un oggetto ChatResponse. Tuttavia, quando lo stato è 0, la risposta è falsa nella rappresentazione JSON e non riesce (onFailure viene attivato).

voglio creare il mio convertitore personalizzato e this question ha un buon esempio, ma questo esempio è per retrofit 1.

I have to creare una classe che estende Converter.Factory, ma non so come ignorare i metodi di questa classe.

realtà ho il prossimo:

@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); 
} 

Come posso analizzare la risposta JSON dalla mia, a questo punto?

Grazie in anticipo.

risposta

29

Stavo cercando un semplice esempio su come implementare un convertitore personalizzato per Retrofit 2 e non ho trovato nulla di buono (there is an example ma, almeno per me, che è troppo complicato per il mio scopo).

Ma alla fine ho trovato una soluzione. Questa soluzione utilizza GSON deserializers. Quindi non abbiamo bisogno di un convertitore personalizzato, dobbiamo solo personalizzare il GSON converter.

Ecco un ottimo tutorial. E qui è il mio codice per analizzare il JSON descritto nella mia interrogazione:

  • Login Deserializer: definisce come analizzare il JSON come un oggetto della nostra classe di destinazione (usando condizionali e tutto ciò che abbiamo bisogno).
  • Custom GSON converter: costruisce un convertitore GSON che utilizza la nostra personalizzato deserializzatore
+0

questo aggiungerebbe una fabbrica convertitore statico per lo stesso tipo di risposta. Cosa succede se desidero rendere l'analisi di diversi oggetti di risposta facoltativi? Potrei avere risposte varie per vari apis con oggetti optionsl e fixed response. –

2

compilare questi due libreria per 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(); 

    } 

chiamata come questi in cui si desidera

 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()); 
      } 
     }); 

e due file per la richiesta e la risposta sono

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 È possibile utilizzare http://www.jsonschema2pojo.org/ per convertire il vostro JSON in formato sotto scritto scegliendo SourceType: JSON e stile della nota: 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; 
     } 

    } 

} 
1

ho trovato @JCarlos soluzione per essere precisi, veloci e corretti.Avevo bisogno di implementare il convertitore di data personalizzato per Retrofit 2 su Android. Sembra che sia necessario registrare un nuovo serializzatore di tipo in GSonConverterFactory. L'implementazione viene eseguita in 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) 
    } 
} 

e la registrazione:

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() 
}