रिट्रोफिट अनुरोध के शरीर में कच्चे पूरे JSON को POST कैसे करें?


284

यह प्रश्न पहले भी पूछा जा सकता था, लेकिन इसका उत्तर निश्चित रूप से नहीं दिया गया था। एक रेट्रोफिट रिक्वेस्ट के बॉडी के अंदर कच्चे JSON को कैसे पोस्ट करता है?

इसी तरह का प्रश्न यहाँ देखें । या क्या यह उत्तर सही है कि यह url एन्कोडेड और फ़ील्ड के रूप में पारित होना चाहिए ? मुझे वास्तव में उम्मीद नहीं है, क्योंकि मैं जिन सेवाओं से जुड़ रहा हूं, वे पोस्ट के शरीर में कच्चे JSON की अपेक्षा कर रहे हैं। वे JSON डेटा के लिए किसी विशेष फ़ील्ड को देखने के लिए सेट नहीं हैं।

मैं बस के साथ इस स्पष्ट करना चाहते हैं restperts एक बार और सभी के लिए। एक व्यक्ति ने रेट्रोफिट का उपयोग नहीं करने का जवाब दिया। अन्य वाक्य रचना का कुछ निश्चित नहीं था। एक और सोचता है कि यह किया जा सकता है, लेकिन केवल तभी जब इसका रूप url-encoded और किसी फ़ील्ड में रखा गया हो (जो मेरे मामले में स्वीकार्य नहीं है)। नहीं, मैं अपने एंड्रॉइड क्लाइंट के लिए सभी सेवाओं को फिर से कोड नहीं कर सकता। और हां, JSON सामग्री को फ़ील्ड प्रॉपर्टी मान के रूप में पार करने के बजाय रॉ JSON पोस्ट करने के लिए बड़ी परियोजनाओं में यह बहुत आम है। चलो इसे सही करें और आगे बढ़ें। क्या कोई प्रलेखन या उदाहरण को इंगित कर सकता है जो दिखाता है कि यह कैसे किया जाता है? या यह क्यों नहीं किया जा सकता है एक वैध कारण प्रदान करें।

अद्यतन: एक बात मैं 100% निश्चितता के साथ कह सकता हूं। आप Google के वॉली में ऐसा कर सकते हैं। यह सही में बनाया गया है। क्या हम इसे रेट्रोफिट में कर सकते हैं?


7
जेक व्हार्टन का पोस्ट सही है! उत्तर के रूप में चिह्नित करें!
edotassi

1
आप jsonObject का बेहतर उपयोग कर सकते हैं।
सुपरयूजर

RequestBodyइस तरह के साथ पूरी तरह से काम करता है -> RequestBody body = RequestBody.create(MediaType.parse("text/plain"), text);विस्तृत उत्तर के लिए futurestud.io/tutorials/…
किडस टेकेस्टे मार्क

जवाबों:


461

@Bodyएनोटेशन एक ही अनुरोध शरीर को परिभाषित करता है।

interface Foo {
  @POST("/jayson")
  FooResponse postJson(@Body FooRequest body);
}

चूंकि रेट्रोफिट डिफ़ॉल्ट रूप से Gson का उपयोग करता है, FooRequestउदाहरणों को अनुरोध के एकमात्र निकाय के रूप में JSON के रूप में क्रमबद्ध किया जाएगा।

public class FooRequest {
  final String foo;
  final String bar;

  FooRequest(String foo, String bar) {
    this.foo = foo;
    this.bar = bar;
  }
}

इसके साथ कॉलिंग:

FooResponse = foo.postJson(new FooRequest("kit", "kat"));

निम्नलिखित निकाय प्राप्त करेंगे:

{"foo":"kit","bar":"kat"}

Gson डॉक्स कैसे वस्तु क्रमांकन काम करता है पर बहुत अधिक है।

अब, यदि आप वास्तव में "रॉ" JSON को स्वयं शरीर के रूप में भेजना चाहते हैं (लेकिन इसके लिए Gson का उपयोग करें!) जो आप उपयोग कर सकते हैं TypedInput:

interface Foo {
  @POST("/jayson")
  FooResponse postRawJson(@Body TypedInput body);
}

TypedInput को "एक संबंधित माइम प्रकार के साथ बाइनरी डेटा" के रूप में परिभाषित किया गया है। उपरोक्त घोषणा के साथ कच्चे डेटा को आसानी से भेजने के दो तरीके हैं:

  1. कच्ची बाइट और JSON माइम प्रकार भेजने के लिए टाइप करेंबेयर का उपयोग करें :

    String json = "{\"foo\":\"kit\",\"bar\":\"kat\"}";
    TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8"));
    FooResponse response = foo.postRawJson(in);
  2. एक वर्ग बनाने के लिए उपवर्ग टाइपिंग स्ट्रिंगTypedJsonString :

    public class TypedJsonString extends TypedString {
      public TypedJsonString(String body) {
        super(body);
      }
    
      @Override public String mimeType() {
        return "application/json";
      }
    }

    और फिर # 1 के समान उस वर्ग के एक उदाहरण का उपयोग करें।


