Java >> Java tutorial >  >> Tag >> Spring

Spring WebClient vs RestTemplate – Sammenligning og funktioner

Introduktion

Forår 5 introducerede en ny reaktiv webklient kaldet WebClient. I dette indlæg vil jeg vise, hvornår og hvordan vi kan bruge Spring WebClient vs RestTemplate. Jeg vil også beskrive, hvilke funktioner WebClient tilbyder.

Hvad er RestTemplate?

RestTemplate er en central Spring-klasse, der tillader HTTP-adgang fra klientsiden. RestTemplate tilbyder POST, GET, PUT, DELETE, HEAD og OPTIONS HTTP-metoder. Den simple brug af RestTemplate er at forbruge Restful-webtjenester.

Du kan oprette en bønne, der giver forekomsten af ​​RestTemplate. Du kan derefter @autowire denne bønne i enhver klasse, hvor du planlægger at ringe til REST-tjenester. RestTemplate er klassen, der implementerer grænsefladen RestOperations .

Følgende kode viser deklarationen af ​​bønnen:

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

Følgende kode viser en REST-klient "YelpClient", der ringer til Yelps REST API for at få anmeldelser af lejebolig.

   @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);
        }

    }

I ovenstående kode bygger vi HTTP-headere ved at tilføje Yelps REST API-nøgle som en del af godkendelsen. Vi kalder GET-metoden for at få gennemgangsdata.

Grundlæggende skal man gøre

  • Autowire RestTemplate-objektet
  • Byg HTTP-headere med godkendelse og indholdstype
  • Brug HttpEntity til at ombryde anmodningsobjektet
  • Angiv URL, HTTP-metode og returtype for udvekslingsmetode.

Hvad er WebClient?

Forår 5 introducerede en reaktiv webklient kaldet WebClient. Det er en grænseflade til at udføre webanmodninger. Det er en del af Spring web reactive modul. WebClient vil til sidst erstatte RestTemplate.

Det vigtigste er, at WebClient er reaktivt, ikke-blokerende, asynkront og fungerer over HTTP-protokollen Http/1.1.

For at bruge WebClient skal man gøre

  • Opret en forekomst af WebClient
  • Foretag en anmodning til REST-slutpunktet
  • håndtere svaret

   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();

Ovenstående kode viser en måde at instansiere WebClient på. Du kan også oprette en instans ved blot at bruge WebClient webClient = WebClient.create();

WebClient giver to metoder exchange og retrieve . exchange metoden henter normalt svaret sammen med status og overskrifter. retrieve metode får svarlegemet direkte. Det er nemmere at bruge.

Afhængigt af om du forsøger at hente et enkelt objekt som svar eller en liste over objekter, kan du bruge mono eller flux .

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

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

Ovenstående kode bruger grundlæggende webClient for at hente en liste over brugere fra REST API.

Spring WebClient vs RestTemplate

Vi kender allerede den ene nøgleforskel mellem disse to funktioner. WebClient er en ikke-blokerende klient, og RestTemplate er en blokerende klient.

RestTemplate bruger Java Servlet API under hætten. Servlet API er en synkron opkalder. Fordi den er synkron, vil tråden blokere, indtil webklient svarer på anmodningen.

Følgelig vil anmodninger, der venter på resultater, stige. Dette vil resultere i en stigning i hukommelsen.

På den anden side er WebClient en asynkron ikke-blokerende klient. Den bruger Springs reaktive ramme under hætten. WebClient er en del af Spring-WebFlux-modulet.

Spring WebFlux bruger reaktorbibliotek. Det giver Mono og Flux API til at arbejde datasekvenser. Reactor er et bibliotek med reaktive strømme. Og alle dets operatører understøtter ikke-blokerende modtryk.

Eksempel på, hvordan man bruger WebClient i en Spring Boot-applikation

Vi kan kombinere mulighederne fra Spring Web MVC og Spring WebFlux. I dette afsnit vil jeg oprette et eksempel på en ansøgning. Denne applikation kalder en REST API ved hjælp af WebFlux, og vi vil bygge et svar for at vise en webside med en liste over brugere.

RestController for dette eksempel er en API til at få en liste over brugere:

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();
    }
}

Controller klasse, der bruger en WebClient til at kalde REST API, ser ud som nedenfor:

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";
    }
}

Nu er det vigtige stykke kode i UserClient, hvor vi vil bruge WebClient til at kalde 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<List> getUsers()
    {
        return this.webClient.get()
                .uri("users")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve().bodyToFlux(UserDto.class).collectList();
    }
}

Ovenstående kode viser først at bygge WebClienten og derefter bruge den til at hente svar fra REST API. retrieve metode tilbyder to muligheder for mono eller flux . Da vi har mere end én bruger at hente, bruger vi flux .

Dette viser, at vi kan bruge reaktiv, ikke-blokerende WebClient, som er en del af WebFlux i Spring Web MVC-ramme.

Hvad ellers er der i Spring WebClient?

Spring WebClient er en del af Spring WebFlux rammer. Den største fordel ved denne API er, at udvikleren ikke behøver at bekymre sig om samtidighed eller tråde. WebClient sørger for det.

WebClient har en indbygget HTTP-klientbiblioteksunderstøttelse til at udføre anmodninger med. Det inkluderer Apache HttpComponents , Jetty Reactive HttpClient , eller Reactor Netty .

WebClient.builder() tilbyder følgende muligheder:

  • uriBuilderFactory – tilpasset uriBuilderFactory for at bruge basis-URL
  • defaultHeader – Overskrifter for hver anmodning
  • defaultCookie – Cookies for hver anmodning
  • defaultRequest – At tilpasse hver anmodning
  • filter – Klientfilter for hver anmodning
  • exchangeStrategies – HTTP Message reader/writer tilpasninger

Jeg har allerede vist retrieve metode i ovenstående kodedemo.

WebClient tilbyder også en metode exchange med varianter som exchangeToMono og exchangeToFlux .

Med attribute() , kan vi også tilføje attributter til anmodningen.

Alternativt kan man bruge WebClient også til synkron brug. I mit eksempel ovenfor MainController , jeg bruger block for at få det endelige resultat. Dette blokerer dybest set parallelle opkald, indtil vi får resultatet.

En nøglefunktion, der WebClient tilbud er retryWhen() . For et mere modstandsdygtigt system er det en fantastisk funktion, som du kan tilføje, mens du bruger WebClient .

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

retryWhen tager Retry klasse som en parameter.

WebClient tilbyder også en funktion til fejlhåndtering. doOnError() giver dig mulighed for at håndtere fejlen. Den udløses, når mono slutter med en fejl. onErrorResume() er et fallback baseret på fejlen.

Konklusion

I dette indlæg viste jeg, hvad Spring WebClient er, hvordan vi kan bruge Spring WebClient vs RestTemplate, og hvilke forskellige funktioner det tilbyder.

Hvis du kunne lide dette indlæg, kan du abonnere på min blog her.

Referencer

  1. Spring WebClient – ​​Spring Documentation
  2. WebClient Cheatsheet – Spring WebClient

Java tag