Android रेट्रोफ़िट पैरामीटर @Headers


85

मैं OAuth का उपयोग कर रहा हूं और मुझे अनुरोध करने पर हर बार अपने शीर्षलेख में OAuth टोकन डालने की आवश्यकता है। मैं @Headerएनोटेशन देखता हूं , लेकिन क्या इसे मानकीकृत करने का कोई तरीका है ताकि मैं रन टाइम में पास हो सकूं?

यहाँ अवधारणा है

@Header({Authorization:'OAuth {var}', api_version={var} })

क्या आप उन्हें रनटाइम में पास कर सकते हैं?

@GET("/users")
void getUsers(
    @Header("Authorization") String auth, 
    @Header("X-Api-Version") String version, 
    Callback<User> callback
)

क्या आपको इसका कभी पता चला? मुझे हेडर में एक टोकन को भी पास करने की आवश्यकता है
theSociableme

मैं इसके समाधान की भी तलाश कर रहा हूं, प्रलेखन से ऐसा लगता है कि विधि पर @Headers () एनोटेशन एक-एक करके शीर्ष लेखों को जोड़ता है , लेकिन केवल शाब्दिक समर्थन करता है। और @ हैडर ("पैरामीटर") स्ट्रिंग स्ट्रिंग पैरामीटर एनोटेशन हेडर को आपूर्ति किए गए मान से बदल देता है।
नाना

2
यहां भी, यह पता नहीं लगा सका कि रेट्रोफिट का उपयोग करते समय सत्रों को कैसे संभालना है।
एफआरआर

हमें सभी वस्तुओं को पास करने की आवश्यकता नहीं थी, रेट्रोफिट खुद ही सभी को संभालता है। कृपया StackOverflow में मेरे उत्तर लिंक की जाँच करें ।
सुबिन बाबू

जवाबों:


98

@Header पैरामीटर का उपयोग करने के अलावा, मैं आपके इंटरफ़ेस को बदले बिना आपके सभी अनुरोध को अपडेट करने के लिए RequestInterceptor का उपयोग करूंगा। कुछ का उपयोग करना:

RestAdapter.Builder builder = new RestAdapter.Builder()
    .setRequestInterceptor(new RequestInterceptor() {
        @Override
        public void intercept(RequestFacade request) {
            request.addHeader("Accept", "application/json;versions=1");
            if (isUserLoggedIn()) {
                request.addHeader("Authorization", getToken());
            }                    
        }
    });

p / s: यदि आप Retrofit2 का उपयोग कर रहे हैं, तो आपको Interceptorइसके बजाय का उपयोग करना चाहिएRequestInterceptor

चूंकि RequestInterceptorअब रेट्रोफिट 2.0 में उपलब्ध नहीं है


3
यह सीधे तौर पर संबंधित नहीं है, लेकिन यदि आप अपने प्राधिकरण हेडर को उत्पन्न करने के लिए अनुरोध ऑब्जेक्ट से मान प्राप्त करने के लिए खुद को आवश्यक पाते हैं, तो आपको ApacheClient का विस्तार करने और अनुरोध ऑब्जेक्ट (सूची <हेडर> हेडर = ... की नकल करने में सक्षम होना चाहिए। ; अनुरोध requestNew = नया अनुरोध (request.getMethod (), request.getUrl (), शीर्ष लेख, request.getBody ()); अनुरोध = requestNew)।

1
यह एक चाल है जिसमें एक कोडित गड़बड़ है, बेहतर उपयोग @ नाना का जवाब
इवान फज़ानुक

1
RestAdapterRetrofit1 पर निर्भर करता है, Retrofit2 में यह है Retrofit। Im Retrofit2 का उपयोग करने जा रहा है, इसलिए यह RequestInterceptorउपरोक्त मुद्दों के रूप में उपयोग करने पर कोई समस्या नहीं है ?
टावर

55

हां, आप उन्हें रनटाइम में पास कर सकते हैं। तथ्य की बात के रूप में, बहुत ज्यादा बिल्कुल के रूप में आप इसे टाइप किया। यह आपके API इंटरफ़ेस क्लास में होगा, जिसका नाम SecretApiInterface.java है

public interface SecretApiInterface {

    @GET("/secret_things")
    SecretThing.List getSecretThings(@Header("Authorization") String token)

}

फिर आप अपने अनुरोध से इस इंटरफ़ेस के मापदंडों को पास करते हैं, उन पंक्तियों के साथ कुछ: (यह फ़ाइल SecretThingRequest .java उदाहरण के लिए होगी )

public class SecretThingRequest extends RetrofitSpiceRequest<SecretThing.List, SecretApiInteface>{

    private String token;

    public SecretThingRequest(String token) {
        super(SecretThing.List.class, SecretApiInterface.class);
        this.token = token;
    }

    @Override
    public SecretThing.List loadDataFromNetwork() {
        SecretApiInterface service = getService();
        return service.getSecretThings(Somehow.Magically.getToken());
    }
}

Somehow.Magically.getToken()एक विधि कॉल कहाँ है जो एक टोकन लौटाती है, यह आपके ऊपर है कि आप इसे कहाँ और कैसे परिभाषित करते हैं।

