1. Обзор
Наши службы часто общаются с другими службами REST для получения информации.
С 5 весны мы будем пользоваться WebClient для выполнения этих запросов реактивным, не блокирующим способом. WebClient является частью новой WebFlux Рамки, построенные поверх Проект Реактор . Он имеет беглый, реактивный API, и он использует протокол HTTP в своей основной реализации.
Когда мы делаем веб-запрос, данные часто возвращаются как JSON. WebClient может преобразовать это для нас.
В этой статье мы узнаем, как преобразовать JSON Array в java- Массив Объект , Массив POJO , и Список POJO с использованием WebClient .
2. Зависимости
Использовать WebClient, Нам нужно добавить пару зависимостей к нашему пом.xml:
org.springframework.boot spring-boot-starter-webflux org.projectreactor reactor-spring 1.0.1.RELEASE
3. JSON, POJO, и обслуживание
Начнем с конечной точки http://localhost:8080/readers , который возвращает список читателей с их любимыми книгами, как массив JSON:
[{ "id": 1, "name": "reader1", "favouriteBook": { "author": "Milan Kundera", "title": "The Unbearable Lightness of Being" } }, { "id": 2, "name": "reader2" "favouriteBook": { "author": "Douglas Adams", "title": "The Hitchhiker's Guide to the Galaxy" } }]
Мы будем требовать соответствующей Читатель и Книжный классы для обработки данных:
public class Reader { private int id; private String name; private Book favouriteBook; // getters and setters.. }
public class Book { private final String author; private final String title; // getters and setters.. }
Для реализации интерфейса мы пишем ReaderConsumerServiceImpl с WebClient как его зависимость:
public class ReaderConsumerServiceImpl implements ReaderConsumerService { private final WebClient webClient; public ReaderConsumerServiceImpl(WebClient webclient) { this.webclient = webclient; } // ... }
4. Сопоставление списка объектов JSON
Когда мы получаем массив JSON по запросу REST, существует несколько способов преобразовать его в коллекцию Java. Давайте рассмотрим различные варианты и посмотрим, как легко обработать возвращенные данные. Мы посмотрим на извлечение любимых книг читателей.
4.1. Моно vs. Флюкс
Проект Реактор ввела две реализации Издатель: Моно и Флюс .
Flux
Когда мы знаем, что результаты возвращаются все сразу – как и в нашем случае использования – мы можем использовать Моно
4.2. WebClient с объектом Array
Во-первых, давайте ПОЛУЧИТЬ звонок с WebClient.get и использовать Моно типа Объект для сбора ответа:
Mono
Далее, давайте извлекаем тело в наш массив Объект :
Object[] objects = response.block();
Фактическое Объект вот произвольная структура, которая содержит наши данные. Давайте преобразуем его в массив Читатель Объектов.
Для этого нам понадобится ОбъектМаппер :
ObjectMapper mapper = new ObjectMapper();
Здесь мы объявили его в ряд, хотя это обычно делается как частные статические окончательные член класса.
Наконец, мы готовы извлечь любимые книги читателей и собрать их в список:
return Arrays.stream(objects) .map(object -> mapper.convertValue(object, Reader.class)) .map(Reader::getFavouriteBook) .collect(Collectors.toList());
Когда мы спрашиваем Джексон deserializer производить Объект в качестве целевого типа, он на самом деле deserializes JSON в серии LinkedHashMap объекты . После обработки с конвертироватьВалю является неэффективным. Мы можем избежать этого, если мы предоставляем наш желаемый тип Джексона во время deserialization.
4.3. WebClient с Reader Array
Мы можем предоставить Читатель вместо Объект к нашему WebClient :
Monoresponse = webClient.get() .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(Reader[].class).log(); Reader[] readers = response.block(); return Arrays.stream(readers) .map(Reader:getFavouriteBook) .collect(Collectors.toList());
Здесь мы можем заметить, что нам больше не нужна ObjectMapper.convertValue . Тем не менее, нам все еще нужно сделать дополнительные преобразования, чтобы использовать Java Поток API и для работы нашего кода с Список .
4.4. WebClient со списком читателей
Если мы хотим, чтобы Джексон Список Читатель s вместо массива, мы должны описать Список мы хотим творить. Для этого мы предоставляем Параметризированный ТипРеференс производства анонимный внутренний класс к методу:
Monoresponse = webClient.get() .accept(MediaType.APPLICATION_JSON) .retrieve() .bodyToMono(new ParameterizedTypeReference
() {}); List readers = response.block(); return readers.stream() .map(Reader::getFavouriteBook) .collect(Collectors.toList());
Это дает нам Список с чем мы можем работать.
Давайте глубже погрузимся в почему мы должны использовать Параметризированный ТипРеференс .
Spring’s WebClient может легко deserialize JSON в Читатель.class когда информация о типе доступна во время выполнения.
С дженериками, однако, тип стирания происходит, если мы пытаемся использовать Список
Используя Параметризированный ТипРеференс , мы можем преодолеть эту проблему. Мгновенное использование его как анонимного внутреннего класса использует тот факт, что подклассы общих классов содержат информацию типа компиляции времени, которая не подлежит стирания типа и может потребляться через отражение.
5. Заключение
В этом учебнике мы увидели три различных способа обработки объектов JSON с помощью WebClient . Мы видели способы указания типов массивов Объект и наши собственные пользовательские классы.
Затем мы узнали, как предоставить тип информации для получения Список с помощью Параметризированный ТипРеференс .
Как всегда, код для этой статьи доступен более на GitHub .