Как я могу обработать пустой корпус ответа с помощью Retrofit 2?

Недавно я начал использовать Retrofit 2, и я столкнулся с проблемой разбора пустого тела ответа. У меня есть сервер, который отвечает только http-кодом без какого-либо содержимого внутри тела ответа. Как я могу обрабатывать только метаинформацию о ответе сервера (заголовки, код состояния и т.д.)?

Спасибо заранее!

Ответ 1

Edit:

Как отмечает Джейк Уортон,

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

- лучший способ пойти против моего первоначального ответа -

Вы можете просто вернуть ResponseBody, который будет обходить синтаксический разбор ответа.

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

Затем в вашем вызове

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

Ответ 2

Если вы используете RxJava, тогда лучше использовать Completable в этом случае

Представляет отложенное вычисление без какого-либо значения, но только указание на завершение или исключение. Класс следует аналогичному шаблону событий, как Reactive-Streams: onSubscribe (onError | onComplete)?

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

в принятом ответе:

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

Если конечная точка возвращает код ответа на неисправность, она все равно будет находиться в onNext, и вам нужно будет проверить код ответа самостоятельно.

Однако, если вы используете Completable.

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

у вас будут только onComplete и onError. если код ответа будет успешным, он запустит onComplete иначе он запустит onError.

Ответ 3

Если вы используете rxjava, используйте что-то вроде:

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

Ответ 4

Вот как я использовал его с Rx2 и Retrofit2 с запросом PUT REST: Мой запрос имел тело json, но только код ответа HTTP с пустым телом.

Клиент 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;

}

Интерфейс:

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

Затем, чтобы использовать его:

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

}

Ответ 5

 public void signUp(String username,String password,String name,String type,String image){
    register_progress= ProgressDialog.show(this, null,getResources().getString(R.string.operation_progress), true);
    Retrofit retrofit = apiClient.getClient();
    apiRest service = retrofit.create(apiRest.class);
    Call<ApiResponse> call = service.register(name,username,password,type,image);
    call.enqueue(new Callback<ApiResponse>() {
        @Override
        public void onResponse(Call<ApiResponse> call, Response<ApiResponse> response) {
            if(response.body()!=null){
                if (response.body().getCode()==200){


                }
                if (response.body().getCode()==500){
                    Toasty.error(getApplicationContext(), "Operation has been cancelled ! ", Toast.LENGTH_SHORT, true).show();
                }
            }else{
                Toasty.error(getApplicationContext(), "Operation has been cancelled ! ", Toast.LENGTH_SHORT, true).show();
            }
            register_progress.dismiss();
        }
        @Override
        public void onFailure(Call<ApiResponse> call, Throwable t) {
            Toasty.error(getApplicationContext(), "Operation has been cancelled ! ", Toast.LENGTH_SHORT, true).show();
            register_progress.dismiss();
        }
    });

кто-нибудь может помочь? Я получаю пустое тело ответа. пожалуйста, измените мой код.