Retrofit 2.0-beta-2正在为MultiPart值添加文字引号

Bri*_*ian 25 httpclient androidhttpclient retrofit okhttp

我们升级到Retrofit 2.0并遇到了这个奇怪的问题.

我有一个方法来记录用户

public interface ApiInterface {

    @Multipart
    @POST("user/login/")
    Call<SessionToken> userLogin(@Part("username") String username, @Part("password") String password);
}
Run Code Online (Sandbox Code Playgroud)

当我查看服务器端的键值POST params时,它们就像这样打印

username : "brian"
password : "password"
Run Code Online (Sandbox Code Playgroud)

使用改造1.9的相同方法K:V对看起来像

username : brian
password : password
Run Code Online (Sandbox Code Playgroud)

它正在为POST变量添加文字引号

如果我使用任何其他休息客户端,变量打印就像没有引号的第二种方式.

以下是我使用拦截器构建Retrofit实例的方法

 OkHttpClient client = new OkHttpClient();
    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();

            // Customize the request
            Request request = original.newBuilder()
                    .header("Accept", "application/json")
                    .header("Authorization", myPrefs.accessToken().getOr(""))
                    .method(original.method(), original.body())
                    .build();

            Response response = chain.proceed(request);

            // Customize or return the response
            return response;
        }
    });

    Ok2Curl.set(client);

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(apiEndpoint)
            .addConverterFactory(GsonConverterFactory.create())
            .client(client)
            .build();
Run Code Online (Sandbox Code Playgroud)

我想我在转换器上做错了但不确定是什么.

还有其他人遇到过这个问题吗?我知道它处于测试阶段但它的使用非常广泛.

Loy*_*yea 31

这是因为它正在运行JSON转换器.

解决方案1: 使用RequestBody而不是String

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

构建RequestBody:

RequestBody usernameBody = RequestBody.create(MediaType.parse("text/plain"), usernameStr);
RequestBody passwordBody = RequestBody.create(MediaType.parse("text/plain"), passwordStr);
Run Code Online (Sandbox Code Playgroud)

启动网络运营:

 retrofit.create(ApiInterface.class).userLogin(usernameBody , passwordBody).enqueue()....
Run Code Online (Sandbox Code Playgroud)

Solution2:创建一个自定义ConverterFactory来处理String部分值.

对于: Retrofit2最终版本不是beta.(com.squareup.retrofit2:改型:2.0.0)

创建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;
}

}
Run Code Online (Sandbox Code Playgroud)

添加到您的改造实例:

retrofit = new Retrofit.Builder()
            .baseUrl(SERVER_URL)
            .client(client)
            .addConverterFactory(StringConverterFactory.create())
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
Run Code Online (Sandbox Code Playgroud)

注意: StringConverterFactory应该先添加GsonConverterFactory!

那么你可以String直接用作零件值.

您可以在https://github.com/square/retrofit/issues/1210中找到有关此问题的更多信息


nic*_*ich 6

我有同样的问题,以及解决方法:

1)添加到build.gradle:

compile 'com.squareup.retrofit2:converter-scalars:2.1.0' // Remember to add the same version
Run Code Online (Sandbox Code Playgroud)

2)在此处添加一行:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(URL_BASE)
                .addConverterFactory(ScalarsConverterFactory.create()) // this line
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(getUnsafeOkHttpClient())
                .build();
Run Code Online (Sandbox Code Playgroud)


Ped*_*aca 4

那样的话该怎么办呢?

RequestBody caption = RequestBody.create(MediaType.parse("text/plain"), new String("caption"));
Run Code Online (Sandbox Code Playgroud)