How to POST raw whole JSON in the body of a Retrofit request?

前端 未结 23 2383
面向向阳花
面向向阳花 2020-11-22 00:57

This question may have been asked before but no it was not definitively answered. How exactly does one post raw whole JSON inside the body of a Retrofit request?

See

相关标签:
23条回答
  • 2020-11-22 01:47

    1)Add dependencies-

     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) make Api Handler class

        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)make bean classes from Json schema 2 pojo

    Remember
    -Target language : Java -Source type : JSON -Annotation style : Gson -select Include getters and setters -also you may select Allow additional properties

    http://www.jsonschema2pojo.org/

    4)make interface fro api calling

        public interface Webservices {
    
    @POST("ApiUrlpath")
        Call<ResponseBean> ApiName(@Body JsonObject jsonBody);
    
    }
    

    if you have a form-data parameters then add below line

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

    Other way for form-data parameter check this link

    5)make JsonObject for passing in to body as parameter

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

    6) Call Api Like this

    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();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 01:47

    This is what works me for the current version of retrofit 2.6.2,

    First of all, we need to add a Scalars Converter to the list of our Gradle dependencies, which would take care of converting java.lang.String objects to text/plain request bodies,

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

    Then, we need to pass a converter factory to our Retrofit builder. It will later tell Retrofit how to convert the @Body parameter passed to the service.

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

    Note: In my retrofit builder i have two converters Gson and Scalars you can use both of them but to send Json body we need to focus Scalars so if you don't need Gson remove it

    Then Retrofit service with a String body parameter.

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

    Then create the JSON body

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

    Call your service

    RetrofitService.myApi.saveUser(user.toString())
    
    0 讨论(0)
  • 2020-11-22 01:48

    use following to send 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());
    

    and pass it to url

    @Body RequestBody key
    
    0 讨论(0)
  • 2020-11-22 01:48

    Things required to send raw json in Retrofit.

    1) Make sure to add the following header and remove any other duplicate header. Since, on Retrofit's official documentation they specifically mention-

    Note that headers do not overwrite each other. All headers with the same name will be included in the request.

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

    2) a. If you are using a converter factory you can pass your json as a String, JSONObject, JsonObject and even a POJO. Also have checked, having ScalarConverterFactory is not necessary only GsonConverterFactory does the job.

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

    2) b. If you are NOT using any converter factory then you MUST use okhttp3's RequestBody as Retrofit's documentation says-

    The object will also be converted using a converter specified on the Retrofit instance. If no converter is added, only RequestBody can be used.

    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) Success!!

    0 讨论(0)
  • 2020-11-22 01:49

    You can use hashmap if you don't want to create pojo class for every API call.

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

    And then send like this

    Call<JsonElement> register(@Body HashMap registerApiPayload);
    
    0 讨论(0)
  • 2020-11-22 01:49

    After so much effort, found that the basic difference is you need to send the JsonObject instead of JSONObject as parameter.

    0 讨论(0)
提交回复
热议问题