如何制作自定义 Retrofit ConverterFactory 以将 ReponseBody 转换为新的 ResponseBody?

How make a custom Retrofit ConverterFactory to transform ReponseBody to a new ResponseBody?

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

注意:当我有响应时,我可以使用映射函数来获取它,但我想在改造中学习如何做。

这是我的代码。

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中使用拦截器解决了问题。这是代码:

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

这是在 Retrofit 构建之前。

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