【问题标题】:How do I convert a successful Response body to a specific type using retrofit?如何使用改造将成功的响应正文转换为特定类型?
【发布时间】:2014-12-20 17:24:55
【问题描述】:

在异步模式下改造调用

public void success(T t, Response rawResponse)

t 是转换后的响应,而 rawResponse 是原始响应。这使您可以访问原始响应和转换后的响应。

在同步模式下,您可以获得转换后的响应或原始响应

转换的响应

@GET("/users/list")
List<User> userList();

原始响应

@GET("/users/list")
Response userList();

Response 对象确实有获取正文的方法

TypedInput  getBody()

retrofit api 确实有一个转换器类,可以将其转换为 java 对象

Object fromBody(TypedInput body,Type type)

但我不知道如何获取 Converter 对象的实例

我可能能够创建 Converter 类的实例,但这需要了解用于创建 RestAdapter 的 Gson 对象,而我可能无法访问该对象。理想情况下,我想直接通过 RestAdpater 获得对转换器对象的引用。


以下任何一项都会回答我的问题:

  1. 有没有办法获得对改造使用的默认转换器的引用?
  2. 有人知道默认转换器是如何构造的吗? (没有默认构造函数,有两个构造函数public GsonConverter(Gson gson)和public GsonConverter(Gson gson, String charset)
  3. 还有其他方法可以在同步模式下同时获取原始响应和转换后的响应吗?

【问题讨论】:

    标签: android retrofit


    【解决方案1】:

    这是一个 StringConverter 类的示例,它实现了改造中的 Converter。基本上你必须覆盖fromBody() 并告诉它你想要什么。

    public class StringConverter implements Converter {
    
        /*
         * In default cases Retrofit calls on GSON which expects a JSON which gives
         * us the following error, com.google.gson.JsonSyntaxException:
         * java.lang.IllegalStateException: Expected BEGIN_OBJECT but was
         * BEGIN_ARRAY at line x column x
         */
    
        @Override
        public Object fromBody(TypedInput typedInput, Type type)
                throws ConversionException {
    
            String text = null;
            try {
                text = fromStream(typedInput.in());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return text;
        }
    
        @Override
        public TypedOutput toBody(Object o) {
            return null;
        }
    
        // Custom method to convert stream from request to string
        public static String fromStream(InputStream in) throws IOException {
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            StringBuilder out = new StringBuilder();
            String newLine = System.getProperty("line.separator");
            String line;
            while ((line = reader.readLine()) != null) {
                out.append(line);
                out.append(newLine);
            }
            return out.toString();
        }
    }
    

    将此应用于您的请求,您必须执行以下操作:

    // initializing Retrofit's rest adapter
    RestAdapter restAdapter = new RestAdapter.Builder()
            .setEndpoint(ApiConstants.MAIN_URL).setLogLevel(LogLevel.FULL)
            .setConverter(new StringConverter()).build();
    

    【讨论】:

    • 感谢您的回复,我想我只是在寻找“getCoverter()”方法。我对转换器很满意(在我目前的情况下是默认转换器),但是如果您在同步模式下运行,您只能获得原始响应或转换后的响应。原始响应具有未转换的主体,我可以对其进行转换,但我需要一个转换器的实例。我可以创建一个单独的实例,使用您的示例我会说转换器 = new StringConverter();,但我想我应该能够以某种方式说转换器 = restAdapter.getConverter();我希望这是有道理的
    • 解决办法是什么?
    • 我从 2 天开始就一直在寻找这个!谢谢朋友!
    • @PalakDarji 很高兴它有帮助:D 干杯!
    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 2014-12-08
    • 2019-09-18
    • 2019-09-21
    • 2016-09-28
    • 2022-11-14
    • 2020-03-20
    • 1970-01-01
    相关资源
    最近更新 更多