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

前端 未结 23 2323
面向向阳花
面向向阳花 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:40

    I tried this: When you are creating your Retrofit instance, add this converter factory to the retrofit builder:

    gsonBuilder = new GsonBuilder().serializeNulls()     
    your_retrofit_instance = Retrofit.Builder().addConverterFactory( GsonConverterFactory.create( gsonBuilder.create() ) )
    
    0 讨论(0)
  • 2020-11-22 01:40

    ✅✅✅✅✅✅✅✅✅✅✅✅ Working Solution ✅✅✅✅✅✅✅✅✅✅✅✅

    While creating OkHttpClient that will be used for Retrofit.

    add an Interceptor like this.

     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()
    

    Now your every Retrofit call's URL and request body will be logged in Logcat. Filter it by "gsonrequest"

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

    Solved my problem based on TommySM answer (see previous). But I didn't need to make login, I used Retrofit2 for testing https GraphQL API like this:

    1. Defined my BaseResponse class with the help of json annotations (import 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. Defined the call procedure in the interface:

      @POST("/api/apiname")
      Call<BaseResponse> apicall(@Body RequestBody params);
      
    3. Called apicall in the body of test: Create a variable of MyRequest type (for example "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 讨论(0)
  • 2020-11-22 01:44

    Based on the top answer, I have a solution to not have to make POJOs for every request.

    Example, I want to post this JSON.

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

    then, I create a common class like this:

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

    Finally, when I need a json

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

    The request marked annotation @Body then can pass to Retrofit.

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

    Add ScalarsConverterFactory to retrofit:

    in gradle:

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

    your retrofit:

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

    change your call interface @Body parameter to String, don't forget to add @Headers("Content-Type: application/json"):

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

    now you can post raw json.

    0 讨论(0)
  • I wanted to compare speed of volley and retrofit for sending and receiving data I wrote below code (for retrofit part)

    first dependency:

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

    Then interface:

     public interface IHttpRequest {
    
        String BaseUrl="https://example.com/api/";
    
        @POST("NewContract")
        Call<JsonElement> register(@Body HashMap registerApiPayload);
    }
    

    and a function to set parameters to post data to server(In MainActivity):

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

    And I found Retrofit faster than volley in my case.

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