RestTemaplte 사용방법
1. 개요
이 튜토리얼에서는 Spring REST Client 의 한종류인 RestTemplate 을 사용하고 잘 사용할 수있는 광범위한 방법을 설명합니다 .
2. Web client
Spring Framework 5에서 WebFlux 스택과 함께 Spring은 WebClient 라는 새로운 HTTP 클라이언트를 도입했습니다 . 웹 클라이언트는 에 현대적인 대안 HTTP 클라이언트입니다 RestTemplate . 기존의 동기식 API를 제공 할뿐만 아니라 효율적인 비 차단 및 비동기 방식도 지원합니다. 이다원에서는 web clinet가 아닌 좀 더 간단하게 많이 사용되는 Rest template을 사용할것입니다.
3. REST API 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());
여기서는 응답 본문을 표준 문자열로 사용하고 있으며 Jackson (및 Jackson이 제공하는 JSON 노드 구조)을 사용하여 세부 정보를 확인합니다.
3.2. JSON 대신 자바 객체를 통해 결과값 받기
응답을 Resource 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. REST API 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. exchange 방법 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. Form Data 방식으로 API 호출
다음으로 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. REST API 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. REST API PUT 호출하여 데이터 수정
다음으로, 우리는 template.put API로 인해 PUT,보다 구체적 으로이 작업에 대한 교환 API를 살펴볼 것 입니다.
7.1. 간단한 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. REST API DELETE를 사용하여 자원 제거
기존 리소스를 제거하기 위해 delete () API를 간단하게 만듭니다 .
String entityUrl = fooResourceUrl + "/" + existingResource.getId();
restTemplate.delete(entityUrl);
9. Timeount 설정
다음과 같이 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 CRUD를 살펴 보고이 모든 것을 사용하여 요청을 사용해봤습니다. 이제 자유자재로 REST API를 사용할 수 있습니다.
이 모든 예제와 코드 구현은 GitHub 에서 찾을 수 있습니다 .
참고
'Spring' 카테고리의 다른 글
RestTemplateBuilder로 안전하게 restTemplate 생성하기 (1) | 2020.06.14 |
---|---|
RestTemplate에서 List 다루기 (0) | 2020.06.14 |
이중화된 시스템 Redis를 통한 Spring security session관리 (0) | 2020.06.13 |
Spring 에서Global Error, Exception handling하는 방법 (0) | 2020.06.12 |
모든 jackson 어노테이션 종류 파악 (1) | 2020.06.11 |