volley implementar ejemplo android retrofit retrofit2 square

android - implementar - retrofit post



¿Cómo puedo manejar el cuerpo de respuesta vacío con Retrofit 2? (4)

Recientemente comencé a usar Retrofit 2 y me enfrenté a un problema al analizar el cuerpo de respuesta vacío. Tengo un servidor que responde solo con código http sin ningún contenido dentro del cuerpo de respuesta. ¿Cómo puedo manejar solo la metainformación sobre la respuesta del servidor (encabezados, código de estado, etc.)?

¡Gracias por adelantado!


Así es como lo usé con Rx2 y Retrofit2, con la solicitud PUT REST: Mi solicitud tenía un cuerpo json pero solo un código de respuesta http con un cuerpo vacío.

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

La interfaz:

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

Luego para usarlo:

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


Editar:

Como señala Jake Wharton,

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

es la mejor manera de ir en comparación con mi respuesta original:

Puede devolver un ResponseBody , que omitirá el análisis de la respuesta.

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

Entonces en tu llamada,

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 está utilizando rxjava, use algo como:

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


Si usa RxJava, entonces es mejor usar Completable en este caso

Representa un cálculo diferido sin ningún valor, sino solo una indicación de finalización o excepción. La clase sigue un patrón de eventos similar al de Reactive-Streams: onSubscribe (onError | onComplete)?

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

en la respuesta aceptada:

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

Si el punto final devuelve el código de respuesta de falla, aún estará en onNext y tendrá que verificar el código de respuesta usted mismo.

Sin embargo, si usa Completable .

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

solo tendrá onComplete y onError . si el código de respuesta es exitoso, activará onComplete contrario, activará onError .