Рубрики
Без рубрики

Spring WebClient против RestTemplate – Сравнение и особенности

Введение Весной 5 был представлен новый реактивный веб-клиент, называемый веб-клиентом. В этом посте,… С тегами spring, веб-клиент, resttemplate, java.

Вступление

Весной 5 был представлен новый реактивный веб-клиент, называемый веб-клиентом. В этом посте я покажу, когда и как мы можем использовать веб-клиент Spring против RestTemplate. Я также опишу, какие функции предлагает веб-клиент.

Что такое RestTemplate?

RestTemplate – это центральный класс Spring, который обеспечивает HTTP-доступ со стороны клиента. RestTemplate предлагает HTTP-методы POST, GET, PUT, DELETE, HEAD и OPTIONS. Простой вариант использования RestTemplate заключается в использовании веб-служб Restful.

Вы можете создать компонент, который предоставляет экземпляр RestTemplate. Затем вы можете @autowire этот компонент в любом классе, в котором вы планируете вызывать службы REST. RestTemplate – это класс, реализующий интерфейс Операции по Отдыху .

Следующий код показывает объявление компонента:

    @Bean
    public RestOperations restOperations()
    {
        return new RestTemplate();
    }

В следующем коде показан клиент REST Клиент Yelp вызов REST API Yelp для получения отзывов об аренде недвижимости.

   @Autowired
   private final RestOperations restOperations;

   public List getRentalPropertyReviews(String address)
   {
        String url = buildRestUrl(businessId);
        HttpHeaders httpHeaders = new HttpHeaders();
        String apiKey = getApiKey(YELP);
        httpHeaders.add("Authorization","Bearer " + apiKey);
        httpHeaders.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity entity = new HttpEntity("parameters", httpHeaders);
        ResponseEntity response;

        try
        {
            response = restOperations.exchange(url, HttpMethod.GET,entity, String.class);
        }
        catch(RestClientException e)
        {
            throw new RuntimeException("Unable to retrieve reviews", e);
        }

    }

В приведенном выше коде мы создаем заголовки HTTP, добавляя ключ API REST Yelp как часть авторизации. Мы вызываем метод GET, чтобы получить данные обзора.

В принципе, нужно сделать

  • Автоматическое подключение объекта RestTemplate
  • Создавайте HTTP-заголовки с авторизацией и типом контента
  • Используйте HttpEntity для обертывания объекта запроса
  • Укажите URL-адрес, метод Http и тип возвращаемого значения для метода exchange.

Что такое Веб-клиент?

Весной 5 был представлен реактивный веб-клиент, называемый веб-клиентом. Это интерфейс для выполнения веб-запросов. Это часть реактивного модуля Spring web. Веб-клиент в конечном итоге заменит RestTemplate.

Самое главное, что веб-клиент является реактивным, неблокирующим, асинхронным и работает по протоколу HTTP Http/1.1.

Чтобы использовать WebClient, нужно сделать

  • Создайте экземпляр WebClient
  • Сделайте запрос к конечной точке REST
  • Обработайте ответ
WebClient webClient = WebClient
       .builder()
       .baseUrl("https://localhost:8443")
       .defaultCookie("cookieKey", "cookieValue")
       .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) 
       .defaultUriVariables(Collections.singletonMap("url", "https://localhost:8443"))
       .build();

Приведенный выше код показывает один из способов создания экземпляра веб-клиента. Вы также можете создать экземпляр, просто используя WebClient.create();

Веб-клиент предоставляет два метода обмена и извлекать . метод exchange обычно извлекает ответ вместе со статусом и заголовками. метод извлечения получает тело ответа напрямую. Это проще в использовании.

Также в зависимости от того, пытаетесь ли вы получить в ответ один объект или список объектов, вы можете использовать mono или поток .

this.webClient =
                webClientBuilder.baseUrl("http://localhost:8080/v1/betterjavacode/").build();

this.webClient.get()
                .uri("users")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToFlux(UserDto.class).collectList();

Приведенный выше код в основном использует WebClient для получения списка пользователей из REST API.

Весенний веб-клиент против RestTemplate

Мы уже знаем одно ключевое различие между этими двумя функциями. Веб-клиент является неблокирующим клиентом, а RestTemplate – блокирующим клиентом.

RestTemplate использует API сервлетов Java под капотом. API сервлета – это синхронный вызывающий объект. Поскольку он синхронный, поток будет блокироваться до тех пор, пока webclient не ответит на запрос.

Следовательно, количество запросов, ожидающих результатов, будет увеличиваться. Это приведет к увеличению объема памяти.

С другой стороны, веб-клиент является асинхронным неблокирующим клиентом. Он использует реактивный каркас пружины под капотом. Веб-клиент является частью модуля Spring-Web Flux.

