web-dev-qa-db-fra.com

Comment gérer un corps de réponse vide avec Retrofit 2?

Récemment, j'ai commencé à utiliser Retrofit 2 et j'ai eu du mal à analyser le corps d'une réponse vide. J'ai un serveur qui ne répond qu'avec du code http sans contenu dans le corps de la réponse. Comment gérer uniquement les méta-informations sur la réponse du serveur (en-têtes, code d'état, etc.)?

Merci d'avance!

106
Yevgen Derkach

Modifier:

Comme le souligne Jake Wharton,

@GET("/path/to/get")
Call<Void> getMyData(/* your args here */);

est la meilleure voie à suivre par rapport à ma réponse initiale -

Vous pouvez simplement renvoyer un ResponseBody, qui contournera l'analyse de la réponse.

@GET("/path/to/get")
Call<ResponseBody> getMyData(/* your args here */);

Puis dans votre appel,

Call<ResponseBody> dataCall = myApi.getMyData();
dataCall.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Response<ResponseBody> response) {
        // use response.code, response.headers, etc.
    }

    @Override
    public void onFailure(Throwable t) {
        // handle failure
    }
});
188
iagreen

Si vous utilisez RxJava, mieux vaut utiliser Completable dans ce cas

Représente un calcul différé sans aucune valeur mais uniquement une indication de fin ou d'exception. La classe suit un modèle d’événement similaire à Reactive-Streams: onSubscribe (onError | onComplete)?

http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Completable.html

dans la réponse acceptée:

@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);

Si le système d'extrémité renvoie le code de réponse d'échec, il sera toujours dans le fichier onNext et vous devrez vérifier le code de réponse vous-même.

Cependant, si vous utilisez Completable.

@GET("/path/to/get")
Completable getMyData(/* your args here */);

vous aurez seulement onComplete et onError. si le code de réponse est réussi, il déclenchera la onComplete sinon il déclenchera onError.

34
Ahmad El-Melegy

Si vous utilisez rxjava, utilisez quelque chose comme:

@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
24
Geng Jiawen

Voici comment je l'ai utilisé avec Rx2 et Retrofit2, avec PUT REST request: Ma demande avait un corps json mais juste un code de réponse http avec un corps vide.

Le client Api:

public class ApiClient {
public static final String TAG = ApiClient.class.getSimpleName();


private DevicesEndpoint apiEndpointInterface;

public DevicesEndpoint getApiService() {


    Gson gson = new GsonBuilder()
            .setLenient()
            .create();


    OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    okHttpClientBuilder.addInterceptor(logging);

    OkHttpClient okHttpClient = okHttpClientBuilder.build();

    apiEndpointInterface = new Retrofit.Builder()
            .baseUrl(ApiContract.DEVICES_REST_URL)
            .client(okHttpClient)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build()
            .create(DevicesEndpoint.class);

    return apiEndpointInterface;

}

L'interface:

public interface DevicesEndpoint {
 @Headers("Content-Type: application/json")
 @PUT(ApiContract.DEVICES_ENDPOINT)
 Observable<ResponseBody> sendDeviceDetails(@Body Device device);
}

Puis l'utiliser:

    private void sendDeviceId(Device device){

    ApiClient client = new ApiClient();
    DevicesEndpoint apiService = client.getApiService();
    Observable<ResponseBody> call = apiService.sendDeviceDetails(device);

    Log.i(TAG, "sendDeviceId: about to send device ID");
    call.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<ResponseBody>() {
        @Override
        public void onSubscribe(Disposable disposable) {
        }

        @Override
        public void onNext(ResponseBody body) {
            Log.i(TAG, "onNext");
        }

        @Override
        public void onError(Throwable t) {
            Log.e(TAG, "onError: ", t);

        }

        @Override
        public void onComplete() {
            Log.i(TAG, "onCompleted: sent device ID done");
        }
    });

}
0
Moti Bartov