5
वैसे भी, क्या इस तरह से इसे बिना प्याज़ के बनाने के लिए है?
सुपरयूजर

28
यह रेट्रोफ़िट पर काम नहीं कर रहा है। 2. टाइप किए गए इनपुट और टाइपेडस्ट्रिंग कक्षाएं हटा दी गईं।
अहमद हेगाज़ी

2
@jakewharton TypedStringजब से इसे हटाया गया है हम इसके लिए क्या कर सकते हैं ?
जारेड बुरो

12
Retrofit2 के लिए, आप RequestBodyएक कच्चा शरीर बनाने के लिए उपयोग कर सकते हैं ।
13

4
मुझे यह अपवाद मिल रहा हैjava.lang.IllegalArgumentException: Unable to create @Body converter for class MatchAPIRequestBody (parameter #1)
शाज़ील अफज़ल २४'१

155

कक्षाओं के बजाय हम HashMap<String, Object>उदाहरण के लिए शरीर के मापदंडों को भेजने के लिए सीधे उपयोग भी कर सकते हैं

interface Foo {
  @POST("/jayson")
  FooResponse postJson(@Body HashMap<String, Object> body);
}

2
उस समय आप HashMap <String, Object> जैसे हैश मैप बना सकते हैं, यह थोड़े जटिल सरणियों और ऑब्जेक्ट्स JSON बनाने के लिए संभव हो सकता है।
शिक्षार्थी

2
यह उत्कृष्ट है यदि आप किसी प्रकार के पीओजेओ से बंधे नहीं रहना चाहते हैं।
टिम अप

2
@ क्या आप रेट्रोफिट का उपयोग करके जसन ऑब्जेक्ट नहीं भेज सकते ... आप पूजो या मेरे उत्तर का पालन करें ... यह रेट्रोफिट की प्रकृति है। यदि आप इस बारे में अधिक चाहते हैं कि जेक व्हार्टन वह रेट्रोफिट डेवलपर आदमी है, तो उसका जवाब भी पूजो के साथ है। ।
शिक्षार्थी

5
मैं IllegalArgumentException: Unable to create @Body converter for java.util.HashMap<java.lang.String, java.lang.Object>मोशी के साथ मिलता हूं । मुझे लगता है कि इस काम के लिए Gson की जरूरत है
osrl

2
अगर कोटलिन का उपयोग करते हुए
peresisUser

148

हां मुझे पता है कि देर हो चुकी है, लेकिन किसी को इससे फायदा होगा।

Retrofit2 का उपयोग करना:

मुझे कल रात इस समस्या का सामना करना पड़ा, वॉली से रेट्रोफिट 2 (और ओपी राज्यों के रूप में, यह वॉली में सही तरीके से बनाया गया था JsonObjectRequest) से पलायन कर रहा था , और हालांकि जेक का जवाब रेट्रोफिट 1.9 के लिए सही है , रिट्रोफिट 2 में नहीं है TypedString

मेरे केस को भेजने की आवश्यकता है Map<String,Object>जिसमें कुछ शून्य मान हो सकते हैं, एक JSONObject में परिवर्तित हो सकता है (जो कि साथ नहीं चलेगा @FieldMap, न ही विशेष वर्ण, कुछ परिवर्तित हो जाते हैं), इसलिए @bnorms संकेत का अनुसरण करें, और जैसा कि स्क्वायर द्वारा कहा गया है :

किसी ऑब्जेक्ट को @Body एनोटेशन के साथ HTTP अनुरोध निकाय के रूप में उपयोग के लिए निर्दिष्ट किया जा सकता है।

ऑब्जेक्ट को रेट्रोफिट उदाहरण पर निर्दिष्ट कनवर्टर का उपयोग करके भी परिवर्तित किया जाएगा। यदि कोई कन्वर्टर नहीं जोड़ा जाता है, तो केवल RequestBody का उपयोग किया जा सकता है।

तो यह एक विकल्प का उपयोग कर रहा है RequestBodyऔर ResponseBody:

अपने इंटरफ़ेस के @Bodyसाथ उपयोग करेंRequestBody

public interface ServiceApi
{
    @POST("prefix/user/{login}")
    Call<ResponseBody> login(@Path("login") String postfix, @Body RequestBody params);  
}

अपने कॉलिंग पॉइंट में RequestBody, यह मीडियाटाइप बताते हुए, बनाएं और अपने मैप को उचित प्रारूप में बदलने के लिए JSONObject का उपयोग करें:

Map<String, Object> jsonParams = new ArrayMap<>();
//put something inside the map, could be null
jsonParams.put("code", some_code);

RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),(new JSONObject(jsonParams)).toString());
//serviceCaller is the interface initialized with retrofit.create...
Call<ResponseBody> response = serviceCaller.login("loginpostfix", body);
      
