解码OkHttp JSON响应

Decode an OkHttp JSON Response

1.简介

在本教程中,我们将探索几种使用OkHttp解码JSON响应的技术。

2. OkHttp响应

OkHttp是Java和Android的HTTP客户端,具有透明处理GZIP,响应缓存和从网络问题中恢复的功能。

尽管具有这些出色的功能,但OkHttp并没有针对JSON,XML和其他内容类型的内置编码器/解码器。但是,我们可以在XML / JSON绑定库的帮助下实现这些功能,也可以使用Feign或Retrofit之类的高级库。

为了实现我们的JSON解码器,我们需要从服务调用的结果中提取JSON。为此,我们可以通过Response对象的body()方法访问主体。 ResponseBody类具有几个用于提取此数据的选项:

  • byteStream():将正文的原始字节公开为InputStream;我们可以将其用于所有格式,但通常用于二进制文件和文件

  • charStream():当我们有文本响应时,charStream()将其InputStream包装在Reader中,并根据响应的内容类型或" UTF-8"(如果未在响应头中设置charset)来处理编码;但是,在使用charStream()时,我们无法更改Reader的编码

  • string():以String的形式返回整个响应主体;管理与charStream()相同的编码,但是如果我们需要不同的编码,则可以使用source()。readString(charset)代替

  • 在本文中,我们将使用string(),因为我们的响应很小,并且没有内存或性能问题。当性能和内存很重要时,byteStream()和charStream()方法在生产系统中是更好的选择。

    首先,我们将okhttp添加到我们的pom.xml文件中:

    1
    2
    3
    4
    5
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        okhttp</artifactId>
        <version>3.14.2</version>
    </dependency>

    然后,我们对SimpleEntity建模以测试我们的解码器:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class SimpleEntity {
        protected String name;

        public SimpleEntity(String name) {
            this.name = name;
        }
       
        // no-arg constructor, getters, and setters
    }

    现在,我们将开始测试:

    1
    2
    3
    4
    5
    SimpleEntity sampleResponse = new SimpleEntity("Baeldung");

    OkHttpClient client = // build an instance;
    MockWebServer server = // build an instance;
    Request request = new Request.Builder().url(server.url("...")).build();

    3.用Jackson解码ResponseBody

    Jackson是JSON-Object绑定最受欢迎的库之一。

    让我们将jackson-databind添加到我们的pom.xml中:

    1
    2
    3
    4
    5
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        jackson-databind</artifactId>
        <version>2.9.9</version>
    </dependency>

    通过Jackson的ObjectMapper,我们可以将JSON转换为对象。因此,我们可以使用ObjectMapper.readValue()解码响应:

    1
    2
    3
    4
    5
    6
    ObjectMapper objectMapper = new ObjectMapper();
    ResponseBody responseBody = client.newCall(request).execute().body();
    SimpleEntity entity = objectMapper.readValue(responseBody.string(), SimpleEntity.class);

    Assert.assertNotNull(entity);
    Assert.assertEquals(sampleResponse.getName(), entity.getName());

    4.用Gson解码ResponseBody

    Gson是另一个有用的库,用于将JSON映射到对象,反之亦然。

    让我们将gson添加到我们的pom.xml文件中:

    1
    2
    3
    4
    5
    <dependency>
        <groupId>com.google.code.gson</groupId>
        gson</artifactId>
        <version>2.8.5</version>
    </dependency>

    让我们看看如何使用Gson.fromJson()解码响应主体:

    1
    2
    3
    4
    5
    6
    Gson gson = new Gson();
    ResponseBody responseBody = client.newCall(request).execute().body();
    SimpleEntity entity = gson.fromJson(responseBody.string(), SimpleEntity.class);

    Assert.assertNotNull(entity);
    Assert.assertEquals(sampleResponse.getName(), entity.getName());

    5.结论

    在本文中,我们探索了几种使用Jackson和Gson解码OkHttp的JSON响应的方法。

    完整的示例可从GitHub上获得。