Spring WebFlux использует библиотеку реакторов . Он предоставляет API Mono и Flux для работы с последовательностями данных. Реактор – это библиотека реактивных потоков. И все его операторы поддерживают неблокирующее обратное давление.

Пример использования WebClient в приложении Spring Boot

Мы можем объединить возможности Spring Web MVC и Spring Web Flux. В этом разделе я создам образец приложения. Это приложение вызовет REST API с помощью Web Flux, и мы создадим ответ, чтобы показать веб-страницу со списком пользователей.

RestController для этого примера используется API для получения списка пользователей:

package com.betterjavacode.webclientdemo.controllers;

import com.betterjavacode.webclientdemo.dto.UserDto;
import com.betterjavacode.webclientdemo.managers.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("v1/betterjavacode")
public class UserController
{
    @Autowired
    public UserManager userManager;

    @GetMapping(value = "/users")
    public List getUsers()
    {
        return userManager.getAllUsers();
    }
}

Контроллер класс, который использует WebClient для вызова REST API, выглядит следующим образом:

package com.betterjavacode.webclientdemo.controllers;

import com.betterjavacode.webclientdemo.clients.UserClient;
import com.betterjavacode.webclientdemo.dto.UserDto;
import com.betterjavacode.webclientdemo.managers.UserManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@Controller
public class MainController
{
    @Autowired
    UserClient userClient;

    @GetMapping(value = "/")
    public String home()
    {
        return "home";
    }

    @GetMapping(value = "/users")
    public String getUsers(Model model)
    {
        List users = userClient.getUsers().block();

        model.addAttribute("userslist", users);
        return "users";
    }
}


Теперь важный фрагмент кода пользовательского клиента – это то, где мы будем использовать WebClient для вызова REST API.

package com.betterjavacode.webclientdemo.clients;

import com.betterjavacode.webclientdemo.dto.UserDto;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.List;

@Service
public class UserClient
{

    private WebClient webClient;

    public UserClient(WebClient.Builder webClientBuilder)
    {
        this.webClient =
                webClientBuilder.baseUrl("http://localhost:8080/v1/betterjavacode/").build();
    }

    public Mono getUsers()
    {
        return this.webClient.get()
                .uri("users")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToFlux(UserDto.class).collectList();
    }
}

Приведенный выше код показывает, как сначала создается веб-клиент, а затем используется для получения ответа от REST API. метод извлечения предлагает два варианта моно или потока. Поскольку у нас есть более одного пользователя, мы используем flux.

Это показывает, что мы можем использовать реактивный, неблокирующий веб-клиент, который является частью WebFlux в Spring Web MVC framework.

Что Еще есть в веб-клиенте Spring?

Веб-клиент Spring является частью Spring Web Flux фреймворка. Основное преимущество этого API заключается в том, что разработчику не нужно беспокоиться о параллелизме или потоках. Веб-клиент позаботится об этом.

Веб-клиент имеет встроенную поддержку клиентской библиотеки HTTP для выполнения запросов. Это включает в себя httpкомпоненты Apache, Реактивный HttpClient Jetty или реакторную сетку.

Веб-клиент.конструктор() предлагает следующие опции:

uriBuilderFactory – настроенный uriBuilderFactory для использования базового URL-адреса Defaultheader – Заголовки для каждого запроса файл Cookie по умолчанию – Файлы cookie для каждого запроса запрос по умолчанию – Настроить каждый запрос фильтр – Фильтр клиентов для каждого запроса Стратегии обмена – Настройки чтения/записи HTTP-сообщений Я уже показывал метод извлечения в приведенной выше демонстрации кода.

Веб-клиент также предлагает метод обмена с такими вариантами, как обмен на Mono и обмен на Flux”.

С помощью атрибута() мы также можем добавить атрибуты в запрос.

В качестве альтернативы можно также использовать WebClient для синхронного использования. В моем примере выше основного контроллера я использую блок для получения конечного результата. Это в основном блокирует параллельные вызовы, пока мы не получим результат.

Одной из ключевых функций, предлагаемых веб-клиентом, является retryWhen() . Для более устойчивой системы это отличная функция, которую вы можете добавить при использовании WebClient.

     webClient
        .get()
        .uri(String.join("", "/users", id))
        .retrieve()
        .bodyToMono(UserDto.class)
        .retryWhen(Retry.fixedDelay(5, Duration.ofMillis(100)))
        .block();

Повторите, когда принимает класс повтора в качестве параметра.

Веб-клиент также предлагает функцию обработки ошибок. do On Error() позволяет обработать ошибку. Он срабатывает, когда моно заканчивается ошибкой. при ошибке Resume() является резервным вариантом, основанным на ошибке.

Вывод

В этом посте я показал, что такое Spring WebClient, как мы можем использовать Spring Web Client против RestTemplate и какие различные функции он предлагает.

Оригинал: “https://dev.to/betterjavacode/spring-webclient-vs-resttemplate-comparison-and-features-3cgp”