response.enqueue(new Callback<ResponseBody>()
    {
        @Override
        public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse)
        {
            try
            {
             //get your response....
              Log.d(TAG, "RetroFit2.0 :RetroGetLogin: " + rawResponse.body().string());
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable throwable)
        {
        // other stuff...
        }
    });

आशा है कि यह किसी की मदद करता है!


उपरोक्त का एक सुरुचिपूर्ण कोटलिन संस्करण, आपके शेष एप्लिकेशन कोड में JSON रूपांतरण से पैरामीटर को अलग करने की अनुमति देता है:

interface ServiceApi {

    fun login(username: String, password: String) =
            jsonLogin(createJsonRequestBody(
                "username" to username, "password" to password))

    @POST("/api/login")
    fun jsonLogin(@Body params: RequestBody): Deferred<LoginResult>

    private fun createJsonRequestBody(vararg params: Pair<String, String>) =
            RequestBody.create(
                okhttp3.MediaType.parse("application/json; charset=utf-8"), 
                JSONObject(mapOf(*params)).toString())

}

2
हाँ, मैं इसके लिए बहुत सारी जटिल प्रतिक्रियाएँ देख रहा हूँ। यदि आप Retrofit2 का उपयोग कर रहे हैं और वॉली का काम करना चाहते हैं JsonObjectRequest, तो बस आपको यह करने की आवश्यकता है। अच्छा उत्तर।
विकू

2
रिट्रोफिट सभी json ऑब्जेक्ट्स के शीर्ष पर "nameValuePairs" नामक एक कुंजी जोड़ता है। मैं इसे कैसे हटा सकता हूं @ टॉमी
nr5

1
धन्यवाद! इससे मेरी समस्या हल हो गई। अब मैं सीधे POJO बनाए बिना JSONObject भेज सकता हूं।
इरफान GLMPR

1
यह एकमात्र समाधान है जिसने मुझे post a null valueअनुरोध में एक संपत्ति में मदद की है जो अन्यथा अनदेखा हो रही थी।
शुभ्रल

मुझे पता है कि मुझे देर हो रही है लेकिन jsonParams.put("code", some_code);तीसरी पंक्ति में क्या है ?
नवीन निरौला

81

में Retrofit2 , जब आप में कच्चे आप का उपयोग करना चाहिए अपने मानकों को भेजना चाहते हैं Scalars

पहले इसे अपनी श्रेणी में जोड़ें:

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'
compile 'com.squareup.retrofit2:converter-scalars:2.3.0'

आपका इंटरफ़ेस

public interface ApiInterface {

    String URL_BASE = "http://10.157.102.22/rest/";

    @Headers("Content-Type: application/json")
    @POST("login")
    Call<User> getUser(@Body String body);

}

गतिविधि

   public class SampleActivity extends AppCompatActivity implements Callback<User> {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sample);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiInterface.URL_BASE)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        ApiInterface apiInterface = retrofit.create(ApiInterface.class);


        // prepare call in Retrofit 2.0
        try {
            JSONObject paramObject = new JSONObject();
            paramObject.put("email", "sample@gmail.com");
            paramObject.put("pass", "4384984938943");

            Call<User> userCall = apiInterface.getUser(paramObject.toString());
            userCall.enqueue(this);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }


    @Override
    public void onResponse(Call<User> call, Response<User> response) {
    }

    @Override
    public void onFailure(Call<User> call, Throwable t) {
    }
}

10
यहाँ ट्रिक गसन से पहले स्केलर एडॉप्टर है, अन्यथा गन्स आपके मैन्युअल रूप से क्रमबद्ध JSON को एक स्ट्रिंग में लपेट देगा।
TWStStrrob

2
jonathan-nolasco-barrientos आपको बदलना होगा .baseUrl (ApiInterface.ENDPOINT) tobaseUrl (ApiInterface.URL_BASE)
मिलाद

2
जब आप उपयोग करते हैं GsonConverterFactory, तो .toString()यह आवश्यक नहीं है। आप घोषणा कर सकते हैं Call<User> getUser(@Body JsonObject body);का उपयोग कर JsonObjectके बजाय JSONObjectऔर पारित paramObjectसीधे। यह ठीक काम करेगा।
इगोर डे लोरेंज़ी

1
@IgordeLorenzi मेरा मुद्दा हल कर रहा है, क्योंकि मैं वसंत बूट का उपयोग कर रहा हूँ केवल जसन को पुनः प्राप्त करने के लिए Gson से JsonObject काम करता है ठीक है
haidarvm

