如何在Retrofit请求的主体中发布原始整个JSON?

时间:2014-01-28 06:40:17

标签: android rest http-post retrofit android-json

之前可能已经提出过这个问题,但没有得到明确答复。如何在Retrofit请求的主体内发布原始整个JSON?

查看类似问题here。或者这个答案是否正确must be form url encoded and passed as a field?我真的希望不会,因为我所连接的服务只是期待帖子正文中的原始JSON。它们未设置为查找JSON数据的特定字段。

我只想一劳永逸地用 restperts 来澄清这一点。一个人回答不使用Retrofit。另一个不确定语法。另一个人认为可以这样做,但只有当它的形式是url编码并放在一个字段中时(在我的情况下这是不可接受的)。不,我无法为我的Android客户端重新编码所有服务。是的,在主要项目中发布原始JSON而不是将JSON内容作为字段属性值传递是非常常见的。让我们做对,继续前进吧。有人可以指向显示如何完成此操作的文档或示例吗?或者提供可以/不应该完成的有效理由。

更新:我可以100%确定地说一件事。你可以在谷歌的排球中做到这一点。它是内置的。我们可以在Retrofit中做到这一点吗?

25 个答案:

答案 0 :(得分:412)

@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 docs对于对象序列化的工作原理有很多了。

现在,如果你真的想要自己发送“原始”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. 创建TypedJsonString类的子类TypedString

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

    然后使用类似#1的类的实例。

答案 1 :(得分:134)

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

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

答案 2 :(得分:127)

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

使用Retrofit2:

我昨晚遇到了这个问题,从Volley迁移到了Retrofit2(并且作为OP状态,这是用JsonObjectRequest建立在Volley中的,虽然 Jake的回答是Retrofit的正确答案。 ,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 {

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

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

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

}

答案 3 :(得分:63)

Retrofit2 中,如果要以raw格式发送参数,则必须使用 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) {
    }
}

答案 4 :(得分:36)

使用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());
        }
    };
    
  4. 那就是它!在我个人看来,它比制作pojos和处理课堂混乱要好得多。这样更干净。

答案 5 :(得分:10)

我特别喜欢杰克对TypedString子类above的建议。您确实可以根据您计划推送的各种POST数据创建各种子类,每个子类都有自己的一组自定义调整。

您还可以选择在Re​​trofit 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 ) ;

答案 6 :(得分:7)

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 schema 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")
  

表单数据参数的其他方式检查此link

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

答案 7 :(得分:5)

在翻新中发送原始json所需的内容。

1)请确保添加以下标头,并删除其他重复的标头。因为,在Retrofit的官方documentation上,他们特别提到-

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

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

2) a。。如果您使用的是转换器工厂,则可以将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 使用。

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)成功!

答案 8 :(得分:4)

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

现在您可以发布原始json。

答案 9 :(得分:4)

经过这么多努力,发现基本的不同之处在于你需要发送JsonObject而不是JSONObject作为参数。

答案 10 :(得分:3)

基于最佳答案,我有一个解决方案,不必为每个请求都创建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。

答案 11 :(得分:3)

使用以下命令发送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());

并将其传递给网址

@Body RequestBody key

答案 12 :(得分:2)

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

答案 13 :(得分:2)

我发现,当您使用复合对象作为@Body参数时,它不能与改造的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>

答案 14 :(得分:1)

我尝试了这个: 在创建Retrofit实例时,请将此转换器工厂添加到Retrofit构建器中:

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

答案 15 :(得分:1)

基于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();
    

答案 16 :(得分:1)

在创建时 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()

现在,每个翻新呼叫的URL和请求正文都将记录在Logcat通过"gsonrequest"过滤

答案 17 :(得分:1)

API调用

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

注意:使用翻新版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;
    }
}

我想这会有所帮助,休息您可能已经拥有的所有集成,并且我们不需要花哨的钱就可以使用上面的代码段。对我来说很好用。

答案 18 :(得分:1)

您需要在界面中设置@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);

这对我有用:

答案 19 :(得分:0)

如果不想为每个API调用都创建pojo类,则可以使用hashmap。

