如何POST原始的整个JSON在一个改造请求的身体?

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

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

我只是想用restperts一劳永逸地澄清这一点。有人回答说不使用Retrofit。另一个不确定语法。另一个人认为是可以做到的,但只有当它的表单url编码并放置在一个字段中(这在我的情况下是不可接受的)。不,我不能为我的Android客户端重新编码所有的服务。是的,在大型项目中,发布原始JSON而不是将JSON内容作为字段属性值传递是非常常见的。让我们改正错误,继续前进。有人能指出说明如何做到这一点的文档或示例吗?或者提供一个可以/不应该这样做的合理理由。

更新:有一件事我可以百分之百确定。你可以在谷歌的Volley中做到这一点。这是与生俱来的。我们可以在Retrofit中这样做吗?

476624 次浏览

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

    然后使用类似于#1的该类实例

代替类,我们也可以直接使用HashMap<String, Object>来发送主体参数 例如< / p >
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是这样的:

  1. 像这样创建你的界面:

    public interface laInterfaz{
    @POST("/bleh/blah/org")
    void registerPayer(@Body JsonObject bean, Callback<JsonObject> callback);
    }
    
  2. 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*/
    
  3. 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());
    }
    };
    

And that its! In my personal opinion, its a lot better than making pojos and working with the class mess. This is a lot more cleaner.

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

使用Retrofit2:

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

我的情况下需要发送一个Map<String,Object>,可以包含一些空值,转换为JSONObject(不会与@FieldMap飞行,也不特殊字符,一些被转换),所以遵循@ b规范提示,并由广场声明:

可以使用@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())
}

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类

< p >记得< br > 目标语言: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)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,则创建MediaTypeRequestBody对象的旧方法已弃用,不能在芬兰湾的科特林中使用。

如果你想使用扩展函数从字符串中获取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注释的帮助下定义了我的BaseResponse类(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();
    

这就是我对当前版本的retrofit 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())
}

注:在我的改造建设者我有两个转换器GsonScalars你可以使用它们,但发送Json的主体,我们需要 聚焦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"})

如果你正在使用转换器工厂,你可以传递json作为String, 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 使用。< / p >
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

像这样增加一个拦截器。

 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中的现在,您的每个Retrofit调用的URL和请求正文都将被记录通过"gsonrequest"过滤它

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

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

JSONObject显示错误,请使用

JsonObject paramObject = new JsonObject(); paramObject.addProperty(“loginId" vMobile_Email); < / p >

你需要在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);

这对我来说很管用:

enter image description here

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

这篇文章在帮助解决这个问题方面帮助很大,并提供了将对象转换为正确的“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());