【问题标题】:How make a custom Retrofit ConverterFactory to transform ReponseBody to a new ResponseBody?如何制作自定义 Retrofit ConverterFactory 将 ReponseBody 转换为新的 ResponseBody?
【发布时间】:2020-09-13 04:11:19
【问题描述】:

我想将“windows-1252”中编码的服务的答案转换为“unicode”。我正在尝试使用自定义转换器工厂进行改造以完成这项工作。我的自定义转换器尝试拦截 ResponseBody 类,更改字符编码,并返回一个新的 ResponseBody 以进行改造以进行处理。 但它没有用。显然,内置转换器的改造首先拦截了 ResponseBody 类,并且无法再次处理它。 有什么办法可以避免这种行为?

注意:当我得到响应时,我可以使用 map 函数获取它,但我想在改造中学习。

这是我的代码。

AnsiconverterFactory.java
-------------------------

public class AnsiConverterFactory extends Converter.Factory {
    public static AnsiConverterFactory create() {
        return new AnsiConverterFactory();
    }

    private AnsiConverterFactory() {
    }

    @Override
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        if (type == ResponseBody.class) {
            return AnsiResponseBodyConverter.INSTANCE;
        }
        return null;
    }

    @Override
    public Converter<?, String> stringConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
        return super.stringConverter(type, annotations, retrofit);
    }

    @Override
    public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
        return null;
    }
}
AnsiResponseBodyConverter.java
------------------------------
public class AnsiResponseBodyConverter implements Converter<ResponseBody, ResponseBody> {
    static final AnsiResponseBodyConverter INSTANCE = new AnsiResponseBodyConverter();

    @Override
    public ResponseBody convert(ResponseBody value) throws IOException {
        Log.d("CONVERTER", " En convert de responsebodyconverter");
        final CharBuffer todo = Charset.forName("windows-1252").decode(ByteBuffer.wrap(value.bytes()));
        return ResponseBody.create(value.contentType(), todo.toString());

    }
}

以及在应用中的使用:

Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://...some webservice here")
                .addConverterFactory(BitmapConverterFactory.create())
                .addConverterFactory(AnsiConverterFactory.create())
                .client(clientBuilder.build())
                .addCallAdapterFactory(RxJava3CallAdapterFactory.create())
                .build();

【问题讨论】:

  • 可以加个okhttp拦截器来转换responsebody吗?
  • 是的。我做到了。它奏效了。

标签: java android retrofit2 okhttp


【解决方案1】:

我终于设法在 okhttp 中使用拦截器解决了这个问题。这是代码:

class LoggingInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());
        ResponseBody body = response.body();
        if (body.contentType().equals(MediaType.parse("text/csv"))) {
            final CharBuffer todo = Charset.forName("windows-1252").decode(ByteBuffer.wrap(body.bytes()));
            body = ResponseBody.create(body.contentType(), todo.toString());
            Response.Builder builder = response.newBuilder();
            return  builder.headers(response.headers())
                    .body(body)
                    .build();
        }
        return response;
    }
}

这只是在改造构建之前。

OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder()
            .addInterceptor(new LoggingInterceptor());

【讨论】:

  • 在调用ResponseBody的方法之前,检查是否为null。
猜你喜欢
  • 1970-01-01
  • 2016-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-31
  • 2010-09-26
  • 1970-01-01
相关资源
最近更新 更多