web-dev-qa-db-de.com

Wie kann ich mit Retrofit 2 mit leeren Antwortkörpern umgehen?

Seit kurzem benutze ich Retrofit 2 und ich hatten ein Problem beim Parsen des leeren Antwortkörpers. Ich habe einen Server, der nur mit http-Code ohne Inhalt im Antworttext antwortet. Wie kann ich nur Metainformationen zur Serverantwort (Header, Statuscode usw.) verarbeiten?

Danke im Voraus!

106
Yevgen Derkach

Bearbeiten:

Wie Jake Wharton betont,

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

ist der beste Weg, um gegen meine ursprüngliche Antwort zu gehen -

Sie können einfach ein ResponseBody zurückgeben, wodurch das Parsen der Antwort umgangen wird.

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

Dann in Ihrem Anruf,

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

Wenn Sie RxJava verwenden, ist es in diesem Fall besser, Completable zu verwenden

Stellt eine zurückgestellte Berechnung ohne Wert dar, sondern nur als Hinweis auf den Abschluss oder eine Ausnahme. Die Klasse folgt einem ähnlichen Ereignismuster wie Reactive-Streams: onSubscribe (onError | onComplete)?

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

in der akzeptierten Antwort:

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

Wenn der Endpunkt einen Fehlerantwortcode zurückgibt, befindet er sich weiterhin im onNext, und Sie müssen den Antwortcode selbst überprüfen.

Wenn Sie jedoch Completable verwenden.

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

sie haben nur onComplete und onError. Wenn der Antwortcode erfolgreich ist, wird onComplete ausgelöst, andernfalls onError.

34
Ahmad El-Melegy

Wenn Sie rxjava verwenden, verwenden Sie Folgendes:

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

Hier ist, wie ich es mit Rx2 und Retrofit2 verwendet habe, mit PUT REST request: Meine Anfrage hatte einen json-Body, aber nur einen http-Antwortcode mit leerem Body.

Der Api-Client:

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;

}

Die Schnittstelle:

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

Dann benutze es:

    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