本文介绍了Retrofit 2.0-beta-2将文字引号添加到MultiPart值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

要升级到Retrofit 2.0并遇到这个奇怪的问题.

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
    @POST("user/login/")
    Call<SessionToken> userLogin(@Part("username") String username, @Part("password") String password);
}

当我查看服务器端的键值POST参数时,它们的打印方式如下

When I look at the key value POST params on the server side they print like this

username : "brian"
password : "password"

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

The same method using retrofit 1.9 the K:V pairs look like

username : brian
password : password

它在POST变量中添加了文字引号

It's adding literal quotes to the POST variables

如果我使用其他任何其他客户端,则变量的打印方式与不带引号的第二种方式一样.

If I use any other rest client the variables print like the second way without the quotes.

这是我如何使用拦截器构建Retrofit实例

Here is how I build the Retrofit instance with an interceptor

 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();

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

I imagine i'm doing something wrong with the converter but not sure what.

还有其他人遇到过这个问题吗?我知道它在Beta版中,但使用非常普遍.

Has anyone else ran into this problem yet? I know its in beta but it's pretty widly used.

推荐答案

这是因为它通过JSON转换器运行.

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

解决方案1:使用RequestBody代替String

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

构建RequestBody:

Build RequestBody:

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

启动网络操作:

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

解决方案2::创建一个自定义ConverterFactory来处理字符串部分值.

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

适用于: Retrofit2最终版本而非Beta. (com.squareup.retrofit2:retrofit:2.0.0)

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

创建您的StringConverterFactory:

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

}

添加到改造实例:

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

注意: StringConverterFactory应该在GsonConverterFactory之前添加!

Attention: StringConverterFactory should add before GsonConverterFactory!

然后您可以直接将String用作零件值.

then you can use String as part value directly.

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

这篇关于Retrofit 2.0-beta-2将文字引号添加到MultiPart值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 12:41