Перейти к основному содержимому

Декодировать ответ OkHttp JSON

· 3 мин. чтения

1. Введение

В этом руководстве мы рассмотрим несколько методов декодирования ответа JSON при использовании OkHttp .

2. Ответ OkHttp

OkHttp — это HTTP-клиент для Java и Android с такими функциями, как прозрачная обработка GZIP, кэширование ответов и восстановление после сетевых проблем.

Несмотря на эти замечательные функции, OkHttp не имеет встроенного кодировщика/декодера для JSON, XML и других типов содержимого. Однако мы можем реализовать их с помощью библиотек привязки XML/JSON или использовать библиотеки высокого уровня, такие как Feign или Retrofit .

Чтобы реализовать наш декодер JSON, нам нужно извлечь JSON из результата вызова службы. Для этого мы можем получить доступ к телу через метод body () объекта Response . Класс ResponseBody имеет несколько вариантов извлечения этих данных:

  • byteStream() : предоставляет необработанные байты тела как InputStream ; мы можем использовать это для всех форматов, но обычно это используется для двоичных файлов и файлов ``
  • charStream() : когда у нас есть текстовый ответ, charStream() оборачивает свой InputStream в Reader и обрабатывает кодировку в соответствии с типом содержимого ответа или «UTF-8», если набор символов не установлен в заголовке ответа; однако при использовании charStream() мы не можем изменить кодировку Reader
  • string() : возвращает все тело ответа в виде String ; управляет кодировкой так же, как charStream() , но если нам нужна другая кодировка, мы можем вместо этого использовать source().readString(charset)

В этой статье мы собираемся использовать string() , так как наш ответ небольшой и у нас нет проблем с памятью или производительностью. Методы byteStream() и charStream() лучше подходят для производственных систем, когда важны производительность и объем памяти.

Для начала добавим okhttp в наш файл pom.xml:

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.2</version>
</dependency>

Затем мы моделируем SimpleEntity для тестирования наших декодеров:

public class SimpleEntity {
protected String name;

public SimpleEntity(String name) {
this.name = name;
}

// no-arg constructor, getters, and setters
}

Теперь мы собираемся начать наш тест:

SimpleEntity sampleResponse = new SimpleEntity("ForEach");

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

3. Расшифруйте ResponseBody с помощью Джексона

Jackson — одна из самых популярных библиотек для привязки JSON-Object.

Давайте добавим jackson-databind в наш pom.xml:

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.0</version>
</dependency>

ObjectMapper Джексона позволяет нам конвертировать JSON в объект. Таким образом, мы можем декодировать ответ, используя ObjectMapper.readValue() :

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. Декодируйте ResponseBody с помощью Gson

Gson — еще одна полезная библиотека для сопоставления JSON с объектами и наоборот.

Давайте добавим gson в наш файл pom.xml:

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>

Давайте посмотрим, как мы можем использовать Gson.fromJson() для декодирования тела ответа:

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. Вывод

В этой статье мы рассмотрели несколько способов декодирования JSON-ответа OkHttp с помощью Jackson и Gson.

Полный пример доступен на GitHub .