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!
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
}
});
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
.
Si vous utilisez rxjava, utilisez quelque chose comme:
@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
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");
}
});
}