Как я могу обработать пустой корпус ответа с помощью 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();
}
});
кто-нибудь может помочь? Я получаю пустое тело ответа. пожалуйста, измените мой код.