आप निश्चित @Header("Blah") String blahरूप से इंटरफ़ेस कार्यान्वयन में एक से अधिक एनोटेशन कर सकते हैं , जैसा कि आपके मामले में!

मैंने पाया कि यह भी भ्रामक है, प्रलेखन स्पष्ट रूप से कहता है कि यह हेडर को बदल देता है, लेकिन यह नहीं है !
यह वास्तव में @Headers("hardcoded_string_of_liited_use")एनोटेशन के साथ जोड़ा जाता है

उम्मीद है की यह मदद करेगा ;)


1
मैंने डॉक्स में पाया कि यह एक मौजूदा हेडर को प्रतिस्थापित नहीं करता है: "ध्यान दें कि हेडर एक दूसरे को अधिलेखित नहीं करते हैं।" Check.github.io/retrofit और "Header Manipulation" की जाँच करें
Amio.io

37

स्वीकृत उत्तर रेट्रोफिट के पुराने संस्करण के लिए है। भविष्य के दर्शकों के लिए Retrofit2.0 के साथ ऐसा करने का तरीका एक कस्टम OkHttp क्लाइंट का उपयोग कर रहा है:

OkHttpClient httpClient = new OkHttpClient.Builder()
  .addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
      Builder ongoing = chain.request().newBuilder();
      ongoing.addHeader("Accept", "application/json;versions=1");
      if (isUserLoggedIn()) {
        ongoing.addHeader("Authorization", getToken());
      }
      return chain.proceed(ongoing.build());
    }
  })
  .build();

Retrofit retrofit = new Retrofit.Builder()
  // ... extra config
  .client(httpClient)
  .build();

आशा है कि यह किसी की मदद करता है। :)


5
Dagger2 के साथ आम उपयोग में, retrofit2 सिंगलटन होगा, इसलिए हर बार httpclient अभ्यस्त बनाया जाएगा। उस मामले में isUserLoggedIn () का मतलब नहीं है, क्या मैं सही हूं? केवल समाधान जिसे मैं वर्तमान में देख सकता हूं कि उपयोगकर्ता लॉगिन स्थिति बदलने पर रेट्रोफ़िट 2 पुनर्संरचना को मजबूर करना है, ताकि उपयुक्त हेडर जोड़ा या अनुरोध से हटा दिया जाए .. या कुछ स्पष्ट समाधान है जो मैं वर्तमान में नहीं देख सकता हूं? धन्यवाद।
बाजीकुसुको 16

2
@bajicdusko यह मेरा सटीक एक ही अनुमान है। क्या आपने हल खोज लिया? यह इतना बेकार, और अजीब लगता है कि पिछला संस्करण अधिक कुशल था।
deed02392

@ deed02392 आप एक सम्मिश्र सेट Interceptorकर सकते हैं जिसमें आप बाद के चरण में इंटरसेप्टर को सेट या रीसेट कर सकते हैं। हालाँकि, मैं तर्क दूंगा कि एक सिंगलटन के रूप में रेट्रोफिट होना शुरुआती अनुकूलन का संकेत हो सकता है। नया रेट्रोफिट उदाहरण बनाने के लिए कोई ओवरहेड नहीं है: github.com/square/retrofit/blob/master/retrofit/src/main/java/…
pablisco

मैंने वास्तव में इसके बारे में गहराई से नहीं सोचा था। मेरे पास कुछ ApiFactory वर्ग है जो dagger2 के साथ भी आरंभीकृत है, और यह रेट्रोफिट के आरंभ के लिए जिम्मेदार है। मैंने ApiFactory में एक सार्वजनिक विधि का खुलासा किया है जो जरूरत पड़ने पर रेट्रोफिट उदाहरण के पुनर्निमाण को मजबूर करता है, इसलिए यह काफी सरल है। मैं इसे गलत कर सकता हूं, लेकिन इसने काम किया है, और मैं इसका उपयोग केवल प्राधिकरण हेडर के लिए कर रहा हूं, इसलिए इसका उपयोग उपयोगकर्ता लॉगिन या लॉगआउट करते समय करता है। एक और विकल्प समापन बिंदु परिभाषा के अंदर @ हैडर एनोटेशन का उपयोग करना है, जो मेरे लिए स्वीकार्य नहीं था। मुझे इसे प्रत्येक समापन बिंदु पर सेट करना चाहिए जो व्यावहारिक नहीं है।
बाजीकुसुको

@pablisco मेरी समझ से आप Interceptorएक Retrofit2 उदाहरण बनाने के बाद एक बार आपको जोड़ या हटा नहीं सकते थे ।
deed02392

7

रेट्रोफिट 2.3.0

OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder
            .addInterceptor(new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    Request.Builder newRequest = request.newBuilder().header("Authorization", accessToken);
                    return chain.proceed(newRequest.build());
                }
            });

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(GithubService.BASE_URL)
            .client(okHttpClientBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

मैं इसे GitHub से कनेक्ट करने के लिए उपयोग कर रहा हूं।

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