Retrofit 2.0-beta-2 is adding literal quotes to MultiPart values

后端 未结 7 1713
终归单人心
终归单人心 2020-12-11 00:18

Went to upgrade to Retrofit 2.0 and running into this weird problem.

I have a method to log a user in

public interface ApiInterface {

    @Multipart         


        
相关标签:
7条回答
  • 2020-12-11 00:52

    This is because it's running through the JSON converter.

    Solution1: use RequestBody instead of String

    public interface ApiInterface {
        @Multipart
        @POST("user/login/")
        Call<SessionToken> userLogin(@Part("username") RequestBody username, @Part("password") RequestBody password);
    }
    

    Build RequestBody:

    RequestBody usernameBody = RequestBody.create(MediaType.parse("text/plain"), usernameStr);
    RequestBody passwordBody = RequestBody.create(MediaType.parse("text/plain"), passwordStr);
    

    Launch network operation:

     retrofit.create(ApiInterface.class).userLogin(usernameBody , passwordBody).enqueue()....
    

    Solution2: Create a custom ConverterFactory to dispose String part value.

    For: Retrofit2 final release not beta. (com.squareup.retrofit2:retrofit:2.0.0)

    Create your StringConverterFactory:

    public class StringConverterFactory extends Converter.Factory {
    private static final MediaType MEDIA_TYPE = MediaType.parse("text/plain");
    
    public static StringConverterFactory create() {
        return new StringConverterFactory();
    }
    
    @Override
    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (String.class.equals(type)) {
            return new Converter<ResponseBody, String>() {
    
                @Override
                public String convert(ResponseBody value) throws IOException {
                    return value.string();
                }
            };
        }
        return null;
    }
    
    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        if(String.class.equals(type)) {
            return new Converter<String, RequestBody>() {
                @Override
                public RequestBody convert(String value) throws IOException {
                    return RequestBody.create(MEDIA_TYPE, value);
                }
            };
        }
    
        return null;
    }
    
    }
    

    Add to your retrofit instance:

    retrofit = new Retrofit.Builder()
                .baseUrl(SERVER_URL)
                .client(client)
                .addConverterFactory(StringConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
    

    Attention: StringConverterFactory should add before GsonConverterFactory!

    then you can use String as part value directly.

    You can find more information about this issue in https://github.com/square/retrofit/issues/1210

    0 讨论(0)
提交回复
热议问题