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

Chr*_*ris 44 api android square retrofit

我试图提出一个请求,我想要包含一个Header,一个form-urlencoded字段和一个json体.我的Retrofit界面如下

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

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

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

我得到一个IllegalArgumentException,只允许一个编码注释.

Jul*_*mas 74

也许这可以帮助一些人,如果你有这个麻烦,你应该删除你的界面的@FormUrlEncoded.希望这可以帮助.

  • @Multipart也会引起同样的问题! (2认同)

Chr*_*ris 17

这篇文章向我指出了正确的方向/sf/answers/1499616541/.我将所有东西都附在体内并将其作为一个发送TypedInput.
所以界面看起来像这样

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

身体看起来像这样

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

  • 这在 Retrofit 2 中不起作用,我们应该使用 RequestBody! (2认同)

Pri*_*nce 10

添加 Julien 的答案,同时删除@Multipart注释。以下是我的使用方法:

@POST("/app/oauth/token")
Call<AuthResponse> getAuthToken(@Body RequestBody body);
Run Code Online (Sandbox Code Playgroud)

而且,这是我构建的方式RequestBody

RequestBody requestBody = new MultipartBody.Builder()
                        .setType(MultipartBody.FORM)
                        .addFormDataPart("grant_type", "password")
                        .addFormDataPart("username", username)
                        .addFormDataPart("password", password)
                        .build();
Run Code Online (Sandbox Code Playgroud)