Panduan untuk RestTemplate

1. Ikhtisar

Dalam tutorial ini, kami akan mengilustrasikan berbagai operasi di mana Spring REST Client - RestTemplate - dapat digunakan, dan digunakan dengan baik.

Untuk sisi API dari semua contoh, kami akan menjalankan layanan RESTful dari sini.

2. Pemberitahuan Penghentian

Pada Spring Framework 5, di samping tumpukan WebFlux, Spring memperkenalkan klien HTTP baru yang disebut WebClient .

WebClient adalah klien HTTP alternatif modern untuk RestTemplate . Tidak hanya menyediakan API sinkron tradisional, tetapi juga mendukung pendekatan non-pemblokiran dan asinkron yang efisien.

Karena itu, jika kita sedang mengembangkan aplikasi baru atau memigrasi yang lama, ada baiknya menggunakan WebClient . Ke depannya, RestTemplate tidak akan digunakan lagi di versi mendatang.

3. Gunakan GET untuk Mengambil Sumber Daya

3.1. Dapatkan JSON Biasa

Mari kita mulai dengan sederhana dan berbicara tentang permintaan GET, dengan contoh cepat menggunakan 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));

Perhatikan bahwa kita memiliki akses penuh ke respons HTTP , jadi kita bisa melakukan hal-hal seperti memeriksa kode status untuk memastikan operasi berhasil atau bekerja dengan isi respons yang sebenarnya:

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

Kami bekerja dengan badan respons sebagai String standar di sini dan menggunakan Jackson (dan struktur node JSON yang disediakan Jackson) untuk memverifikasi beberapa detail.

3.2. Mengambil POJO Bukan JSON

Kami juga dapat memetakan respons langsung ke Resource DTO:

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

Sekarang kita cukup menggunakan getForObject API di template:

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

4. Gunakan HEAD untuk Mengambil Header

Sekarang mari kita lihat sekilas cara menggunakan HEAD sebelum beralih ke metode yang lebih umum.

Kami akan menggunakan headForHeaders () API di sini:

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

5. Gunakan POST untuk Membuat Sumber Daya

Untuk membuat Resource baru di API, kita dapat memanfaatkan API postForLocation () , postForObject (), atau postForEntity () .

Yang pertama mengembalikan URI dari Resource yang baru dibuat, sedangkan yang kedua mengembalikan Resource itu sendiri.

5.1. The 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. The postForLocation () API

Demikian pula, mari kita lihat operasi yang alih-alih mengembalikan Sumber Daya penuh, hanya mengembalikan Lokasi Sumber Daya yang baru dibuat itu:

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

5.3. The exchange () API

Mari kita lihat bagaimana melakukan POST dengan API pertukaran yang lebih umum :

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. Kirimkan Data Formulir

Selanjutnya, mari kita lihat cara mengirimkan formulir menggunakan metode POST.

Pertama, kita perlu mengatur header Content-Type ke application / x-www-form-urlencoded.

Ini memastikan bahwa string kueri besar dapat dikirim ke server, berisi pasangan nama / nilai yang dipisahkan oleh & :

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

Kita bisa membungkus variabel formulir menjadi LinkedMultiValueMap :

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

Selanjutnya, kami membuat Permintaan menggunakan contoh HttpEntity :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

Akhirnya, kita bisa terhubung ke layanan REST dengan memanggil restTemplate.postForEntity () di Endpoint: / foos / form

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

6. Gunakan OPTIONS untuk Mendapatkan Operasi yang Diizinkan

Selanjutnya, kita akan melihat sekilas penggunaan permintaan OPTIONS dan menjelajahi operasi yang diizinkan pada URI tertentu menggunakan permintaan semacam ini; API adalah optionsForAllow :

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

7. Gunakan PUT untuk Memperbarui Sumber Daya

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

Untuk menghapus Sumber Daya yang ada, kita akan menggunakan API delete () dengan cepat :

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

9. Konfigurasi Timeout

Kita dapat mengkonfigurasi RestTemplate ke waktu habis hanya dengan menggunakan ClientHttpRequestFactory :

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

Dan kita dapat menggunakan HttpClient untuk opsi konfigurasi lebih lanjut:

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. Kesimpulan

Dalam artikel ini, kami membahas Kata Kerja HTTP utama, menggunakan RestTemplate untuk mengatur permintaan menggunakan semua ini.

Jika Anda ingin mengetahui cara melakukan otentikasi dengan template, lihat artikel kami di Basic Auth dengan RestTemplate.

Penerapan semua contoh dan cuplikan kode ini dapat ditemukan di GitHub.