Guiden till RestTemplate

1. Översikt

I denna handledning ska vi illustrera det breda utbudet av operationer där Spring REST Client - RestTemplate - kan användas och användas bra.

För API-sidan av alla exempel kör vi tjänsten RESTful härifrån.

2. Meddelande om avskrivning

Från och med Spring Framework 5, tillsammans med WebFlux-stacken, introducerade Spring en ny HTTP-klient som heter WebClient .

WebClient är en modern, alternativ HTTP-klient till RestTemplate . Det ger inte bara ett traditionellt synkron API, men det stöder också en effektiv icke-blockerande och asynkron strategi.

Med det sagt, om vi utvecklar nya applikationer eller migrerar en gammal, är det en bra idé att använda WebClient . Framåt kommer RestTemplate att upphöra i framtida versioner.

3. Använd GET för att hämta resurser

3.1. Få Plain JSON

Låt oss börja enkelt och prata om GET-förfrågningar, med ett snabbt exempel med hjälp av getForEntity () API :

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

Observera att vi har full åtkomst till HTTP-svaret , så att vi kan göra saker som att kontrollera statuskoden för att se till att operationen lyckades eller arbeta med svarets faktiska del:

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

Vi arbetar med svarsorganet som en standardsträng här och använder Jackson (och den JSON-nodstruktur som Jackson tillhandahåller) för att verifiera några detaljer.

3.2. Hämtar POJO istället för JSON

Vi kan också mappa svaret direkt till en Resource DTO:

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

Nu kan vi helt enkelt använda getForObject API i mallen:

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

4. Använd HEAD för att hämta rubriker

Låt oss nu titta snabbt på att använda HEAD innan vi går vidare till de vanligaste metoderna.

Vi kommer att använda headForHeaders () API här:

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

5. Använd POST för att skapa en resurs

För att skapa en ny resurs i API: n kan vi utnyttja API: erna postForLocation () , postForObject () eller postForEntity () .

Den första returnerar URI för den nyskapade resursen, medan den andra returnerar resursen själv.

5.1. Den postForObject () API

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

5.2. Den postForLocation () API

På samma sätt, låt oss ta en titt på operationen som istället för att returnera hela resursen, bara returnerar platsen för den nyskapade resursen:

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

5.3. Det utbyte () API

Låt oss ta en titt på hur man gör en POST med det mer generiska utbytes- API: et:

RestTemplate restTemplate = new RestTemplate(); HttpEntity request = new HttpEntity(new Foo("bar")); ResponseEntity 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. Skicka formulärdata

Låt oss sedan titta på hur man skickar in ett formulär med POST-metoden.

Först måste vi ställa in rubriken Content-Type till application / x-www-form-urlencoded.

Detta säkerställer att en stor frågesträng kan skickas till servern, som innehåller namn / värde-par åtskilda av & :

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

Vi kan slå in formulärvariablerna i en LinkedMultiValueMap :

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

Därefter bygger vi begäran med en HttpEntity- instans :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

Slutligen kan vi ansluta till REST-tjänsten genom att ringa restTemplate.postForEntity () på slutpunkten: / foos / form

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

6. Använd ALTERNATIV för att få tillåtna operationer

Därefter kommer vi att ta en snabb titt på att använda en OPTIONS-begäran och utforska de tillåtna operationerna på en specifik URI med hjälp av denna typ av begäran; API: et är optionsForAllow :

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

7. Använd PUT för att uppdatera en resurs

Next, we'll start looking at PUT and more specifically the exchange() API for this operation, since the template.put API is pretty straightforward.

7.1. Simple PUT With exchange()

We'll start with a simple PUT operation against the API — and keep in mind that the operation isn't returning a body back to the client:

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

7.2. PUT With exchange() and a Request Callback

Next, we're going to be using a request callback to issue a PUT.

Let's make sure we prepare the callback, where we can set all the headers we need as well as a 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()); }; }

Next, we create the Resource with a POST request:

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

And then we update the 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);

8. Use DELETE to Remove a Resource

För att ta bort en befintlig resurs använder vi snabbt delete- API: et:

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

9. Konfigurera timeout

Vi kan konfigurera RestTemplate till timeout genom att helt enkelt använda ClientHttpRequestFactory :

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

Och vi kan använda HttpClient för ytterligare konfigurationsalternativ:

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

10. Slutsats

I den här artikeln gick vi över de viktigaste HTTP-verberna med RestTemplate för att orkestrera förfrågningar med alla dessa.

Om du vill gräva in hur du gör autentisering med mallen, kolla in vår artikel om Basic Auth med RestTemplate.

Implementeringen av alla dessa exempel och kodavsnitt finns på GitHub.