Retrofit - @Body 参数不能与表单或多部分编码一起使用

Posted

技术标签:

【中文标题】Retrofit - @Body 参数不能与表单或多部分编码一起使用【英文标题】:Retrofit - @Body parameters cannot be used with form or multi-part encoding 【发布时间】:2015-02-03 16:39:57 【问题描述】:

我正在尝试发出要包含 Header 、 form-urlencoded 字段和 json 正文的请求。 我的Retrofit界面如下

@FormUrlEncoded
@POST("/api/register")
Observable<RegisterResponse> register(
    @Header("Authorization") String authorization, 
    @Field("grant_type") String grantType, 
    @Body RegisterBody body
);

当我提出这个请求时,我得到了异常 @Body 参数不能与表单或多部分编码一起使用。 我也试过@Multipart注解:

@Multipart
@FormUrlEncoded
@POST("/api/register")
Observable<RegisterResponse> register(
    @Header("Authorization") String authorization, 
    @Part("grant_type") TypedString grantType, 
    @Body RegisterBody body
);

我得到一个IllegalArgumentException 并且只允许一个编码注释。

【问题讨论】:

Multipart Request using Retrofit 1.8.0 not working 的可能重复项 另外,因为它是一个多部分,你需要几个@Part,而不是一个Body和一个Part 【参考方案1】:

也许这可以帮助一些人,如果你有这个问题,你应该删除你界面的@FormUrlEncoded。 希望这会有所帮助。

【讨论】:

@Multipart 也会导致同样的问题!【参考方案2】:

这篇文章为我指明了正确的方向https://***.com/a/21423093/1446856。 我附上了正文中的所有内容并将其作为TypedInput发送。 所以界面看起来是这样的

@POST("/api/register")
@Headers( "Content-Type: application/json;charset=UTF-8")
Observable<RegisterResponse> register(
    @Header("Authorization") String authorization,
    @Body TypedInput body
);

身体看起来像这样

String bodyString = jsonBody + "?grant_type=" + 
    grantType + "&scope=" + scope;
TypedInput requestBody = new TypedByteArray(
    "application/json", bodyString.getBytes(Charset.forName("UTF-8")));

【讨论】:

'jsonBody' 的值是多少? @ViksaaSkool 它可以是任何 json 字符串。例如 "currency":"GBP", "customerId":2, "country":"GB", "lang":"en-GB", "sizeSchema":"UK", "store":"1" 这个在 Retrofit 2 中不起作用,我们应该使用 RequestBody !! bodyString 的值是多少?或者如何在改造 2 中实现这一点?【参考方案3】:

除了 Julien 的回答之外,还删除了 @Multipart 注释。以下是我的使用方法:

@POST("/app/oauth/token")
Call<AuthResponse> getAuthToken(@Body RequestBody body);

而且,这就是我构建RequestBody 的方法:

RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("grant_type", "password")
                        .addFormDataPart("username", username)
                        .addFormDataPart("password", password)
                        .build();

【讨论】:

比公认的答案更简洁、更容易,就像一个魅力。【参考方案4】:

我通过将字段添加到

中解决了这个问题
@POST("/api/register") 

像这样:

@POST("/api/register?grantType=value")

这不是一个好的解决方案,但可能有用。

【讨论】:

【参考方案5】:

将带有 json Body 的 Authentication 标头发送到 Kotlin 中的 API 示例代码:

 @POST("/api/user/sendlist/")
    fun callSendJsonListPost(
                      @Header("Authheader") header: String,
                      @Body list: StringBuilder
                      )
        : Observable<EntityModelUserslist>

【讨论】:

以上是关于Retrofit - @Body 参数不能与表单或多部分编码一起使用的主要内容,如果未能解决你的问题,请参考以下文章

retrofit @FieldMap 与 @Body 区别

IllegalArgumentException:@Body parameters cannot be used with form or multi-part encoding

Retrofit 2 0 自定义Converter

【Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMap...

Retrofit之表单提交多文件上传

Retrofit之请求参数