1
@IgordeLorenzi वहाँ एक अंतर है जो एक बेहतर JSONObject या JsonObject है जिसका उपयोग स्केलेर्स के साथ किया जाता है।
सुमित शुक्ला

44

प्रयोग JsonObjectयह तरीका है:

  1. अपना इंटरफ़ेस इस तरह बनाएँ:

    public interface laInterfaz{ 
        @POST("/bleh/blah/org")
        void registerPayer(@Body JsonObject bean, Callback<JsonObject> callback);
    }
  2. Jsons संरचना के लिए JsonObject रिकॉर्डिंग करें।

    JsonObject obj = new JsonObject();
    JsonObject payerReg = new JsonObject();
    payerReg.addProperty("crc","aas22");
    payerReg.addProperty("payerDevManufacturer","Samsung");
    obj.add("payerReg",payerReg);
    /*json/*
        {"payerReg":{"crc":"aas22","payerDevManufacturer":"Samsung"}}
    /*json*/
  3. सेवा को कॉल करें:

    service.registerPayer(obj, callBackRegistraPagador);
    
    Callback<JsonObject> callBackRegistraPagador = new Callback<JsonObject>(){
        public void success(JsonObject object, Response response){
            System.out.println(object.toString());
        }
    
        public void failure(RetrofitError retrofitError){
            System.out.println(retrofitError.toString());
        }
    };

और वह अपनी! मेरी व्यक्तिगत राय में, यह पॉज़ोस बनाने और वर्ग की गड़बड़ी के साथ काम करने से बहुत बेहतर है। यह एक बहुत अधिक क्लीनर है।


1
क्या होगा अगर मैं jsonobject वर्ग में निर्दिष्ट मान नहीं भेजना चाहता। मैं उसके लिए कौन से एनाउंसमेंट का उपयोग कर सकता हूं?
अली गुलरेली

1
जैसा कि आप उपरोक्त उदाहरण देख सकते हैं ... JsonObject जैसा कि यह एक ऑब्जेक्ट है, किसी भी एनोटेशन का उपयोग नहीं करता है। आपके मामले में यदि आप विशिष्ट मूल्य नहीं भेजना चाहते हैं, तो आप शायद इसे संपत्ति के रूप में नहीं जोड़ सकते हैं ...
सुपरयूजर

1
मेरा मतलब है कि मैं उस मूल्य को नहीं भेजना चाहता जो कक्षा में घोषित किया गया है। Btw मैंने इस समस्या को ठीक किया। इसके लिए एक एनोटेशन था कि किस नाम को उजागर किया जाए।
अली गुलरेली

2
यह सबसे लचीला तरीका है। यदि आप नहीं जानते हैं कि आपके पास कितनी वस्तुएं हैं, तो भी आप अपने json ऑब्जेक्ट का निर्माण कर सकते हैं या यदि आप नहीं जानते हैं कि वे मेरे से +1 का नाम रखते हैं
स्टोचो एंड्रीव

1
im त्रुटि प्राप्त करना सेवा विधियाँ शून्य नहीं हो सकती हैं। विधि के लिए APIServices.signUpUser
Erum

11

मैं विशेष रूप से ऊपरTypedString उपवर्ग के जेक के सुझाव को पसंद करता हूं । आप वास्तव में POST डेटा के प्रकार के आधार पर विभिन्न प्रकार के उपवर्ग बना सकते हैं जिन्हें आप पुश करने की योजना बना रहे हैं, प्रत्येक के अनुरूप ट्वीक्स का अपना कस्टम सेट है।

आपके पास अपने रिट्रोफिट एपीआई में अपने JSON POST विधियों में एक हेडर एनोटेशन जोड़ने का विकल्प भी है ...

@Headers( "Content-Type: application/json" )
@POST("/json/foo/bar/")
Response fubar( @Body TypedString sJsonBody ) ;

… लेकिन एक उपवर्ग का उपयोग करना अधिक स्पष्ट रूप से स्व-दस्तावेजीकरण है।

@POST("/json/foo/bar")
Response fubar( @Body TypedJsonString jsonBody ) ;

1
JW सुझाव से टाइप किए गए JsonString का उपयोग करके एक स्पष्ट उदाहरण के साथ दिन को बचाया
miroslavign

10

1) निर्भरता जोड़ें-

 compile 'com.google.code.gson:gson:2.6.2'
compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'

2) आपी हैंडलर क्लास करें

    public class ApiHandler {


  public static final String BASE_URL = "URL";  

    private static Webservices apiService;

    public static Webservices getApiService() {

        if (apiService == null) {

           Gson gson = new GsonBuilder()
                    .setLenient()
                    .create();
            Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create(gson)).baseUrl(BASE_URL).build();

            apiService = retrofit.create(Webservices.class);
            return apiService;
        } else {
            return apiService;
        }
    }


}

