Как сделать настраиваемый Retrofit ConverterFactory для преобразования ReponseBody в новый ResponseBody? - PullRequest
0 голосов
/ 26 мая 2020

Я хотел бы преобразовать ответ службы, которая кодируется в «windows -1252», в «unicode». Я пытаюсь использовать фабрику нестандартных преобразователей для модернизации системы sh, которая работает. Мой пользовательский преобразователь пытается перехватить класс ResponseBody, изменить кодировку символов и вернуть новый ResponseBody для модификации для обработки. Но это не сработало. Судя по всему, модифицированные встроенные преобразователи сначала перехватывают класс ResponseBody, и он не может быть обработан снова. Есть ли способ избежать такого поведения?

Примечание: я могу получить его с помощью функции карты, когда у меня есть ответ, но я хотел бы научиться делать это при модернизации.

Это мой код.

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

1 Ответ

1 голос
/ 31 мая 2020

Мне наконец удалось решить проблему с помощью перехватчика в 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());
...