2016-02-19 7 views
11

Я должен обрабатывать динамические ответы JSON.Пользовательский конвертер для дооборудования 2

Раньше я использовал классы и аннотации следующим образом:

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

Когда статус 1 (успех) onResponse обжигают, и я могу получить объект ChatResponse. Но, когда статус равен 0, ответ представляется в представлении JSON и он не работает (onFailure уволен).

Я хочу, чтобы создать свой собственный конвертер, и this question имеют хороший пример, но пример для Модернизированного 1.

I have to создать класс, который расширяет Converter.Factory, но я не знаю, как переопределить методы этого класса.

На самом деле у меня есть следующий:

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

Как я могу разобрать ответ JSON моим собственным в этой точке?

Заранее спасибо.

ответ

29

Я искал простой пример того, как реализовать пользовательский конвертер для Retrofit 2, и не нашел ничего хорошего (there is an example, но, по крайней мере, для меня это слишком сложно для моей пурпуры).

Но, наконец, я нашел решение. Это решение должно использовать GSON deserializers. Поэтому нам не нужен настраиваемый конвертер, мы просто должны настроить GSON converter.

Отличный tutorial. И вот мой код для разбора JSON, описанный в моем вопросе:

  • Login Deserializer: Определяет, как для разбора JSON в качестве объекта нашего целевого класса (используя условные и все, что нам нужно).
  • Custom GSON converter: Создает GSON конвертер, который использует наш обычай десериализатор
+0

Это добавит статический преобразователь завода для того же типа реакции. Что делать, если я хочу, чтобы разбор различных объектов ответа был необязательным? У меня могут быть различные ответы для различных apis с параметрами и фиксированными объектами ответа. –

2

компилировать эти две библиотеки для 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(); 

    } 

вызов, как их там, где вы хотите

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

и двух файлов для запроса и ответа

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 Вы можете использовать http://www.jsonschema2pojo.org/ для преобразования JSON ниже письменной форме, выбрав SourceType: JSON и аннотирование Стиль: 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

Я нашел @JCarlos решение будет точным, быстрым и правильным.Мне нужно было реализовать пользовательский конвертер даты для Retrofit 2 на Android. Похоже, вам нужно зарегистрировать новый сериализатор типов в GSonConverterFactory. Реализация осуществляется в 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) 
    } 
} 

и регистрация:

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