//www.lazada.com.my/products/bundle-of-6-oldtown-white-coffee-3-in-1-classic-15s-x6-packs-free-oldtown-4-sticks-random-flavor-i434054933-s631848411.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-hazelnut-15s-x6-packs-i436317818-s639072921.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-classic-15s-x4-packs-i436315786-s639051449.html?mp=1
//www.lazada.com.my/products/bundle-of-6-oldtown-white-coffee-3-in-1-extra-rich-15s-x6-packs-free-oldtown-brown-mug-x1-4-sticks-random-flavor-i434056795-s631848533.html?mp=1
//www.lazada.com.my/products/bundle-of-6-oldtown-white-coffee-2-in-1-coffee-creamer-15s-x6-packs-free-oldtown-brown-mug-x1-4-sticks-random-flavor-i434061102-s631849047.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-hazelnut-15s-x2-packs-free-2-sticks-random-flavor-i434043717-s631808896.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-hazelnut-15s-x4-packs-i436302855-s639061262.html?mp=1
//www.lazada.com.my/products/bundle-of-6-oldtown-white-coffee-3-in-1-less-sugar-15s-x6-packs-free-oldtown-brown-mug-x1-4-sticks-random-flavor-i434054922-s631844581.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-extra-rich-15s-x4-packs-i436302850-s639053701.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-less-sugar-15s-i428864462-s623547178.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-extra-rich-15s-x2-packs-free-2-sticks-random-flavor-i434051011-s631820678.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-classic-15s-i429053474-s623935676.html?mp=1
//www.lazada.com.my/products/oldtown-3-in-1-white-milk-tea-13s-i429057450-s623942383.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-natural-cane-sugar-15s-x6-packs-i436315838-s639079875.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-mocha-15s-i429056707-s623944523.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-hazelnut-15s-i446475373-s668555737.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-less-sugar-15s-x2-packs-free-2-sticks-random-flavor-i434038995-s631814134.html?mp=1
//www.lazada.com.my/products/bundle-of-6-oldtown-white-coffee-3-in-1-hazelnut-15s-x6-packs-free-oldtown-4-sticks-random-flavor-i434059429-s631843615.html?mp=1
//www.lazada.com.my/products/oldtown-3-in-1-white-milk-tea-13s-x2-packs-free-2-sticks-random-flavor-i434048248-s631818679.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-2-in-1-coffee-creamer-15s-x2-packs-free-2-sticks-random-flavor-i434045440-s631815896.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-natural-cane-sugar-15s-x4-packs-i436347739-s639057542.html?mp=1
//www.lazada.com.my/products/oldtown-black-series-enrich-freeze-dried-instant-coffee-100g-i434617928-s633601781.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-less-sugar-15s-x4-packs-i436353732-s639059385.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-2-in-1-coffee-creamer-15s-i429056294-s623942054.html?mp=1
//www.lazada.com.my/products/bundle-of-4-oldtown-white-coffee-2-in-1-coffee-creamer-15s-x4-packs-free-4-sticks-random-flavor-i434053005-s631824941.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-classic-15s-x2-packs-free-2-sticks-random-flavor-i434041889-s631816196.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-extra-rich-15s-i429055995-s623946380.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-less-sugar-15s-x6-packs-i436317821-s639075740.html?mp=1
//www.lazada.com.my/products/oldtown-black-series-enrich-freeze-dried-instant-coffee-100g-2-glass-i435467037-s636334815.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-natural-cane-sugar-15s-x2-packs-free-2-sticks-random-flavor-i434043759-s631818279.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-2-in-1-coffee-creamer-15s-x2-packs-i436315754-s639016791.html?mp=1
//www.lazada.com.my/products/oldtown-white-coffee-3-in-1-classic-15s-x6-packs-i436353749-s639073757.html?mp=1
//www.lazada.com.my/products/bundle-of-6-oldtown-3-in-1-white-milk-tea-13s-x6-packs-free-oldtown-4-sticks-random-flavor-i434058314-s631843262.html?mp=1
//www.lazada.com.my/products/bundle-of-4-oldtown-white-coffee-3-in-1-hazelnut-15s-x4-packs-free-4-sticks-random-flavor-i446532232-s668570216.html?mp=1
//www.lazada.com.my/products/oldtown-3-in-1-white-milk-tea-13s-x6-packs-i436303866-s639071227.html?mp=1
//www.lazada.com.my/products/oldtown-black-series-enrich-freeze-dried-instant-coffee-100g-2-glass-foc-glass-mug-i442451196-s654637474.html?mp=1
//www.lazada.com.my/products/bundle-of-4-oldtown-3-in-1-white-milk-tea-13s-x4-packs-free-4-sticks-random-flavor-i434046913-s631825874.html?mp=1
//www.lazada.com.my/products/bundle-of-4-oldtown-white-coffee-3-in-1-classic-15s-x4-packs-free-4-sticks-random-flavor-i434052193-s631832149.html?mp=1
//www.lazada.com.my/products/oldtown-3-in-1-white-milk-tea-13s-x2-packs-i436282923-s639018195.html?mp=1
//www.lazada.com.my/products/bundle-of-6-oldtown-white-coffee-3-in-1-natural-cane-sugar-15s-x6-packs-free-oldtown-4-sticks-random-flavor-i434062035-s631849174.html?mp=1

然后像这样发送

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

答案 20 :(得分:0)

为使此处给出的答案更清楚,这是使用扩展功能的方法。 仅当您使用Kotlin时

如果您使用的是com.squareup.okhttp3:okhttp:4.0.1,则不建议使用旧的创建 MediaType RequestBody 对象的方法,并且不能在 Kotlin中使用 em>。

如果要使用扩展功能从字符串中获取 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)

答案 21 :(得分:0)

这对我当前使用的retrofit版本 2.6.2

起作用

首先,我们需要在Gradle依赖项列表中添加一个Scalars Converter,这将负责将java.lang.String对象转换为text / plain请求主体,

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

然后,我们需要将转换器工厂传递给我们的改造制造商。稍后将告诉Retrofit如何转换传递给服务的@Body参数。

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

注意:在我的改造生成器中,我有两个转换器Gson和   Scalars您可以同时使用它们来发送我们需要发送的Json正文   集中精力,以便在不需要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())

答案 22 :(得分:0)

我想比较截击和翻新的速度,以发送和接收我在下面的代码中编写的数据(翻新部分)

第一个依赖项

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比凌空快。

答案 23 :(得分:0)

JSONObject显示错误,请使用

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

答案 24 :(得分:0)

enter image description here

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