Panduan untuk RestTemplate

1. Gambaran keseluruhan

Dalam tutorial ini, kita akan menggambarkan pelbagai operasi di mana Spring REST Client - RestTemplate - boleh digunakan, dan digunakan dengan baik.

Untuk bahagian API dari semua contoh, kami akan menjalankan perkhidmatan RESTful dari sini.

2. Notis Penurunan

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

WebClient adalah klien HTTP alternatif moden untuk RestTemplate . Bukan hanya menyediakan API segerak tradisional, tetapi juga menyokong pendekatan tanpa sekatan dan asinkron yang cekap.

Walaupun begitu, jika kita mengembangkan aplikasi baru atau memindahkan aplikasi lama, ada baiknya menggunakan WebClient . Melangkah ke hadapan, RestTemplate akan ditamatkan dalam versi akan datang.

3. Gunakan GET untuk Mendapatkan Sumber

3.1. Dapatkan JSON Plain

Mari kita mulakan dan bercakap mengenai 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 bahawa kami mempunyai akses penuh ke respons HTTP , jadi kami dapat melakukan perkara seperti memeriksa kod status untuk memastikan operasi itu berjaya atau bekerja dengan badan respons yang sebenarnya:

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

Kami bekerjasama dengan badan tindak balas sebagai String standard di sini dan menggunakan Jackson (dan struktur simpul JSON yang disediakan oleh Jackson) untuk mengesahkan beberapa butiran.

3.2. Mengambil POJO Bukannya JSON

Kami juga dapat memetakan respons langsung ke DTO Sumber:

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

Sekarang kita boleh menggunakan API getForObject dalam templat:

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

4. Gunakan HEAD untuk Mendapatkan Header

Mari kita lihat cepat menggunakan HEAD sebelum beralih ke kaedah yang lebih biasa.

Kami akan menggunakan API headForHeaders () di sini:

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

5. Gunakan POST untuk Membuat Sumber

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

Yang pertama mengembalikan URI Sumber yang baru dibuat, sementara yang kedua mengembalikan Sumber 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

Begitu juga, mari kita lihat operasi bahawa bukannya mengembalikan Sumber penuh, hanya mengembalikan Lokasi Sumber yang baru dibuat:

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

5.3. The pertukaran () API

Mari lihat bagaimana melakukan POST dengan API pertukaran yang lebih generik :

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. Hantar Data Borang

Seterusnya, mari kita lihat cara menghantar borang menggunakan kaedah POST.

Pertama, kita perlu menetapkan tajuk Jenis Kandungan ke aplikasi / x-www-form-urlencoded.

Ini memastikan bahawa rentetan pertanyaan besar dapat dikirim ke pelayan, yang mengandungi pasangan nama / nilai dipisahkan oleh & :

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

Kita boleh membungkus pemboleh ubah bentuk ke LinkedMultiValueMap :

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

Seterusnya, kami membina Permintaan menggunakan contoh HttpEntity :

HttpEntity
    
      request = new HttpEntity(map, headers);
    

Akhirnya, kita dapat menyambung ke perkhidmatan 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 PILIHAN untuk Mendapatkan Operasi yang Dibolehkan

Seterusnya, kita akan melihat dengan cepat menggunakan permintaan PILIHAN dan meneroka operasi yang dibenarkan pada URI tertentu menggunakan permintaan seperti 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 Mengemas kini Sumber

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 membuang Sumber yang ada, kami akan menggunakan API delete () dengan cepat :

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

9. Konfigurasikan Timeout

Kita boleh mengkonfigurasi RestTemplate untuk habis masa dengan hanya menggunakan ClientHttpRequestFactory :

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

Dan kami boleh menggunakan HttpClient untuk pilihan 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. Kesimpulannya

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

Sekiranya anda ingin mengetahui cara melakukan pengesahan dengan templat, lihat artikel kami mengenai Basic Auth with RestTemplate.

Pelaksanaan semua contoh dan coretan kod ini boleh didapati di GitHub.