web-dev-qa-db-fra.com

Convertisseur personnalisé pour Retrofit 2

Je dois gérer une réponse JSON dynamique.

Avant, j'utilisais les classes et les annotations comme suit:

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

Lorsque le statut est 1 (succès), le onResponse est déclenché et je peux obtenir un objet ChatResponse. Mais, lorsque l'état est 0, la réponse est fausse dans la représentation JSON et elle échoue (onFailure est déclenché).

Je veux créer mon convertisseur personnalisé, et cette question a un bon exemple, mais cet exemple concerne Retrofit 1.

je dois créer une classe qui étend Converter.Factory, mais je ne sais pas comment remplacer les méthodes de cette classe.

En fait, j'ai le suivant:

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

Comment puis-je analyser la réponse JSON par moi-même à ce stade?

Merci d'avance.

21
JCarlos

Je cherchais un exemple simple sur la façon d'implémenter un convertisseur personnalisé pour Retrofit 2, et je n'ai rien trouvé de bon ( il y a un exemple mais, au moins pour moi, c'est trop compliqué pour mon purpouse).

Mais finalement, j'ai trouvé une solution. Cette solution consiste à utiliser GSON deserializers. Nous n'avons donc pas besoin d'un convertisseur personnalisé, il nous suffit de personnaliser le GSON converter.

Voici un excellent tutoriel . Et voici mon code pour analyser le JSON décrit dans ma question:

  • Login Deserializer : Définit comment analyser le JSON en tant qu'objet de notre classe cible (en utilisant les conditions et tout ce dont nous avons besoin).
  • Convertisseur GSON personnalisé : Construit un convertisseur GSON qui utilise notre désérialiseur personnalisé
37
JCarlos

J'ai trouvé la solution @JCarlos précise, rapide et correcte. J'avais besoin d'implémenter convertisseur de date personnalisé pour Retrofit 2 sur Android. Il semble que vous devez enregistrer un nouveau sérialiseur de type dans GSonConverterFactory. L'implémentation se fait 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)
    }
}

et l'inscription:

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

compiler ces deux bibliothèques pour 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();

    }

appeler comme ceux-là où vous voulez

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

et deux fichiers pour la demande et la réponse sont

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 Vous pouvez utiliser http://www.jsonschema2pojo.org/ pour convertir votre JSON en écrit ci-dessous format en choisissant SourceType: JSON et Style d'annotation: 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;
        }

    }

}
2
Prakhar1001

Ici est un exemple.

Prochainement:

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();
0
Andrey