1. 개요
이 튜토리얼에서는 Spring REST 클라이언트 인 RestTemplate을 사용하고 잘 사용할 수있는 광범위한 작업을 설명합니다 .
모든 예제의 API 측에서는 여기 에서 RESTful 서비스를 실행합니다 .
2. 지원 중단 알림
Spring Framework 5부터 WebFlux 스택과 함께 Spring은 WebClient 라는 새로운 HTTP 클라이언트를 도입했습니다 .
WebClient 는 RestTemplate에 대한 최신 대체 HTTP 클라이언트 입니다. 기존의 동기식 API를 제공 할뿐만 아니라 효율적인 비 차단 및 비동기 접근 방식도 지원합니다.
즉, 새 애플리케이션을 개발하거나 이전 애플리케이션을 마이그레이션하는 경우 WebClient 를 사용하는 것이 좋습니다 . 앞으로 RestTemplate 은 향후 버전에서 더 이상 사용되지 않습니다.
3. GET을 사용하여 리소스 검색
3.1. 일반 JSON 가져 오기
getForEntity () API 를 사용하는 간단한 예제를 통해 간단하게 시작하고 GET 요청에 대해 이야기하겠습니다 .
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));
HTTP 응답에 대한 전체 액세스 권한이 있으므로 상태 코드를 확인하여 작업이 성공했는지 확인하거나 응답의 실제 본문과 함께 작업하는 것과 같은 작업을 수행 할 수 있습니다.
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());
JsonNode name = root.path("name");
assertThat(name.asText(), notNullValue());
여기서는 Response body을 표준 문자열로 사용하고 Jackson (및 Jackson이 제공하는 JSON 노드 구조)을 사용하여 세부 정보를 확인하고 있습니다.
3.2. JSON 대신 POJO 검색
응답을 리소스 DTO에 직접 매핑 할 수도 있습니다.
public class Foo implements Serializable {
private long id;
private String name;
// standard getters and setters
}
이제 템플릿에서 getForObject API를 간단히 사용할 수 있습니다 .
Foo foo = restTemplate
.getForObject(fooResourceUrl + "/1", Foo.class);
assertThat(foo.getName(), notNullValue());
assertThat(foo.getId(), is(1L));
4. HEAD를 사용하여 헤더 검색
이제보다 일반적인 방법으로 넘어 가기 전에 HEAD 사용을 간단히 살펴 보겠습니다.
우리는 사용하게 될 겁니다 ) (headForHeaders을 여기 API를 :
HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl);
assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));
5. POST를 사용하여 리소스 만들기
API에서 새 리소스를 생성하기 위해 postForLocation () , postForObject () 또는 postForEntity () API를 잘 사용할 수 있습니다 .
첫 번째는 새로 생성 된 리소스의 URI를 반환하고 두 번째는 리소스 자체를 반환합니다.
5.1. 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. postForLocation () API
마찬가지로 전체 리소스를 반환하는 대신 새로 생성 된 리소스 의 위치 만 반환하는 작업을 살펴 보겠습니다 .
HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));
URI location = restTemplate
.postForLocation(fooResourceUrl, request);
assertThat(location, notNullValue());
5.3. 교환 () API
보다 일반적인 교환 API를 사용하여 POST를 수행하는 방법을 살펴 보겠습니다 .
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. 양식 데이터 제출
다음으로 POST 메서드를 사용하여 양식을 제출하는 방법을 살펴 보겠습니다.
먼저 Content-Type 헤더를 application / x-www-form-urlencoded로 설정해야합니다.
이렇게하면 &로 구분 된 이름 / 값 쌍을 포함하는 큰 쿼리 문자열을 서버로 보낼 수 있습니다 .
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
양식 변수를 LinkedMultiValueMap 으로 래핑 할 수 있습니다 .
MultiValueMap<String, String> map= new LinkedMultiValueMap<>();
map.add("id", "1");
다음 으로 HttpEntity 인스턴스를 사용하여 요청을 작성 합니다 .
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
마지막으로 끝점에서 restTemplate.postForEntity () 를 호출하여 REST 서비스에 연결할 수 있습니다 . / foos / form
ResponseEntity<String> response = restTemplate.postForEntity(
fooResourceUrl+"/form", request , String.class);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
6. OPTIONS를 사용하여 허용 된 작업 얻기
다음으로 OPTIONS 요청을 사용하고 이러한 종류의 요청을 사용하여 특정 URI에서 허용되는 작업을 탐색하는 방법을 간략하게 살펴 보겠습니다. API는 optionsForAllow입니다 .
Set<HttpMethod> optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);
HttpMethod[] supportedMethods
= {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};
assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));
7. PUT를 사용하여 리소스 업데이트
다음으로, template.put API가 매우 간단하기 때문에 PUT와 좀 더 구체적 으로이 작업에 대한 exchange () API를 살펴 보겠습니다 .
7.1. 간단한 PUT 와 교환 ()
API에 대한 간단한 PUT 작업으로 시작하겠습니다.이 작업은 본문을 클라이언트로 다시 반환하지 않습니다.
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. exchange () 및 요청 콜백이있는 PUT
다음으로 요청 콜백을 사용하여 PUT를 발행 할 것입니다.
필요한 모든 헤더와 요청 본문을 설정할 수있는 콜백을 준비해야합니다.
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());
};
}
다음으로 POST 요청으로 리소스를 생성합니다.
ResponseEntity<Foo> response = restTemplate
.exchange(fooResourceUrl, HttpMethod.POST, request, Foo.class);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
그런 다음 리소스를 업데이트합니다.
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. DELETE를 사용하여 리소스 제거
기존 리소스를 제거하기 위해 delete () API를 빠르게 사용할 것입니다 .
String entityUrl = fooResourceUrl + "/" + existingResource.getId();
restTemplate.delete(entityUrl);
9. 시간 초과 구성
ClientHttpRequestFactory 를 사용하여 RestTemplate 을 시간 초과 하도록 구성 할 수 있습니다 .
RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
private ClientHttpRequestFactory getClientHttpRequestFactory() {
int timeout = 5000;
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory
= new HttpComponentsClientHttpRequestFactory();
clientHttpRequestFactory.setConnectTimeout(timeout);
return clientHttpRequestFactory;
}
추가 구성 옵션에 HttpClient 를 사용할 수 있습니다.
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. 결론
이 기사에서는 RestTemplate 을 사용하여 이들 모두를 사용하여 요청을 오케스트레이션 하는 주요 HTTP 동사에 대해 살펴 보았습니다 .
템플릿으로 인증을 수행하는 방법에 대해 자세히 알아 보려면 RestTemplate을 사용한 기본 인증 에 대한 기사를 확인하십시오 .
이러한 모든 예제 및 코드 스 니펫의 구현은 GitHub 에서 찾을 수 있습니다 .