Articles

De Gids voor RestTemplate

Posted on

Overzicht

In deze tutorial gaan we het brede scala aan operaties illustreren waarbij de Spring REST Client – RestTemplate – gebruikt kan worden, en goed gebruikt kan worden.

Voor de API-kant van alle voorbeelden zullen we de RESTful service van hieruit draaien.

Verder lezen:

Basic Authentication with the RestTemplate

Hoe doe je Basic Authentication met de Spring RestTemplate.
Lees meer →

RestTemplate met Digest Authenticatie

Hoe Digest Authenticatie in te stellen voor de Spring RestTemplate met behulp van HttpClient 4.
Lees meer →

Exploring the Spring Boot TestRestTemplate

Lees hoe je de nieuwe TestRestTemplate in Spring Boot kunt gebruiken om een eenvoudige API te testen.
Lees meer →

Deprecation Notice

Sinds Spring Framework 5 heeft Spring, naast de WebFlux stack, een nieuwe HTTP client geïntroduceerd genaamd WebClient.

WebClient is een moderne, alternatieve HTTP client voor RestTemplate. Niet alleen biedt het een traditionele synchrone API, maar het ondersteunt ook een efficiënte nonblocking en asynchrone aanpak.

Dat gezegd hebbende, als we nieuwe applicaties ontwikkelen of een oude migreren, is het een goed idee om WebClient te gebruiken. RestTemplate zal in toekomstige versies worden afgeschreven.

Gebruik GET om bronnen op te halen

3.1. Get Plain JSON

Laten we eenvoudig beginnen en het hebben over GET requests, met een snel voorbeeld met behulp van de getForEntity() API:

RestTemplate restTemplate = new RestTemplate();String fooResourceUrl = "http://localhost:8080/spring-rest/foos";ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class);assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));

Merk op dat we volledige toegang hebben tot de HTTP response, zodat we dingen kunnen doen zoals de status code controleren om er zeker van te zijn dat de operatie succesvol was of werken met de eigenlijke body van de response:

ObjectMapper mapper = new ObjectMapper();JsonNode root = mapper.readTree(response.getBody());JsonNode name = root.path("name");assertThat(name.asText(), notNullValue());

We werken hier met de respons als een standaard String en gebruiken Jackson (en de JSON-knooppuntenstructuur die Jackson biedt) om enkele details te verifiëren.

3.2. POJO ophalen in plaats van JSON

We kunnen de respons ook direct naar een Resource DTO mappen:

public class Foo implements Serializable { private long id; private String name; // standard getters and setters}

Nu kunnen we gewoon de getForObject API in het sjabloon gebruiken:

Foo foo = restTemplate .getForObject(fooResourceUrl + "/1", Foo.class);assertThat(foo.getName(), notNullValue());assertThat(foo.getId(), is(1L));

Gebruik HEAD om Headers op te halen

Laten we nu even snel kijken naar het gebruik van HEAD voordat we verder gaan met de meer gebruikelijke methoden.

We gaan hier de headForHeaders() API gebruiken:

HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl);assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));

Gebruik POST om een Resource te maken

Om een nieuwe Resource in de API te maken, kunnen we goed gebruik maken van de postForLocation(), postForObject() of postForEntity() APIs.

De eerste retourneert de URI van de nieuw aangemaakte Resource, terwijl de tweede de Resource zelf retourneert.

5.1. De postForObject() API

RestTemplate restTemplate = new RestTemplate();HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class);assertThat(foo, notNullValue());assertThat(foo.getName(), is("bar"));

5.2. De postForLocation() API

Laten we eens kijken naar de operatie die in plaats van de volledige Resource terug te geven, alleen de Location van die nieuw aangemaakte Resource teruggeeft:

HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));URI location = restTemplate .postForLocation(fooResourceUrl, request);assertThat(location, notNullValue());

5.3. De exchange() API

Laten we eens kijken hoe je een POST doet met de meer generieke exchange API:

RestTemplate restTemplate = new RestTemplate();HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));ResponseEntity<Foo> response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED)); Foo foo = response.getBody(); assertThat(foo, notNullValue());assertThat(foo.getName(), is("bar"));

5.4. Formuliergegevens verzenden

Volgende, laten we eens kijken hoe we een formulier verzenden met de POST methode.

Eerst moeten we de Content-Type header instellen op application/x-www-form-urlencoded.

