永远不会调用带有Retrofit 2.0.2的自定义xml转换器

时间:2016-06-16 12:46:33

标签: android retrofit

我必须使用带有xml api响应的retrofit 2.0.2。但我的自定义xml转换器永远不会被调用。

玩弄这个我发现:

  • 如果我使用Volley来解析相同的响应,则调用相同的自定义xml转换器;
  • 如果我将GsonConverterFactory应用于我的RestClient并解析json响应,则调用我的自定义JsonAdapter(@JsonAdapter(SomeAdapter.class))。

任何人,如何调用我的简单xml转换器?我做错了什么,或改造2.0.2不知何故不支持简单的xml转换器。

我解析响应的java类:

import org.simpleframework.xml.Element;
import org.simpleframework.xml.convert.Convert;

public class PassengerResponse {
  @Element
  @Convert(value = SomeConverter.class)
  private String id;
}

永远不会调用的自定义xml转换器:

import org.simpleframework.xml.convert.Converter;
import org.simpleframework.xml.stream.InputNode;
import org.simpleframework.xml.stream.OutputNode;

public class SomeConverter implements Converter<String> {
   @Override
   public String read(InputNode node) throws Exception {
    return null;
   }

   @Override
   public void write(OutputNode node, String value) throws Exception {
   }
}

我的改造RestClient:

import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;

public class RestClient2 {
private UserApiJSON userPassengerApi;
private static final int TIMEOUT = 120000;
private static RestClient2 INSTANCE;

public static RestClient2 getInstance() {
    if (INSTANCE == null) {
        INSTANCE = new RestClient2();
    }
    return INSTANCE;
}

private RestClient2() {

    HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
    loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

    OkHttpClient okHttpClient = new OkHttpClient();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(SimpleXmlConverterFactory.create())
            .client(okHttpClient.newBuilder().connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
                    .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
                    .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
                    .addInterceptor(loggingInterceptor)
                    .build())
            .build();

    userPassengerApi = retrofit.create(UserApiJSON.class);
}

public UserApiJSON getUserPassengerApi() {
    return userPassengerApi;
}
}

3 个答案:

答案 0 :(得分:6)

实际上SimpleXmlConverterFactory有不同的方法来创建它的实例。)如果您只需要使自定义的Converer工作,请执行下一步:

Strategy strategy = new AnnotationStrategy();
Serializer serializer = new Persister(strategy);

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL)
    .addConverterFactory(SimpleXmlConverterFactory.create(serializer))
    .client(okHttpClient.newBuilder().connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
    .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
    .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
    .addInterceptor(loggingInterceptor).build())
    .build();

注意:如果您添加不同的转换器,订单会完成。为什么?观看杰克沃顿presentation

答案 1 :(得分:1)

要使用自定义转换器,您必须创建自定义Converter.Factory。然后将其添加到retrofit使用方法addConverterFactory()。下面的工作示例:

public class StringConverterFactory extends Converter.Factory {

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

而不是添加它改装

Retrofit retrofit = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(SimpleXmlConverterFactory.create())
        .addConverterFactory(StringConverterFactory.create())
        .client(okHttpClient.newBuilder().connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
                .readTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
                .writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS)
                .addInterceptor(loggingInterceptor)
                .build())
        .build();

在Retrofit 2中允许多个转换器。 Jake Wharton的视频讲述了Retrofit 2,它的功能就像多个转换器一样。

Retrofit内部,有一个方法nextRequestBodyConverter可返回适当Type的转换器

答案 2 :(得分:1)

public UsStatesApi providesApi(){

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();

        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        Strategy strategy = new AnnotationStrategy();

        Serializer serializer = new Persister(strategy);

        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .connectTimeout(2, TimeUnit.MINUTES)
                .writeTimeout(2, TimeUnit.MINUTES)
                .readTimeout(2, TimeUnit.MINUTES)
                .build();

        Retrofit retrofit =  new Retrofit.Builder()
                .addConverterFactory(SimpleXmlConverterFactory.create(serializer))
                .baseUrl("http://www.google.com")
                .client(okHttpClient)
                .build();

        return retrofit.create( UsStatesApi.class);

    }