簡體   English   中英

如何在改造請求的正文中發布原始的整個 JSON?

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

這個問題以前可能有人問過,但沒有得到明確的回答。 在改造請求的正文中究竟如何發布原始的整個 JSON?

在這里看到類似的問題。 或者這個答案是否正確,它必須是表單 url 編碼並作為字段傳遞 我真的不希望這樣,因為我連接的服務只是在帖子正文中期待原始 JSON。 它們未設置為查找 JSON 數據的特定字段。

我只想一勞永逸地與其他人澄清這一點。 一個人回答不要使用 Retrofit。 另一個不確定語法。 另一個人認為是的,它可以做到,但前提是它的形式是 url 編碼並放在一個字段中(這在我的情況下是不可接受的)。 不,我無法為我的 Android 客戶端重新編碼所有服務。 是的,在主要項目中發布原始 JSON 而不是將 JSON 內容作為字段屬性值傳遞是很常見的。 讓我們做對並繼續前進。 有人可以指出顯示這是如何完成的文檔或示例嗎? 或者提供一個可以/不應該做的正當理由。

更新:我可以 100% 肯定地說一件事。 您可以在 Google 的 Volley 中執行此操作。 它是內置的。我們可以在 Retrofit 中做到這一點嗎?

@Body注解定義了一個請求體。

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

由於 Retrofit 默認使用 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被定義為“具有關聯 mime 類型的二進制數據”。 有兩種方法可以通過上述聲明輕松發送原始數據:

  1. 使用TypedByteArray發送原始字節和 JSON mime 類型:

     String json = "{\"foo\":\"kit\",\"bar\":\"kat\"}"; TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8")); FooResponse response = foo.postRawJson(in);
  2. 子類TypedString以創建TypedJsonString類:

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

    然后使用類似於#1 的該類的實例。

是的,我知道已經晚了,但有人可能會從中受益。

使用改造2:

昨晚我從 Volley 遷移到 Retrofit2 時遇到了這個問題(正如 OP 所說,這是用JsonObjectRequest內置到 Volley 中的),雖然Jake 的答案是 Retrofit1.9 的正確答案,但 Retrofit2 沒有TypedString

我的案例需要發送一個Map<String,Object>可能包含一些空值,轉換為 JSONObject (不會與@FieldMap一起飛行,特殊字符也不會,有些會被轉換),所以遵循@bnorms 提示,並作為Square表示:

可以使用 @Body 注釋指定一個對象用作 HTTP 請求正文。

該對象也將使用 Retrofit 實例上指定的轉換器進行轉換。 如果不添加轉換器,則只能使用 RequestBody。

所以這是一個使用RequestBodyResponseBody的選項:

在您的界面中使用@BodyRequestBody

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

在您的調用點創建一個RequestBody ,說明它是 MediaType,並使用 JSONObject 將您的 Map 轉換為正確的格式:

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

希望這對任何人都有幫助!


上面的一個優雅的 Kotlin 版本,允許從應用程序代碼的其余部分中的 JSON 轉換中抽象出參數:

interface ServiceApi {

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

}

class ServiceApiUsingClass {

//ServiceApi init

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

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

除了類,我們還可以直接使用HashMap<String, Object>來發送主體參數,例如

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

Retrofit2中,當您想以原始形式發送參數時,您必須使用Scalars

首先在你的gradle中添加這個:

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

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

那就是它! 在我個人看來,它比制作 pojos 和處理課堂混亂要好得多。 這更清潔。

我特別喜歡 Jake 對上述TypedString子類的建議。 您確實可以根據您計划推送的 POST 數據類型創建各種子類,每個子類都有自己自定義的一組一致的調整。

您還可以選擇在 Retrofit API 中為 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)添加依賴項-

 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)制作Api Handler類

    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 pojo 制作 bean 類

記住
-目標語言: Java -源類型:JSON -注釋樣式:Gson -選擇包括 getter 和 setter -您也可以選擇允許附加屬性

http://www.jsonschema2pojo.org/

4)制作API調用接口

    public interface Webservices {

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

}

如果您有表單數據參數,則添加以下行

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

表單數據參數的其他方式檢查此鏈接

5)制作JsonObject作為參數傳入body

 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)像這樣調用Api

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

添加 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();

把你的調用接口@Body參數改成String,別忘了加上@Headers("Content-Type: application/json")

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

現在您可以發布原始 json。

我發現當您使用復合對象作為@Body參數時,它不能與 Retrofit 的GSONConverter工作(假設您正在使用它)。 在使用它時,您必須使用JsonObject而不是JSONObject ,它會添加NameValueParams而不會對其進行詳細說明 - 只有添加另一個日志攔截器的依賴項和其他惡作劇時,您才能看到這一點。

所以我發現解決這個問題的最佳方法是使用RequestBody 您可以通過簡單的 api 調用將您的對象轉換為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>

這對我當前版本的retrofit 2.6.2 有用

首先,我們需要在 Gradle 依賴項列表中添加一個 Scalars Converter,它負責將 java.lang.String 對象轉換為 text/plain 請求體,

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

然后,我們需要將轉換器工廠傳遞給我們的 Retrofit 構建器。 稍后它將告訴 Retrofit 如何轉換傳遞給服務的 @Body 參數。

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

注意:在我的改造構建器中,我有兩個轉換器GsonScalars ,您可以同時使用它們,但是要發送 Json 主體,我們需要關注Scalars ,因此如果您不需要Gson ,請將其刪除

然后使用 String body 參數改造服務。

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

如果您不想為每個 API 調用創建 pojo 類,則可以使用 hashmap。

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