3) Json स्कीमा 2 पूजो से बीन क्लासेस बनाएं

याद रखें
-टर्ज भाषा: जावा- स्रोत प्रकार: JSON -nnotation style: Gson -select इसमें गेटर्स और सेटर शामिल करें -क्योंकि आप चुन सकते हैं अतिरिक्त गुणों की अनुमति दें

http://www.jsonschema2pojo.org/

4) इंटरफ़ेस फ़्रि एपी कॉलिंग करें

    public interface Webservices {

@POST("ApiUrlpath")
    Call<ResponseBean> ApiName(@Body JsonObject jsonBody);

}

यदि आपके पास प्रपत्र-डेटा पैरामीटर हैं, तो नीचे पंक्ति जोड़ें

@Headers("Content-Type: application/x-www-form-urlencoded")

प्रपत्र-डेटा पैरामीटर के लिए अन्य तरीका इस लिंक की जाँच करें

5) पैरामीटर के रूप में बॉडी में जाने के लिए JsonObject बनाते हैं

 private JsonObject ApiJsonMap() {

    JsonObject gsonObject = new JsonObject();
    try {
        JSONObject jsonObj_ = new JSONObject();
        jsonObj_.put("key", "value");
        jsonObj_.put("key", "value");
        jsonObj_.put("key", "value");


        JsonParser jsonParser = new JsonParser();
        gsonObject = (JsonObject) jsonParser.parse(jsonObj_.toString());

        //print parameter
        Log.e("MY gson.JSON:  ", "AS PARAMETER  " + gsonObject);

    } catch (JSONException e) {
        e.printStackTrace();
    }

    return gsonObject;
}

६) आपी को ऐसे ही कॉल करें

private void ApiCallMethod() {
    try {
        if (CommonUtils.isConnectingToInternet(MyActivity.this)) {
            final ProgressDialog dialog;
            dialog = new ProgressDialog(MyActivity.this);
            dialog.setMessage("Loading...");
            dialog.setCanceledOnTouchOutside(false);
            dialog.show();

            Call<ResponseBean> registerCall = ApiHandler.getApiService().ApiName(ApiJsonMap());
            registerCall.enqueue(new retrofit2.Callback<ResponseBean>() {
                @Override
                public void onResponse(Call<ResponseBean> registerCall, retrofit2.Response<ResponseBean> response) {

                    try {
                        //print respone
                        Log.e(" Full json gson => ", new Gson().toJson(response));
                        JSONObject jsonObj = new JSONObject(new Gson().toJson(response).toString());
                        Log.e(" responce => ", jsonObj.getJSONObject("body").toString());

                        if (response.isSuccessful()) {

                            dialog.dismiss();
                            int success = response.body().getSuccess();
                            if (success == 1) {



                            } else if (success == 0) {



                            }  
                        } else {
                            dialog.dismiss();


                        }


                    } catch (Exception e) {
                        e.printStackTrace();
                        try {
                            Log.e("Tag", "error=" + e.toString());

                            dialog.dismiss();
                        } catch (Resources.NotFoundException e1) {
                            e1.printStackTrace();
                        }

                    }
                }

                @Override
                public void onFailure(Call<ResponseBean> call, Throwable t) {
                    try {
                        Log.e("Tag", "error" + t.toString());

                        dialog.dismiss();
                    } catch (Resources.NotFoundException e) {
                        e.printStackTrace();
                    }
                }

            });

        } else {
            Log.e("Tag", "error= Alert no internet");


        }
    } catch (Resources.NotFoundException e) {
        e.printStackTrace();
    }
}

9

मैंने पाया कि जब आप एक कंपाउंड ऑब्जेक्ट को @Bodyपरमेस के रूप में उपयोग करते हैं , तो यह रेट्रोफिट्स GSONConverter(आप जो उपयोग कर रहे हैं उस धारणा के तहत) के साथ अच्छी तरह से काम नहीं कर सकता है । इसके साथ काम करते समय आपको उपयोग करना है JsonObjectऔर नहीं JSONObject, यह इसके NameValueParamsबारे में क्रिया किए बिना जोड़ता है - आप केवल यह देख सकते हैं कि यदि आप लॉगिंग इंटरसेप्टर की एक और निर्भरता जोड़ते हैं, और अन्य शीनिगान।

तो मुझे इससे निपटने के लिए सबसे अच्छा तरीका क्या मिला RequestBody। आप RequestBodyएक साधारण एपीआई कॉल के साथ अपनी वस्तु को चालू करते हैं और इसे लॉन्च करते हैं। मेरे मामले में मैं एक मानचित्र परिवर्तित कर रहा हूं:

   val map = HashMap<String, Any>()
        map["orderType"] = orderType
        map["optionType"] = optionType
        map["baseAmount"] = baseAmount.toString()
        map["openSpotRate"] = openSpotRate.toString()
        map["premiumAmount"] = premiumAmount.toString()
        map["premiumAmountAbc"] = premiumAmountAbc.toString()
        map["conversionSpotRate"] = (premiumAmountAbc / premiumAmount).toString()
        return RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONObject(map).toString())

