这个问题以前可能被问过,但没有明确的答案。如何在Retrofit请求的主体中发布原始的整个JSON ?

在这里看到类似的问题。或者这个答案是正确的,它必须是表单url编码并作为一个字段传递?我真的希望不是,因为我要连接的服务只是希望在文章正文中有原始JSON。它们不是用来为JSON数据寻找特定字段的。

I just want to clarify this with the restperts once and for all. One person answered not to use Retrofit. The other was not certain of the syntax. Another thinks yes it can be done but only if its form url-encoded and placed in a field (that's not acceptable in my case). No, I can't re-code all the services for my Android client. And yes, it's very common in major projects to post raw JSON instead of passing over JSON content as field property values. Let's get it right and move on. Can someone point to the documentation or example that shows how this is done? Or provide a valid reason why it can/should not be done.

更新:有一件事我可以百分之百确定。你可以在谷歌的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类型的二进制数据”。有两种方法可以使用上述声明轻松发送原始数据:

Use TypedByteArray to send raw bytes and the JSON mime type: String json = "{\"foo\":\"kit\",\"bar\":\"kat\"}"; TypedInput in = new TypedByteArray("application/json", json.getBytes("UTF-8")); FooResponse response = foo.postRawJson(in); Subclass TypedString to create a TypedJsonString class: public class TypedJsonString extends TypedString { public TypedJsonString(String body) { super(body); } @Override public String mimeType() { return "application/json"; } } And then use an instance of that class similar to #1.


我们也可以直接使用HashMap<String, Object>来发送主体参数,而不是类 例如

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

我特别喜欢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 ) ;

使用JsonObject是它的方式:

Create your interface like this: public interface laInterfaz{ @POST("/bleh/blah/org") void registerPayer(@Body JsonObject bean, Callback<JsonObject> callback); } Make the JsonObject acording to the jsons structure. 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*/ Call the service: 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()); } };

这就是它!在我个人看来,这比制作pojo和处理班级混乱要好得多。这样干净多了。


是的,我知道很晚了,但有人可能会从中受益。

使用Retrofit2:

我昨晚从Volley迁移到Retrofit2时遇到了这个问题(正如OP所述,这是用JsonObjectRequest构建到Volley中的),尽管Jake的答案是Retrofit1.9的正确答案,但Retrofit2没有TypedString。

我的情况下需要发送一个地图<字符串,对象>,可以包含一些空值,转换为JSONObject(不会飞@FieldMap,也不特殊字符,一些得到转换),所以遵循@ b规范提示,并由Square声明:

可以使用@Body注释指定对象作为HTTP请求主体。 对象还将使用Retrofit实例上指定的转换器进行转换。如果没有添加转换器,则只能使用RequestBody。

这是一个使用RequestBody和ResponseBody的选项:

在你的接口中使用@Body和RequestBody

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

在Retrofit2中,当你想要发送原始参数时,你必须使用标量。

首先在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) {
    }
}

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 -select包含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)make 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();
    }
}

经过如此多的努力,发现基本的区别是您需要发送JsonObject而不是JsonObject作为参数。


使用following发送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

根据上面的答案,我有一个解决方案,不必为每个请求都创建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。


我试了一下: 当你创建你的Retrofit实例时,将这个转换器工厂添加到Retrofit构建器中:

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

如果你不想创建额外的类或使用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)

添加ScalarsConverterFactory进行改造:

在gradle:

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

现在你可以发布raw 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>

如果不想为每个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);

为了更清楚地说明这里给出的答案,下面是如何使用扩展函数。这仅适用于使用Kotlin的情况

如果你正在使用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)

解决了我的问题基于TommySM的答案(见前)。 但是我不需要登录,我使用Retrofit2来测试https GraphQL API,就像这样:

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; } } Defined the call procedure in the interface: @POST("/api/apiname") Call<BaseResponse> apicall(@Body RequestBody params); 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();


这是我在当前版本的2.6.2中工作的地方,

首先,我们需要添加一个Scalars Converter到我们的Gradle依赖项列表中,它负责将java.lang.String对象转换为文本/纯请求体,

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

注:在我的改造建设者我有两个转换器Gson和 标量,你可以使用他们,但发送Json的主体,我们需要 focus Scalars,所以如果你不需要Gson删除它

然后用String体参数对服务进行翻新。

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

我想比较排射的速度和改装的发送和接收数据,我写在下面的代码(改装部分)

第一个依赖:

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中需要发送原始json的东西。

1)确保添加以下标题,并删除任何其他重复的标题。因为,在Retrofit的官方文件中他们特别提到了-

注意,头文件不会相互覆盖。所有带有 相同的名字将包含在请求中。

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

2) a.如果你正在使用一个转换器工厂,你可以传递你的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) b.如果你没有使用任何转换器工厂,那么你必须使用okhttp3的RequestBody,因为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)成功! !


在创建OkHttpClient时,将用于Retrofit。

像这样增加一个拦截器。

 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"过滤


火通话

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

我想这将有所帮助,您可能已经拥有了所有集成,我们不需要任何花哨的东西来使用上面的代码片段。它非常适合我。


JSONObject显示错误,请使用

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


你需要在interface中设置@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);

这对我来说很管用:


添加ScalarsConverterFactory.create()方法并传递硬代码


2022年的最新解决方案:

首先要检查的一件事是,您的post请求是否通过第三方API(如postman)工作。在遇到本页上的解决方案之前,我已经这样做了。

下一步是向您的改装实例添加日志记录功能。点击这里了解如何添加日志记录来进行改造。

在添加日志记录时,我看到了一个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())

pair中的泛型值参数被设置为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。


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