我正在尝试使用Retrofit 2发出POST请求。请求类型为form-data
NOT application/x-www-form-urlencoded
。
我只发布数据而不是请求中的文件,响应采用JSON格式。
我已经尝试了@FormUrlEncoded, @Multipart
,但它无效。
我已尝试过以下请求
1。第一次尝试
@FormUrlEncoded
@POST("XXXX")
Call<PlanResponse> getPlanName(@Field(Constants.ACTION_ID) String actionId, @Field(Constants.OFFER_CODE) String offerCode);
2。第二次尝试
@Headers({"Content-Type: multipart/form-data","Content-Type: text/plain"})
@FormUrlEncoded
@POST("XXXX")
Call<PlanResponse> getPlans(@Body @FieldMap(encoded = false) Map<String, String> data);
第3。第三次尝试
@Headers("Content-Type: multipart/form-data")
@Multipart
@POST("XXXX")
Call<PlanResponse> myPlans(@Part(Constants.ACTION_ID) String actionId, @Part(Constants.OFFER_CODE) String offerCode);
我只是将身体变为 null 。它正在与POSTMAN合作。
我还搜索了form-data
和application/x-www-form-urlencoded
,发现如果数据是二进制,则使用form-data
,如果数据是ASCII,则使用application/x-www-form-urlencoded
我正在尝试查找改造不支持表单数据吗?
POSTMAN请求
Cache-Control: no-cache
Postman-Token: XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX-XXXXXXXXXXXX
Content-Type: multipart/form-data; boundary=---- WebKitFormBoundaryXXXXXXXXXXXX
----WebKitFormBoundaryXXXXXXXXXXXX
Content-Disposition: form-data; name="actionId"
1000
----WebKitFormBoundaryXXXXXXXXXXXX
Content-Disposition: form-data; name="offerCode"
MYCODE
----WebKitFormBoundaryXXXXXXXXXXXX
我只能添加从POSTMAN
剪切的HTTP生成代码答案 0 :(得分:28)
在改造2.0中执行上述POST请求时,您应该像这样使用RequestBody类型作为参数。
@Multipart
@POST("XXXX")
Call<PlanResponse> myPlans(@Part(Constants.ACTION_ID) RequestBody actionId, @Part(Constants.OFFER_CODE) RequestBody offerCode);
这里是如何从String获取requestBody。
String somevalue = "somevalue";
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), somevalue);
答案 1 :(得分:14)
这是使用请求正文的另一个解决方案:
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("param1", param1)
.addFormDataPart("param2", param2)
.build();
apiInterface.somePostMethod(requestBody).enqueue(
//onResponse onFailure methods
);
这是我的api接口POST方法
@POST("somePostMethod")
Call<ResponseBody> somePostMethod(@Body RequestBody body);
希望它有所帮助。
答案 2 :(得分:1)
对于Kotlin,这是另一种实现方式。对于不接受FormUrEncoded数据的api。
fun login(email: String, password: String, grantType: String):
Single<TokenModel> {
var userNameB:RequestBody=
email.toRequestBody(email.toMediaTypeOrNull())
var passwordB: RequestBody =
password.toRequestBody(password.toMediaTypeOrNull())
var grantTypeB: RequestBody =
grantType.toRequestBody(grantType.toMediaTypeOrNull())
return userApi.loginUSer(userNameB,passwordB,grantTypeB)
.map { TokenModel(it.accessToken, it.refreshToken) }
}
然后。
@Multipart
@POST("auth/token/")
fun loginUSer(
@Part("username") request: RequestBody,
@Part("password") passwordB: RequestBody,
@Part("grant_type") grantTypeB: RequestBody
): Single<Token>
答案 3 :(得分:1)
这是在 Kotlin 中使用请求正文表单数据的另一个解决方案。这个解决方案在 Kotlin 中对我有用。
val request = ServiceBuilder.buildService(TmdbEndpoints::class.java)
val requestBody: RequestBody = MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("email", "abc@gmail.com")
.addFormDataPart("password", "admin")
.addFormDataPart("push_token", "token")
.addFormDataPart("device_id", "1112222")
.addFormDataPart("platform", "android")
.addFormDataPart("device_name", "my device")
.addFormDataPart("version", "1.2")
.build()
val call = request.userFigLogin(requestBody)
call.enqueue(object : Callback<LoginResult> {
override fun onFailure(call: Call<LoginResult>, t: Throwable) { }
override fun onResponse(call: Call<LoginResult>,
response: retrofit2.Response<LoginResult>) { }
})
<块引用>
您应该像这样为您的参数使用 RequestBody 类型。
@POST("api/login")
fun userFigLogin(@Body body: RequestBody): Call<LoginResult>
答案 4 :(得分:0)
我想将ID数组传递给现有请求。
我在这里尝试了Retrofit - Send request body as array or number,How to send PUT request with retrofit string and array list of model I need to use URL encoded的几种变体,但是它们没有用。然后我尝试了android retrofit send array as x-www-form-urlencoded。
我在列表参数中添加了[]
,并在其类型中添加了List
:
@FormUrlEncoded
@POST("your_request/")
fun sendIds(
@Field("token") token: String,
@Field("city_id") cityId: Int?,
@Field("description") description: String,
@Field("ids[]") ids: List<Int>? // Add '[]' here.
): Deferred<YourResponse>
然后像往常一样(用Kotlin协程命名):
api.sendIds("f0123abc", null, "description", listOf(1, 2, 3)).await()
另请参阅Is it possible to send an array with the Postman Chrome extension?,以了解其在Postman中的外观。
答案 5 :(得分:0)
表单数据。 我将通过一个典型的注册过程示例来使您清楚。 首先添加标题
@FormUrlEncoded
在您的 用户客户端 中。 使用
@FieldMap
代替直接对象。因此,您的 user-client 代码将是这样的
@POST("signup/")
@FormUrlEncoded
Call<ResponseModel> signup(@FieldMap Map<String,String> params);
现在在您的主要活动中,像这样为您的所有数据创建一个哈希表,
Map<String,String> params = new HashMap<String, String>();
params.put("fullname", fullname);
params.put("city", city);
params.put("state",state);
params.put("address",address);
params.put("email",email);
params.put("password1", password1);
params.put("password2", password2);
现在简单地将此哈希图传递给这样的方法
Call<ResponseModel> call = service.signup(params);
call.enqueue(new Callback<ResponseModel>() {
@Override
public void onResponse(Call<ResponseModel> call, Response<ResponseModel> response) {
if (response.isSuccessful()) {
Toast.makeText(SignUp.this,response.body.getData,Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(SignUp.this, "Error : ", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<ResponseModel> call, Throwable t) {
t.printStackTrace();
Toast.makeText(SignUp.this, "Server Unavailable : "+t.toString(), Toast.LENGTH_SHORT).show();
}
});
答案 6 :(得分:-1)
我认为这可以帮助您
@Multipart
@Headers( "Content-Type: application/x-www-form-urlencoded")
@POST("api/register")
fun postRegister(
@Part("authtype") authtype: String,
@Part("channel")channel : String,
@Part("children")children : List<String>,
@Part("names") names: List<String>,
@Part("email") email: String,
@Part("password")password : String,
@Part("name") name: String,
@Part("timezone") timezone: Int,
@Part("timezone_name")timezone_name : String,
@Part("token_device")token_device : String,
@Part("imageData") imageData: String,
@Part("mimeType") mimeType: String,
@Part("extension") extension: String,
): Call<ResponseBase>