और यह कॉल है:

 @POST("openUsvDeal")
fun openUsvDeal(
        @Body params: RequestBody,
        @Query("timestamp") timeStamp: Long,
        @Query("appid") appid: String = Constants.APP_ID,
): Call<JsonObject>

2
खैर इसने रात भर गुगली करने के बाद मेरी मदद की।
W4R10CK

8

ScalarsConverterFactory को फिर से जोड़ने के लिए जोड़ें:

में:

implementation'com.squareup.retrofit2:converter-scalars:2.5.0'

आपका रेट्रोफिट:

retrofit = new Retrofit.Builder()
            .baseUrl(WEB_DOMAIN_MAIN)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

स्ट्रिंग में अपने कॉल इंटरफ़ेस @ बॉडी पैरामीटर को बदलें, जोड़ना न भूलें @Headers("Content-Type: application/json"):

@Headers("Content-Type: application/json")
@POST("/api/getUsers")
Call<List<Users>> getUsers(@Body String rawJsonString);

अब आप कच्चे json पोस्ट कर सकते हैं।


6

यदि आप हर एपीआई कॉल के लिए पूजो क्लास नहीं बनाना चाहते हैं तो आप हैशमैप का उपयोग कर सकते हैं।

HashMap<String,String> hashMap=new HashMap<>();
        hashMap.put("email","this@gmail.com");
        hashMap.put("password","1234");

और फिर इस तरह भेजें

Call<JsonElement> register(@Body HashMap registerApiPayload);

4

इतने प्रयास के बाद, पाया कि मूल अंतर आपको पैरामीटर के JsonObjectबजाय भेजने की आवश्यकता है JSONObject


मैं भी यही गलती कर रहा था: पी
मेहताब अहमद

4

json भेजने के लिए निम्नलिखित का उपयोग करें

final JSONObject jsonBody = new JSONObject();
    try {

        jsonBody.put("key", "value");

    } catch (JSONException e){
        e.printStackTrace();
    }
    RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),(jsonBody).toString());

और इसे url में पास करें

@Body RequestBody key

4

शीर्ष उत्तर के आधार पर, मेरे पास हर अनुरोध के लिए पीओजेओ नहीं बनाने का उपाय है।

उदाहरण के लिए, मैं इस JSON पोस्ट करना चाहते हैं।

{
    "data" : {
        "mobile" : "qwer",
        "password" : "qwer"
    },
    "commom" : {}
}

फिर, मैं इस तरह एक सामान्य वर्ग बनाता हूं:

import java.util.Map;
import java.util.HashMap;

public class WRequest {

    Map<String, Object> data;
    Map<String, Object> common;

    public WRequest() {
        data = new HashMap<>();
        common = new HashMap<>();
    }
}

अंत में, जब मुझे एक जैसन की आवश्यकता होगी

WRequest request = new WRequest();
request.data.put("type", type);
request.data.put("page", page);

अनुरोध के रूप में चिह्नित एनोटेशन @Bodyफिर रेट्रोफिट को पास कर सकता है।


4

यदि आप अतिरिक्त कक्षाएं नहीं बनाना चाहते हैं या JSONObjectआप का उपयोग कर सकते हैं एक HashMap

रेट्रोफिट इंटरफ़ेस:

@POST("/rest/registration/register")
fun signUp(@Body params: HashMap<String, String>): Call<ResponseBody>

कॉल करें:

val map = hashMapOf(
    "username" to username,
    "password" to password,
    "firstName" to firstName,
    "surname" to lastName
)

retrofit.create(TheApi::class.java)
     .signUp(map)
     .enqueue(callback)

3

रिट्रोफिट में कच्चे जोंस भेजने के लिए आवश्यक चीजें।

1) निम्नलिखित हेडर को जोड़ना सुनिश्चित करें और किसी अन्य डुप्लिकेट हेडर को हटा दें। चूंकि, रेट्रोफिट के आधिकारिक दस्तावेज पर वे विशेष रूप से उल्लेख करते हैं-

ध्यान दें कि हेडर एक दूसरे को ओवरराइट नहीं करते हैं। एक ही नाम वाले सभी हेडर अनुरोध में शामिल किए जाएंगे।

@Headers({"Content-Type: application/json"})

2) ए। यदि आप एक कन्वर्टर फैक्ट्री का उपयोग कर रहे हैं, तो आप स्ट्रिंग, JSONObject, JsonObject और यहां तक ​​कि एक POJO के रूप में अपने json को पास कर सकते हैं। यह भी जाँच की, ScalarConverterFactoryआवश्यक नहीं है केवल GsonConverterFactoryकाम करता है।

