Hướng dẫn RestTemplate

1. Khái quát chung

Trong hướng dẫn này, chúng tôi sẽ minh họa một loạt các hoạt động mà Spring REST Client - RestTemplate - có thể được sử dụng và sử dụng tốt.

Đối với phía API của tất cả các ví dụ, chúng tôi sẽ chạy dịch vụ RESTful từ đây.

2. Thông báo Ngừng sử dụng

Kể từ Spring Framework 5, cùng với ngăn xếp WebFlux, Spring đã giới thiệu một ứng dụng khách HTTP mới có tên là WebClient .

WebClient là một ứng dụng HTTP hiện đại, thay thế cho RestTemplate . Nó không chỉ cung cấp API đồng bộ truyền thống mà còn hỗ trợ phương pháp tiếp cận không chặn và không đồng bộ hiệu quả.

Điều đó nói rằng, nếu chúng tôi đang phát triển các ứng dụng mới hoặc di chuyển một ứng dụng cũ, thì bạn nên sử dụng WebClient . Trong tương lai, RestTemplate sẽ không được dùng nữa trong các phiên bản sau.

3. Sử dụng GET để lấy tài nguyên

3.1. Nhận JSON thuần túy

Hãy bắt đầu đơn giản và nói về các yêu cầu GET, với một ví dụ nhanh bằng cách sử dụng API getForEntity () :

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

Lưu ý rằng chúng tôi có toàn quyền truy cập vào phản hồi HTTP , vì vậy chúng tôi có thể thực hiện những việc như kiểm tra mã trạng thái để đảm bảo hoạt động thành công hoặc hoạt động với nội dung thực tế của phản hồi:

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

Chúng tôi đang làm việc với phần thân phản hồi như một Chuỗi tiêu chuẩn ở đây và sử dụng Jackson (và cấu trúc nút JSON mà Jackson cung cấp) để xác minh một số chi tiết.

3.2. Truy xuất POJO thay vì JSON

Chúng tôi cũng có thể ánh xạ phản hồi trực tiếp tới DTO tài nguyên:

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

Bây giờ chúng ta có thể chỉ cần sử dụng API getForObject trong mẫu:

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

4. Sử dụng HEAD để lấy tiêu đề

Bây giờ chúng ta hãy xem nhanh cách sử dụng HEAD trước khi chuyển sang các phương pháp phổ biến hơn.

Chúng tôi sẽ sử dụng API headForHeaders () ở đây:

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

5. Sử dụng POST để tạo tài nguyên

Để tạo một Tài nguyên mới trong API, chúng ta có thể sử dụng tốt các API postForLocation () , postForObject () hoặc postForEntity () .

Đầu tiên trả về URI của Tài nguyên mới được tạo, trong khi thứ hai trả về chính Tài nguyên đó.

5.1. Các 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. Các postForLocation () API

Tương tự, hãy xem thao tác thay vì trả về Tài nguyên đầy đủ, chỉ trả về Vị trí của Tài nguyên mới được tạo đó:

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

5.3. Các trao đổi () API

Hãy cùng xem cách thực hiện ĐĂNG với API trao đổi chung hơn :

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. Gửi dữ liệu biểu mẫu

Tiếp theo, hãy xem cách gửi biểu mẫu bằng phương thức POST.

Đầu tiên, chúng ta cần đặt tiêu đề Content-Type thành application / x-www-form-urlencoded.

Điều này đảm bảo rằng một chuỗi truy vấn lớn có thể được gửi đến máy chủ, chứa các cặp tên / giá trị được phân tách bằng & :

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

We can wrap the form variables into a LinkedMultiValueMap:

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

Next, we build the Request using an HttpEntity instance:

HttpEntity
    
      request = new HttpEntity(map, headers);
    

Finally, we can connect to the REST service by calling restTemplate.postForEntity() on the Endpoint: /foos/form

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

6. Use OPTIONS to Get Allowed Operations

Next, we're going to have a quick look at using an OPTIONS request and exploring the allowed operations on a specific URI using this kind of request; the API is optionsForAllow:

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

7. Use PUT to Update a Resource

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

Để xóa Tài nguyên hiện có, chúng tôi sẽ sử dụng nhanh API delete () :

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

9. Định cấu hình thời gian chờ

Chúng ta có thể cấu hình RestTemplate để hết thời gian bằng cách sử dụng ClientHttpRequestFactory :

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

Và chúng ta có thể sử dụng HttpClient cho các tùy chọn cấu hình khác:

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. Kết luận

Trong bài viết này, chúng tôi đã xem xét các Động từ HTTP chính, sử dụng RestTemplate để sắp xếp các yêu cầu bằng cách sử dụng tất cả những thứ này.

Nếu bạn muốn tìm hiểu cách thực hiện xác thực với mẫu, hãy xem bài viết của chúng tôi về Xác thực cơ bản với RestTemplate.

Bạn có thể tìm thấy việc triển khai tất cả các ví dụ và đoạn mã này trên GitHub.