请问为什么Retrofit以Mutipart上传参数时,String参数会多一对双引号

这是我的Activity

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Observable<Object> a = fileRetrofit().create(ApiStores.class).addCase2("123", 1234);
        a.subscribeOn(Schedulers.io()).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {

            }
        });
    }

    public static Retrofit mFileRetrofit;

    public static Retrofit fileRetrofit(){
        if (mFileRetrofit == null) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .addInterceptor(new LoggingInterceptor());
            OkHttpClient okHttpClient = builder.build();

            mFileRetrofit = new Retrofit.Builder()
                    .baseUrl(ApiStores.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .client(okHttpClient)
                    .build();
        }
        return mFileRetrofit;
    }
}

这是接口

public interface ApiStores {
    //baseUrl
    String BASE_URL = "http://123.12.123.123/";

    @Multipart
    @POST("qwe/asd")
    Observable<Object> addCase2(@Part("tag") String tag, @Part("tag2") int tag2);
}

一下是LOG”
request

                                    
                                    Sending request http://123.12.123.123/qwe/asd on null
                                    
                                    --369f49f5-597d-4aa2-9c5e-86eccda84c88
                                    Content-Disposition: form-data; name="tag"
                                    Content-Transfer-Encoding: binary
                                    Content-Type: application/json; charset=UTF-8
                                    Content-Length: 5
                                    
                                    "123"
                                    --369f49f5-597d-4aa2-9c5e-86eccda84c88
                                    Content-Disposition: form-data; name="tag2"
                                    Content-Transfer-Encoding: binary
                                    Content-Type: application/json; charset=UTF-8
                                    Content-Length: 4
                                    
                                    1234
                                    --369f49f5-597d-4aa2-9c5e-86eccda84c88--

可以看到content-length为5, 即为“123”的长度,两边的双引号也被发送过去了

阅读 9.7k
5 个回答

“@Part(“data”) String des”在Post请求中默认的Content-Type类型是“application/json”,这就说明我们在接口中不能再使用@Part注解了

@Multipart
@POST("userPhoto")
Observable<BaseHttpResult<String>> uploadMultipleTypeFile(@PartMap Map<String, RequestBody> params);

Map<String, RequestBody> bodyMap = new HashMap<>();
bodyMap.put("photo"; filename=""+file.getName(), RequestBody.create(MediaType.parse("image/png"),file));
bodyMap.put("userId", toRequestBody(userId));
bodyMap.put("serialNumber", toRequestBody(serialNumber));

public static RequestBody toRequestBody(String value) {

    RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), value);
    return requestBody;

}

造成的主要原因有两个:1、retrofit并不内置String的Converter,只有在Url、Header、普通表单字段相关的注解才会默认处理成String。2、你注册了GsonConverter,而GsonConverter是不会判断能不能处理该类型的,全部转成json,而String在json里就是 "String"的形式,所以长度变成5,Content-Type头是application/json; charset=UTF-8

新手上路,请多包涵

被采纳的答案真是乱指挥,你的代码啥也不用改。

原因是你注册了 GsonConverter,没注册标准类型数据的转换器,导致String这些都会转成 JSON 传输,你只需要加一个标准类型的转换器就行了。

implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
.addConverterFactory(ScalarsConverterFactory.create())
新手上路,请多包涵

bodyMap.put("photo";filename=""+file.getName(),

     RequestBody.create(MediaType.parse("image/png"),file))
 这里的 "photo";filename=""+file.getName() 怎么理解
新手上路,请多包涵

.addConverterFactory(ScalarsConverterFactory.create())这个顺序要在 .addConverterFactory(GsonConverterFactory.create())
之前,否则也会解析成json

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