@POST("/urlPath")
@FormUrlEncoded
Call<Response> myApi(@Header("Authorization") String auth, @Header("KEY") String key, 
                     @Body JsonObject/POJO/String requestBody);

2) बी। यदि आप किसी कन्वर्टर फैक्ट्री का उपयोग नहीं कर रहे हैं, तो आप ओक्त्रॉट के रिक्वेस्ट बॉडी का उपयोग अवश्य करें क्योंकि रेट्रोफिट का प्रलेखन कहता है-

ऑब्जेक्ट को रेट्रोफिट उदाहरण पर निर्दिष्ट कनवर्टर का उपयोग करके भी परिवर्तित किया जाएगा। यदि कोई कन्वर्टर नहीं जोड़ा जाता है, तो केवल RequestBody का उपयोग किया जा सकता है।

RequestBody requestBody=RequestBody.create(MediaType.parse("application/json; charset=utf-8"),jsonString);

@POST("/urlPath")
@FormUrlEncoded
Call<Response> myApi(@Header("Authorization") String auth, @Header("KEY") String key, 
                 @Body RequestBody requestBody);

3) सफलता !!


2

यह वह है जो मुझे retrofit 2.6.2 के वर्तमान संस्करण के लिए काम करता है ,

सबसे पहले, हमें अपने ग्रेडल निर्भरता की सूची में एक स्केलर्स कन्वर्टर जोड़ने की जरूरत है, जो कि java.lang को बदलने में ध्यान रखेगा। वस्तुओं को पाठ / सादे अनुरोध निकायों में,

implementation'com.squareup.retrofit2:converter-scalars:2.6.2'

फिर, हमें अपने रेट्रोफिट बिल्डर को एक कन्वर्टर फैक्ट्री को पास करना होगा। यह बाद में Retrofit को बताएगा कि सेवा में दिए गए @Body पैरामीटर को कैसे परिवर्तित किया जाए।

private val retrofitBuilder: Retrofit.Builder by lazy {
    Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(ScalarsConverterFactory.create())
        .addConverterFactory(GsonConverterFactory.create())
}

नोट: मेरे रेट्रोफिट बिल्डर में मेरे पास दो कन्वर्टर्स हैं Gsonऔर Scalarsआप दोनों का उपयोग कर सकते हैं लेकिन Json बॉडी को भेजने के लिए हमें ध्यान केंद्रित करने की आवश्यकता है Scalarsयदि आपको Gsonइसे हटाने की आवश्यकता नहीं है

फिर एक स्ट्रिंग बॉडी पैरामीटर के साथ रिट्रोफिट सेवा।

@Headers("Content-Type: application/json")
@POST("users")
fun saveUser(@Body   user: String): Response<MyResponse>

फिर JSON बॉडी बनाएं

val user = JsonObject()
 user.addProperty("id", 001)
 user.addProperty("name", "Name")

अपनी सेवा को बुलाओ

RetrofitService.myApi.saveUser(user.toString())

2

✅✅✅✅✅✅✅✅✅✅✅✅ कार्य समाधान ✅✅✅✅✅✅✅✅✅✅✅✅

जबकि इसका निर्माण OkHttpClient रेट्रोफिट के लिए किया जाएगा।

इस तरह एक इंटरसेप्टर जोड़ें।

 private val httpClient = OkHttpClient.Builder()
        .addInterceptor (other interceptors)
        ........................................

        //This Interceptor is the main logging Interceptor
        .addInterceptor { chain ->
            val request = chain.request()
            val jsonObj = JSONObject(Gson().toJson(request))

            val requestBody = (jsonObj
            ?.getJSONObject("tags")
            ?.getJSONObject("class retrofit2.Invocation")
            ?.getJSONArray("arguments")?.get(0) ?: "").toString()
            val url = jsonObj?.getJSONObject("url")?.getString("url") ?: ""

            Timber.d("gsonrequest request url: $url")
            Timber.d("gsonrequest body :$requestBody")

            chain.proceed(request)
        }

        ..............
        // Add other configurations
        .build()

अब आप अपने हर रेट्रोफिट कॉल का यूआरएल और अनुरोध शरीर लॉग इन किया जाएगा में Logcatइससे छान लें"gsonrequest"


1

मैंने यह कोशिश की: जब आप अपना रेट्रोफिट उदाहरण बना रहे हैं, तो इस कन्वर्टर कारखाने को रेट्रोफिट बिल्डर में जोड़ें:

gsonBuilder = new GsonBuilder().serializeNulls()     
your_retrofit_instance = Retrofit.Builder().addConverterFactory( GsonConverterFactory.create( gsonBuilder.create() ) )

1

