= RestTemplate 이란?
Spring에 내장되어있는 클래스중 하나로써, Rest방식의 API를 호출할 수 있다.
- Spring 3.0부터 지원한다. REST API 호출 이후, 응답을 받을 때까지 기다리는 동기 방식으로 http 통신에 유용하게 쓸 수 있다. (비 차단 및 비동기 방식도 지원)
- JSON, XML 등의 데이터를 쉽게 응답 받을 수 있다.
= RestTemplate의 동작구조
(1) Application이 RestTemplate를 생성하고 URL, HTTP메소드 등의 헤더를 담아서 Request한다.
(2) RestTemplate는 HttpMessageConverter클래스를 사용하여 RequestEntity를 요청 메시지로 변환한다.
(3) RestTemplate는 ClientHttpRequestFactory로부터 ClientHttpRequest정보를 받아와 Request한다.
(4) ClientHttpRequest는 요청메시지를 만들어 Http프로토콜을 통해 API 서버와 통신한다.
(5) RestTemplate는 ResponseErrorHandler인터페이스로 오류가 있는지 확인하고 처리 로직을 실행
(6) ResponseErrorHandler는 오류가 있으면 ClientHttpResponse에서 응답 데이터를 받아와서 처리한다
(7) RestTemplate는 HttpMessageConverter클래스를 이용해서 응답 데이터를 JAVA Object로 변환한다
(8) Application으로 반환한다 (JSON, XML, String ..)
= DI(Dependency Injection)
"기본적으로 내장되어있으므로, 별도로 선언할 필요는 없다."
= RestTemplate 설정(Config)
package com.wmp.ep.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.time.Duration;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder
.requestFactory(() -> new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory()))
.setConnectTimeout(Duration.ofMillis(30000)) // 30초
.setReadTimeout(Duration.ofMillis(30000))
.additionalMessageConverters(new StringHttpMessageConverter(Charset.forName("UTF-8")))
.build();
}
}
= RestTemplate 사용 메소드
메소드 | HTTP Method | 설명 |
getForObject | GET | 주어진 URL 주소로 HTTP GET Method로 지정한 객체로 결과를 반환받음 |
getForEntity | GET | 주어진 URL 주소로 HTTP GET Method로 결과는 ResponseEntity<T>로 반환받음 |
postForLocation | POST | POST 요청을 보내고 결과로 헤더에 저장된 URI를 결과로 반환받음 |
postForObject | POST | POST 요청을 보내고 지정한 객체로 결과를 반환받음 |
postForEntity | POST | POST 요청을 보내고 결과로 ResponseEntity<T> 객체로 반환받음 |
delete | DELETE | 주어진 URL 주소로 HTTP DELETE Method를 실행 |
headForHeaders | HEADER | 헤더의 모든 정보를 얻을 수 있으면 HTTP HEAD Method를 사용 |
put | PUT | 주어진 URL 주소로 HTTP PUT Method를 실행 |
patchForObject | PATCH | 주어진 URL 주소로 HTTP PATCH Method를 실행 |
optionsForAllow | OPTIONS | 주어진 URL 주소에서 지원하는 HTTP Method를 조회 |
exchange | ANY | HTTP 헤더를 새로 만들 수 있고 어떤 HTTP Method도 사용가능 |
execute | ANY | Request/Response 콜백을 수정할 수 있음 |
= RestTemplate 메소드 예제
- getForObject
-> responseType으로 응답받을 Class Type 지정이 가능하다.
-> uriVariables는 pathVariable(param value)을 입력
String url = "http://localhost:8080/getRestTemplate";
ResponseData data = restTemplate.gerForObject(url, ResponseData.class);
// pathVariable(param value)이 입력되는 경우
// pathVariable 단일 개수
ResponseData data = getForObject("http://localhost:8080/getRestTemplate/{number1}", ResponseData.class, "10");
// pathVariable 복수 개수
Map<String, String> params = new HashMap<>();
params.put("number1", 10);
params.put("number2", 20);
ResponseData data = getForObject("http://localhost:8080/getRestTemplate/{number1}/nums/{number2}", ResponseData.class, params);
- getForEntity
-> responseType에 지정한 Generic Type을 ResponseEntity로 받을 수 있다.
-> 이외에는 getForObject와 동일
String url = "http://localhost:8080/getRestTemplate";
ResponseEntity<String> responseEntity = restTemplate.getForEntity(url + "/{id}", String.class, 25);
System.out.println(responseEntity.getStatusCode());
System.out.println(responseEntity.getBody());
// 위와같이 params를 넘겨줄 수 있다.
// Map으로 담아서 MultiValue로 전송도 가능
- postForObject
-> request에 requestBody와 헤더정보를 설정하여 보낼 수 있다.
-> responseType으로 응답받을 Class Type 지정이 가능하다.
-> uriVariables는 pathVariable(param value)을 입력
String url = "http://localhost:8080/getRestTemplate";
ResponseData newResponseData = ResponseData.builder().code(200),message("정상").build();
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json");
ResponseData data = restTemplate.postForObject(url, new HttpEntity<>(newResponseData, headers), ResponseData.class);
// 각각 Parameter에는 URL, Entity(body, header), Response Class
// body영역은, DTO 등 Class가 위치할 수 있으나, Map 으로도 전송이 가능하다.
- postForEntity
getForEntity와 마찬가지로 responseType에 지정한 Generic Type을 ResponseEntity로 받을 수 있다.
- put
-> PUT Method를 호출한다
-> request에 requestBody와 헤더정보를 설정하여 보낼 수 있다.
-> uriVariables는 pathVariable(param value)을 입력
-> 리턴타입이 void라서, 응답값을 받을 수 없다.
- delete
-> DELETE Method를 호출한다
-> uriVariables는 pathVariable(param value)을 입력
-> 리턴타입이 void라서, 응답값을 받을 수 없다.
Map<String, String> params = new HashMap<>();
params.put("name", "xggames");
restTemplate.delete(BASE_URL + "/employee/{name}", params);
- exchange
-> 반드시 responseType에 지정한 Generic Type을 ResponseEntity로 받아야 한다.
-> method에 원하는 Method Type을 지정할 수 있다.
-> uriVariables는 pathVariable(param value)을 입력
-> 위에서 언급한 put, delete메소드에서 리턴타입이 void였던 부분을 해결해줄 수 있다.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>("Hello World!", headers);
ResponseEntity<Employee> empEntity = restTemplate.exchange(BASE_URL + "/exchange/employee/{id}", HttpMethod.GET, request, Employee.class, 50);
= 기타
RestTemplate이외에도 더 많은 HttpClient들이 있다. 참고하자
https://www.baeldung.com/spring-5-webclient
https://bravenamme.github.io/2021/01/07/web_client/ - WebClient
https://techblog.woowahan.com/2630/ - feignClient
= 참고자료
- https://www.wrapuppro.com/programing/view/iLVLziCsP4icNB6
- https://advenoh.tistory.com/46
- https://juntcom.tistory.com/141
'SpringFramework > Spring' 카테고리의 다른 글
Spring - Log4j2 (0) | 2021.10.13 |
---|---|
Spring - Swagger (0) | 2021.10.08 |
Spring - ResponseEntity (0) | 2021.10.08 |
Spring - Mybatis FrameWork 개념 및 설정 (0) | 2021.09.30 |
Spring Package 구조와 역할 (0) | 2021.09.30 |