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 .