然后像這樣發送

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

使用以下發送 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

如果您不想創建額外的類或使用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)

在改造中發送原始 json 所需的東西。

1)確保添加以下標題並刪除任何其他重復的標題。 因為,在 Retrofit 的官方文檔中,他們特別提到 -

請注意,標題不會相互覆蓋。 所有具有相同名稱的標頭都將包含在請求中。

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

2)一個。 如果您使用轉換器工廠,您可以將 json 作為字符串、JSONObject、JsonObject 甚至 POJO 傳遞。 還檢查過,不需要ScalarConverterFactory只有GsonConverterFactory可以完成這項工作。

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

2)乙。 如果您不使用任何轉換器工廠,那么您必須使用 okhttp3 的 RequestBody,因為 Retrofit 的文檔說-

該對象也將使用 Retrofit 實例上指定的轉換器進行轉換。 如果不添加轉換器,則只能使用 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)成功!!

經過這么多努力,發現基本的區別是您需要發送JsonObject而不是JSONObject作為參數。

基於最佳答案,我有一個解決方案,不必為每個請求制作 POJO。

例如,我想發布這個 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<>();
    }
}

最后,當我需要一個 json

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

標記為注解@Body的請求然后可以傳遞給Retrofit。

你需要在界面中設置@Body

@Headers({ "Content-Type: application/json;charset=UTF-8"})
    @POST("Auth/Login")
    Call<ApiResponse> loginWithPhone(@Body HashMap<String, String> fields);

要通過原始主體進行改造,只需使用:

 HashMap<String,String> SendData =new HashMap<>();
        SendData.put("countryCode",ccode);
        SendData.put("phoneNumber",phone);

        Call<ApiResponse>call = serviceInterface.loginWithPhone(SendData);

這對我有用:

為了更清楚地了解此處給出的答案,這是您可以使用擴展功能的方式。 僅當您使用 Kotlin 時

如果您使用的是com.squareup.okhttp3:okhttp:4.0.1 ,創建MediaTypeRequestBody對象的舊方法已被棄用,無法在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)

根據 TommySM 的回答解決了我的問題(見前文)。 但我不需要登錄,我使用 Retrofit2 來測試 https GraphQL API,如下所示:

  1. 借助 json 注釋(導入 jackson.annotation.JsonProperty)定義了我的 BaseResponse 類。

     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. 在測試體中調用 apicall:創建一個 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();

我想比較截擊和改造的速度以發送和接收我在下面的代碼中編寫的數據(改造部分)

第一個依賴:

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

以及設置參數以將數據發布到服務器的函數(在 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) {

        }
    });

}

在我的案例中,我發現 Retrofit 比 volley 更快。

API 調用

@Headers("Content-Type: application/json")
@POST("/set_data")
Call<CommonResponse> setPreferences(@Body RequestData request);

注意:使用 Retrofit 的 GSON 庫

import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;

public class RequestData {

    @SerializedName("access_token")
    @Expose
    private String accessToken;

    @SerializedName("data")
    @Expose
    private Data data;
    // The above 'Data' is another similar class to add inner JSON objects. JSONObject within a JSONObject.

    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }

    public void setData(Data data) {
        this.data = data;
    }
}

我想這會有所幫助,剩下你可能已經擁有的所有集成,我們不需要任何花哨的東西來使用上面的代碼片段。 它對我來說非常有效。

我試過這個:當你創建你的改造實例時,將此轉換器工廠添加到改造構建器中:

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

在創建將用於改造的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()

現在,您的每個 Retrofit 調用的 URL 和請求正文都將記錄Logcat中。 "gsonrequest"過濾

2022 年更新的解決方案:

首先要檢查的一件事是您的發布請求是否通過第三方 API(例如郵遞員)工作。 在遇到此頁面上的解決方案之前,我已經這樣做了。

下一步是將日志記錄工具添加到您的改造實例。 單擊此處了解如何添加日志記錄以進行改造。

添加日志記錄后,我看到了 500 服務器錯誤,基於端點通過 Postman 工作的事實,我們知道該錯誤必須與傳遞給 Post 方法的數據格式有關。

您的改造構建器應如下所示:

val retrofitInstance = Retrofit.Builder()
            .baseUrl("https://pacific-tundra-61285.herokuapp.com/")
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .client(httpClient)
            .build()

這篇文章對解決這個問題有很大幫助,並提供了在發出 post 請求時將對象轉換為正確的“application/json”格式的正確方法。 kotlin 版本中使用了一些不推薦使用的方法,新代碼非常相似:

private fun createRequestBody(vararg params : Pair<String, Any>) =
        JSONObject(mapOf(*params)).toString()
            .toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull())

該對中的通用值參數設置為 Any,以便您可以處理與您的對象相關的不同類型。

為了清楚起見,最后一部分是實際的 post 方法和用於調用 post 請求的代碼。

@POST("create/")
    fun create(@Body params : RequestBody) : Call<YourObject>
val call = apiService.create(createRequestBody( 
"string" to object // You should pass in any key and value pairs here.

最后像往常一樣在調用上調用 enqueue。

JSONObject 顯示錯誤請使用

JsonObject paramObject = new JsonObject(); paramObject.addProperty("loginId", vMobile_Email);

在此處輸入圖像描述

添加 ScalarsConverterFactory.create() 方法並傳遞硬代碼

@Headers(value = "Content-Type: application/json") @POST("api/Persona/Add") 調用 AddPersona(@Header("authorization") String token, @Body JsonObject object); JsonObject postParam = new JsonObject(); postParam.addProperty("PersonaCedula", item.getPersonaCedula());

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM