最近,我开始使用Retrofit 2,并且在解析空白响应正文时遇到问题。我有一个仅用http代码响应的服务器,响应主体内部没有任何内容。
如何仅处理有关服务器响应的元信息(标头,状态代码等)?
最近,我开始使用Retrofit 2,并且在解析空白响应正文时遇到问题。我有一个仅用http代码响应的服务器,响应主体内部没有任何内容。
如何仅处理有关服务器响应的元信息(标头,状态代码等)?
Answers:
编辑:
杰克·沃顿(Jake Wharton)指出,
@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
}
});
Void
。Unit
在Kotlin代码中使用会带来与Void
Java for Retrofit 相同的好处吗?
Unit
在Kotlin中不起作用,Void
但是可以。我假设某处有一个硬编码的支票。
如果您使用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
。
onError
Throwable
在这种情况下,论点将包含什么?我找到了这种清洁器,但是我们经常仍然需要查看响应代码和失败的正文。
如果您使用的是rxjava,请使用类似以下内容的代码:
@GET("/path/to/get")
Observable<Response<Void>> getMyData(/* your args here */);
这是我将其与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");
}
});
}
Void
这种方法不仅具有更好的语义,而且在空情况下(在)非空情况下(当您只是不在乎身体时)效率更高(略)。