Recently I started using Retrofit 2
and I faced an issue with parsing empty response body. I have a server which responds only with http code without any content inside the response body. How can I handle only meta information about server response (headers, status code etc)?
最近我开始使用Retrofit 2,我遇到了解析空响应体的问题。我有一个服务器只响应http代码而没有响应体内的任何内容。如何只处理有关服务器响应的元信息(标题,状态代码等)?
Thanks in advance!
提前致谢!
4 个解决方案
#1
145
Edit:
编辑:
As Jake Wharton points out,
正如杰克沃顿指出的那样,
@GET("/path/to/get")
Call<Void> getMyData(/* your args here */);
is the best way to go versus my original response --
与我最初的回应相比,这是最好的方式 -
You can just return a ResponseBody
, which will bypass parsing the response.
您只需返回一个ResponseBody,它将绕过解析响应。
@GET("/path/to/get")
Call<ResponseBody> getMyData(/* your args here */);
Then in your call,
然后在你的电话中,
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
17
If you are using rxjava, use something like :
如果您使用的是rxjava,请使用以下内容:
@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
#3
13
If you use RxJava, then it's better to use Completable
in this case
如果您使用RxJava,那么在这种情况下最好使用Completable
Represents a deferred computation without any value but only indication for completion or exception. The class follows a similar event pattern as Reactive-Streams: onSubscribe (onError|onComplete)?
表示没有任何值的延迟计算,但仅表示完成或异常。该类遵循与Reactive-Streams类似的事件模式:onSubscribe(onError | onComplete)?
http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Completable.html
http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Completable.html
in the accepted answer:
在接受的答案中:
@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
If the endpoint returns failure response code, it will still be in the onNext
and you will have to check the response code yourself.
如果端点返回失败响应代码,它仍将在onNext中,您必须自己检查响应代码。
However, if you use Completable
.
但是,如果您使用Completable。
@GET("/path/to/get")
Completable getMyData(/* your args here */);
you will have only onComplete
and onError
. if the response code is success it will fire the onComplete
else it will fire onError
.
你将只有onComplete和onError。如果响应代码成功,它将触发onComplete,否则它将触发onError。
#4
0
Here is how I used it with Rx2 and Retrofit2, with PUT REST request: My request had a json body but just http response code with empty body.
以下是我如何将它与Rx2和Retrofit2一起使用,带有PUT REST请求:我的请求有一个json体,但只是带有空体的http响应代码。
The Api 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;
}
The interface:
界面:
public interface DevicesEndpoint {
@Headers("Content-Type: application/json")
@PUT(ApiContract.DEVICES_ENDPOINT)
Observable<ResponseBody> sendDeviceDetails(@Body Device device);
}
Then to use it:
然后使用它:
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");
}
});
}
#1
145
Edit:
编辑:
As Jake Wharton points out,
正如杰克沃顿指出的那样,
@GET("/path/to/get")
Call<Void> getMyData(/* your args here */);
is the best way to go versus my original response --
与我最初的回应相比,这是最好的方式 -
You can just return a ResponseBody
, which will bypass parsing the response.
您只需返回一个ResponseBody,它将绕过解析响应。
@GET("/path/to/get")
Call<ResponseBody> getMyData(/* your args here */);
Then in your call,
然后在你的电话中,
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
17
If you are using rxjava, use something like :
如果您使用的是rxjava,请使用以下内容:
@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
#3
13
If you use RxJava, then it's better to use Completable
in this case
如果您使用RxJava,那么在这种情况下最好使用Completable
Represents a deferred computation without any value but only indication for completion or exception. The class follows a similar event pattern as Reactive-Streams: onSubscribe (onError|onComplete)?
表示没有任何值的延迟计算,但仅表示完成或异常。该类遵循与Reactive-Streams类似的事件模式:onSubscribe(onError | onComplete)?
http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Completable.html
http://reactivex.io/RxJava/2.x/javadoc/io/reactivex/Completable.html
in the accepted answer:
在接受的答案中:
@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
If the endpoint returns failure response code, it will still be in the onNext
and you will have to check the response code yourself.
如果端点返回失败响应代码,它仍将在onNext中,您必须自己检查响应代码。
However, if you use Completable
.
但是,如果您使用Completable。
@GET("/path/to/get")
Completable getMyData(/* your args here */);
you will have only onComplete
and onError
. if the response code is success it will fire the onComplete
else it will fire onError
.
你将只有onComplete和onError。如果响应代码成功,它将触发onComplete,否则它将触发onError。
#4
0
Here is how I used it with Rx2 and Retrofit2, with PUT REST request: My request had a json body but just http response code with empty body.
以下是我如何将它与Rx2和Retrofit2一起使用,带有PUT REST请求:我的请求有一个json体,但只是带有空体的http响应代码。
The Api 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;
}
The interface:
界面:
public interface DevicesEndpoint {
@Headers("Content-Type: application/json")
@PUT(ApiContract.DEVICES_ENDPOINT)
Observable<ResponseBody> sendDeviceDetails(@Body Device device);
}
Then to use it:
然后使用它:
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");
}
});
}