TommySM उत्तर (पिछले देखें) पर आधारित मेरी समस्या का समाधान किया। लेकिन मुझे लॉगिन करने की आवश्यकता नहीं थी, मैंने इस तरह https ग्राफकॉल एपीआई के परीक्षण के लिए रेट्रोफिट 2 का उपयोग किया:

  1. Json एनोटेशन (आयात jackson.annotation.JsonProperty) की मदद से मेरा बेसरास्पॉन्ड वर्ग परिभाषित किया।

    public class MyRequest {
        @JsonProperty("query")
        private String query;
    
        @JsonProperty("operationName")
        private String operationName;
    
        @JsonProperty("variables")
        private String variables;
    
        public void setQuery(String query) {
            this.query = query;
        }
    
        public void setOperationName(String operationName) {
            this.operationName = operationName;
        }
    
        public void setVariables(String variables) {
            this.variables = variables;
        }
    }
  2. इंटरफ़ेस में कॉल प्रक्रिया को परिभाषित करें:

    @POST("/api/apiname")
    Call<BaseResponse> apicall(@Body RequestBody params);
  3. परीक्षण के शरीर में एपिकॉल कहा जाता है: MyRequest प्रकार का एक चर बनाएं (उदाहरण के लिए "myLittleRequest")।

    Map<String, Object> jsonParams = convertObjectToMap(myLittleRequest);
    RequestBody body = 
         RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),
                        (new JSONObject(jsonParams)).toString());
    response = hereIsYourInterfaceName().apicall(body).execute();

0

यहां दिए गए उत्तरों पर अधिक स्पष्टता के लिए, यह है कि आप एक्सटेंशन फ़ंक्शन का उपयोग कैसे कर सकते हैं। यह केवल अगर आप कोटलिन का उपयोग कर रहे हैं

आप उपयोग कर रहे हैं com.squareup.okhttp3:okhttp:4.0.1की वस्तुओं बनाने के पुराने तरीकों MediaType और RequestBody पदावनत किया गया है और में नहीं किया जा सकता Kotlin

यदि आप अपने स्ट्रिंग्स से MediaType ऑब्जेक्ट और ResponseBody ऑब्जेक्ट प्राप्त करने के लिए एक्सटेंशन फ़ंक्शंस का उपयोग करना चाहते हैं, तो सबसे पहले निम्न पंक्तियों को उस वर्ग में जोड़ें जिसमें आप उनका उपयोग करने की अपेक्षा करते हैं।

import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody

अब आप सीधे इस तरह MediaType का एक ऑब्जेक्ट प्राप्त कर सकते हैं

val mediaType = "application/json; charset=utf-8".toMediaType()

RequestBody का एक ऑब्जेक्ट प्राप्त करने के लिए पहले उस JSONObject को कनवर्ट करें जिसे आप इस तरह से एक स्ट्रिंग में भेजना चाहते हैं। आपको इसके लिए MediaType ऑब्जेक्ट पास करना होगा।

val requestBody = myJSONObject.toString().toRequestBody(mediaType)

0

मैं नीचे दिए गए कोड (रिट्रोफिट भाग के लिए) लिखे गए डेटा को भेजने और प्राप्त करने के लिए वॉली और रेट्रोफिट की गति की तुलना करना चाहता था।

पहली निर्भरता:

dependencies {
     implementation 'com.squareup.retrofit2:retrofit:2.4.0'
     implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
}

फिर इंटरफ़ेस:

 public interface IHttpRequest {

    String BaseUrl="https://example.com/api/";

    @POST("NewContract")
    Call<JsonElement> register(@Body HashMap registerApiPayload);
}

और सर्वर पर डेटा पोस्ट करने के लिए पैरामीटर सेट करने के लिए एक फ़ंक्शन (मेनऐक्टिविटी में):

private void Retrofit(){

    Retrofit retrofitRequest = new Retrofit.Builder()
            .baseUrl(IHttpRequest.BaseUrl)
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    // set data to send
    HashMap<String,String> SendData =new HashMap<>();
    SendData.put("token","XYXIUNJHJHJHGJHGJHGRTYTRY");
    SendData.put("contract_type","0");
    SendData.put("StopLess","37000");
    SendData.put("StopProfit","48000");

    final IHttpRequest request=retrofitRequest.create(IHttpRequest.class);

    request.register(SendData).enqueue(new Callback<JsonElement>() {
        @Override
        public void onResponse(Call<JsonElement> call, Response<JsonElement> response) {
            if (response.isSuccessful()){
                Toast.makeText(getApplicationContext(),response.body().toString(),Toast.LENGTH_LONG).show();
            }
        }

        @Override
        public void onFailure(Call<JsonElement> call, Throwable t) {

        }
    });

}

और मुझे अपने मामले में वॉली से ज्यादा तेजी से रिट्रोफिट मिला।

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