Dit zorgt ervoor dat een grote querystring naar de server kan worden gestuurd, met daarin naam/waarde-paren gescheiden door &:

HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

We kunnen de formuliervariabelen in een LinkedMultiValueMap verpakken:

MultiValueMap<String, String> map= new LinkedMultiValueMap<>();map.add("id", "1");

Daarna bouwen we het Request op met behulp van een HttpEntity instantie:

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

Ten slotte kunnen we verbinding maken met de REST-service door restTemplate.postForEntity() op het eindpunt: /foos/form

ResponseEntity<String> response = restTemplate.postForEntity( fooResourceUrl+"/form", request , String.class); assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

Gebruik OPTIONS om toegestane operaties op te halen

Volgende gaan we snel kijken naar het gebruik van een OPTIONS verzoek en het onderzoeken van de toegestane operaties op een specifieke URI met behulp van dit soort verzoek; de API is optionsForAllow:

Set<HttpMethod> optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);HttpMethod supportedMethods = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));

Gebruik PUT om een Resource te updaten

Volgende gaan we kijken naar PUT en meer specifiek de exchange() API voor deze operatie, aangezien de template.put API vrij rechttoe rechtaan is.

7.1. Eenvoudige PUT Met exchange()

We beginnen met een eenvoudige PUT operatie tegen de API – en houd in gedachten dat de operatie geen body teruggeeft aan de client:

Foo updatedInstance = new Foo("newName");updatedInstance.setId(createResponse.getBody().getId());String resourceUrl = fooResourceUrl + '/' + createResponse.getBody().getId();HttpEntity<Foo> requestUpdate = new HttpEntity<>(updatedInstance, headers);template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);

7.2. PUT met exchange() en een Request Callback

Nu gaan we een request callback gebruiken om een PUT uit te voeren.

Laten we ervoor zorgen dat we de callback voorbereiden, waar we alle headers kunnen instellen die we nodig hebben, evenals een request body:

RequestCallback requestCallback(final Foo updatedInstance) { return clientHttpRequest -> { ObjectMapper mapper = new ObjectMapper(); mapper.writeValue(clientHttpRequest.getBody(), updatedInstance); clientHttpRequest.getHeaders().add( HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE); clientHttpRequest.getHeaders().add( HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass()); };}

Volgende, we maken de Resource met een POST verzoek:

ResponseEntity<Foo> response = restTemplate .exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);assertThat(response.getStatusCode(), is(HttpStatus.CREATED));

En dan actualiseren we de Resource:

Foo updatedInstance = new Foo("newName");updatedInstance.setId(response.getBody().getId());String resourceUrl =fooResourceUrl + '/' + response.getBody().getId();restTemplate.execute( resourceUrl, HttpMethod.PUT, requestCallback(updatedInstance), clientHttpResponse -> null);

Gebruik DELETE om een Resource te verwijderen

Om een bestaande Resource te verwijderen, maken we snel gebruik van de delete() API:

String entityUrl = fooResourceUrl + "/" + existingResource.getId();restTemplate.delete(entityUrl);

Configureer Timeout

We kunnen RestTemplate configureren om te time-outen door simpelweg ClientHttpRequestFactory te gebruiken:

RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(); clientHttpRequestFactory.setConnectTimeout(timeout); return clientHttpRequestFactory;}

En we kunnen HttpClient gebruiken voor verdere configuratie opties:

private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; RequestConfig config = RequestConfig.custom() .setConnectTimeout(timeout) .setConnectionRequestTimeout(timeout) .setSocketTimeout(timeout) .build(); CloseableHttpClient client = HttpClientBuilder .create() .setDefaultRequestConfig(config) .build(); return new HttpComponentsClientHttpRequestFactory(client);}

Conclusie

In dit artikel hebben we de belangrijkste HTTP Verbs besproken, waarbij we RestTemplate hebben gebruikt om requests te orkestreren die al deze verbs gebruiken.

Als je wilt weten hoe je authenticatie met het sjabloon kunt doen, bekijk dan ons artikel over Basic Auth met RestTemplate.

De implementatie van al deze voorbeelden en code snippets kun je vinden op GitHub.

Ga aan de slag met Spring 5 en Spring Boot 2, via de cursus Learn Spring:

>> CHECK OUT THE COURSE

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *