मैं रेट्रोफिट 2 के साथ खाली प्रतिक्रिया निकाय को कैसे संभाल सकता हूं?


125

हाल ही में मैंने रेट्रोफिट 2 का उपयोग करना शुरू किया और मुझे खाली प्रतिक्रिया वाले शरीर को पार्स करने के साथ एक समस्या का सामना करना पड़ा। मेरे पास एक सर्वर है जो प्रतिक्रिया शरीर के अंदर बिना किसी सामग्री के केवल http कोड के साथ प्रतिक्रिया करता है।

मैं सर्वर प्रतिक्रिया (हेडर, स्थिति कोड आदि) के बारे में केवल मेटा जानकारी कैसे संभाल सकता हूं?

जवाबों:


216

संपादित करें:

जैसा कि जेक व्हार्टन बताते हैं,

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

58
इससे भी बेहतर: उपयोग करें Voidजिसमें न केवल बेहतर शब्दार्थ है, बल्कि (थोड़ा) खाली मामले में अधिक कुशल है और गैर-खाली मामले में बहुत अधिक कुशल है (जब आप सिर्फ शरीर की परवाह नहीं करते हैं)।
जेक व्हार्टन

1
@JakeWharton यह महान व्यवहार है। यह इंगित करने के लिए धन्यवाद। उत्तर अपडेट किया गया।
इग्रिन

2
बहुत बढ़िया जवाब। शून्य का उपयोग न करने का एक कारण यह है कि यदि आपके पास एक संसाधन है जो केवल एक शरीर वापस करता है जब अनुरोध असफल होता है और आप एररबॉडी रिस्पॉन्सबॉडी को कुछ विशिष्ट या सामान्य प्रकार में परिवर्तित करना चाहते हैं।

7
@JakeWharton उपयोग करने के लिए महान सुझाव Void। क्या Unitकोटलिन कोड का उपयोग करने से Voidरेट्रोफिट के लिए जावा में समान लाभ मिलेगा ?
अक्षय चोरिया

6
@ अक्षय- कोर्डिया मैंने अभी चेक किया है, कोटलिन Unitमें काम नहीं करता है, Voidहालांकि। मुझे लगता है कि कहीं न कहीं एक हार्डकोड चेक है।
user3363866

40

यदि आप RxJava का उपयोग करते हैं, तो Completableइस मामले में उपयोग करना बेहतर है

बिना किसी मूल्य के एक आस्थगित संगणना का प्रतिनिधित्व करता है लेकिन केवल पूर्णता या अपवाद के लिए संकेत। कक्षा प्रतिक्रिया-धाराओं के समान घटना पैटर्न का अनुसरण करती है: 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


1
onError Throwableउस मामले में, क्या तर्क होगा ? मुझे यह क्लीनर लगता है, लेकिन हमें अभी भी विफलताओं के लिए प्रतिक्रिया कोड और शरीर को देखने की जरूरत है।
big_m

24

यदि आप rxjava का उपयोग कर रहे हैं, तो कुछ का उपयोग करें:

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

यही मुझे मिल रहा था! धन्यवाद!
साइरलॉन

मैंने RUTJava2 और Retrofit2 के साथ PUT REST अनुरोध के लिए ResposeBody का उपयोग किया है। यह ठीक काम किया
मोती बार्टोव

1
हमारे पास एक समापन बिंदु एपीआई है जो सफलता के समय खाली शरीर देता है, और त्रुटि होने पर शरीर को झटका देता है। यदि रिस्पांस <शून्य> का उपयोग कर रहे हैं, तो मैं त्रुटि मामले को कैसे संभाल सकता हूं?
केएनवीएन फेवो

आप यहां कौन सा रिस्पांस क्लास इस्तेमाल करते हैं? रेट्रोफिट या OKHttps?
मथायस

1
यह एक अच्छा विकल्प नहीं है यदि आप अपवादों पर त्रुटि को हैंडल करते हैं .. तो आपको इस दृष्टिकोण के साथ कोई अपवाद नहीं मिलता है, बल्कि त्रुटि पर प्रतिक्रिया के रूप में एक JSON
Ovi Trif

0

यहाँ है कि मैंने इसे Rx2 और Retrofit2 के साथ, PUT REST अनुरोध के साथ कैसे उपयोग किया: मेरे अनुरोध में एक जोंस बॉडी थी, लेकिन खाली शरीर के साथ बस http प्रतिक्रिया कोड था।

एपीआई क्लाइंट:

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

}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.