改造 2 只有 form-data
Retrofit 2 with only form-data
我正在尝试使用 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);
我只得到 body 作为 null。它正在与 POSTMAN 一起工作。
我还搜索了 form-data
和 application/x-www-form-urlencoded
,发现如果数据是二进制的,则使用 form-data
,如果数据是 ASCII,则使用 application/x-www-form-urlencoded
我正在尝试查找 Retrofit 是否不支持 form-data?
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 生成代码
在改造 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);
这是另一个使用请求正文的解决方案:
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);
希望对您有所帮助。
我想将一组 ID 传递给现有请求。
我从这里尝试了几种变体,Retrofit - Send request body as array or number, , but they didn't work. Then I tried 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 中的外观。
对于 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>
form-data 是肯定支持的。
我将使用典型注册过程的示例让您清楚。
首先添加一个header
@FormUrlEncoded
在您的用户客户端。
使用
@FieldMap
而不是直接的对象。所以你的 user-client 代码会像这样
@POST("signup/")
@FormUrlEncoded
Call<ResponseModel> signup(@FieldMap Map<String,String> params);
现在在你的主 activity 中,像这样为你的所有数据创建一个 Hashmap,
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);
现在简单地将这个 hashmap 传递到这样的方法中
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();
}
});
我想这对你有帮助
@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>
Here's another Solution using the request body form-data in Kotlin. This solution work for me in 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>) { }
})
You should use RequestBody type for your parameter like this.
@POST("api/login")
fun userFigLogin(@Body body: RequestBody): Call<LoginResult>
只需将其从页眉中删除
defaultProperties["Content-Type"] = "application/json"
我正在尝试使用 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);
我只得到 body 作为 null。它正在与 POSTMAN 一起工作。
我还搜索了 form-data
和 application/x-www-form-urlencoded
,发现如果数据是二进制的,则使用 form-data
,如果数据是 ASCII,则使用 application/x-www-form-urlencoded
我正在尝试查找 Retrofit 是否不支持 form-data?
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 生成代码在改造 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);
这是另一个使用请求正文的解决方案:
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);
希望对您有所帮助。
我想将一组 ID 传递给现有请求。
我从这里尝试了几种变体,Retrofit - Send request body as array or number,
我将 []
添加到列表参数,并将 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 中的外观。
对于 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>
form-data 是肯定支持的。 我将使用典型注册过程的示例让您清楚。 首先添加一个header
@FormUrlEncoded
在您的用户客户端。 使用
@FieldMap
而不是直接的对象。所以你的 user-client 代码会像这样
@POST("signup/")
@FormUrlEncoded
Call<ResponseModel> signup(@FieldMap Map<String,String> params);
现在在你的主 activity 中,像这样为你的所有数据创建一个 Hashmap,
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);
现在简单地将这个 hashmap 传递到这样的方法中
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();
}
});
我想这对你有帮助
@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>
Here's another Solution using the request body form-data in Kotlin. This solution work for me in 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>) { }
})
You should use RequestBody type for your parameter like this.
@POST("api/login")
fun userFigLogin(@Body body: RequestBody): Call<LoginResult>
只需将其从页眉中删除 defaultProperties["Content-Type"] = "application/json"