RestTemplate 정리 - Kim-Taesu/study GitHub Wiki
- 좀 더 아래 글에 상세 내용이 정리 되어 있다.
- 결론적으로는 모두 메서드 내부에서
execute
를 호출하기 때문에 성능적으로 큰 차이가 없다. - 사용 방법에 따라 갈린다.
- https://stackoverflow.com/a/52364898
나는 HTTP method에서 사용되는 request를 커스텀하게 설정하고, 요청 결과인 response도 커스텀하게 설정하고 싶다!
-
execute
를 사용하면 된다. -
RequestCallback
인터페이스의doWithRequest
메서드를 구현하여 원하는 방식으로 request를 설정하면 된다. -
ResponseExtractor
인터페이스의extractData
메서드를 구현하여 원하는 방식으로 response의 데이터를 추출하면 된다.
나는 request 응답을 ResponseEntity 형태로 받고 싶다!
-
exchange
,XXXForEntity
를 사용하면 된다. -
XXXForEntity
는 메소드 명에 따라 HTTP method가 정해져있다. - header, body는
Object request
파라미터 부분에 설정하면 된다. -
exchange
는 request header, body를HttpEntity<?>
를 사용하여 설정한다. -
RequestEntity<?>
를 사용하여 url, HTTP method, header, body 까지 설정 가능하다. - response를 읽을 때 확실하게 정해진 Type이 있다면
exchange
가 편할것 같다. -
execute
는 Callback 메서드를 생성해야하지만exchange
는 타입만 명시하면 되기 때문이다. - 사용 환경에 따라서 개발자가 편한대로 사용하면 될 것 같다.
나는 Request의 결과를 특정 type 형태로 받고 싶다!
-
XXXForObject
를 사용하면 된다.
headers는 아래 코드로 생성할 수 있다
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
HttpEntity<String> httpEntity = new HttpEntity<>(headers);
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(downloadUrl, HttpMethod.GET, httpEntity, byte[].class);
body는 아래 코드로 생성할 수 있다
String body = "Request Body";
HttpEntity<String> httpEntity = new HttpEntity<>(body);
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(downloadUrl, HttpMethod.GET, httpEntity, byte[].class);
headers + body는 아래 코드로 생성할 수 있다
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.MULTIPART_FORM_DATA);
String body = "Request Body";
HttpEntity<String> httpEntity = new HttpEntity<>(body, headers);
ResponseEntity<byte[]> responseEntity = restTemplate.exchange(downloadUrl, HttpMethod.GET, httpEntity, byte[].class);
- 동기 방식으로 HTTP 요청을 할 수 있는 Java 기반 REST client
- 간단한 template 메서드 API를 사용하여 HTTP 요청을 할 수 있다.
- template 메서드는 JDK HttpURLConnection, Apache HttpComponents와 같은 기본 HTTP 클라이언트 라이브러리를 사용한다.
- RestTemplate은 callback 메서드와 HttpMessageConverter를 커스터마이징 하여 사용할 수 있다. (보충 필요)
- HttpMessageConverter : object를 HTTP request body로 마샬링할 수 있고, Response를 다시 object로 언마샬링 할 수 있다.
- RestTemplate은 RESTful HTTP 요청을 만들기 위한 abstract method를 제공한다.
- 내부적으로 Resttempalte은 Android HTTP client library를 활용한다.
- 표준 JS2SE 기능은
SimpleClientHttpRequestFactory
에 의해 제공 - HttpClient는
HttpComponentsClientHttpRequestFacotry
에 의해 제공
- HTTP 요청을 처리하는 도중 에러가 발생하면
RestClientException
발생-
ResponseErrorHandler
를 구현하여 error를 핸들링할 수 있다.
-
- RestTempalte을
new RestTemplate()
으로 생성 시, message converter는 기본HttpMessageConverters
로 초기화 한다. -
setXXX
메서드로 Error handling, message converter를 커스텀하게 설정할 수 있다.
- RestTemplate 메서드의 네이밍 규칙
- 첫 번째 부분 : 호출되는 HTTP 메서드
- 두 번째 부분 : 반환되는 객체
-
getForObject()
: GET을 수행하고, HTTP Response를 명시한 Object 유형으로 변환 -
postForLocation()
: POST를 수행하고, 새로 생성된 객체를 찾을 수 있는 Response HTTP Location 헤더를 반환
대부분의 템플릿 메서드는 내부적으로 execute()
메서드를 호출한다.
-
주어진 URI Template으로 HTTP method를 실행한다.
-
RequestCallback으로 request를 생성하고
-
ResponseExtrator로 response를 읽는다.
@Nullable <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException; @Nullable <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Map<String, ?> uriVariables) throws RestClientException; @Nullable <T> T execute(URI url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor) throws RestClientException;
ClientHttpRequest
- client-side HTTP request
-
ClientHttpRequestFactory
에 의해 생성된다. - execute로 Http 요청을 진행하고, request에 대한 응답으로
ClientHttpResponse
를 받는다.
RequestCallback
-
ClientHttpRequest
에 대한 callback interface- request header, body 값을 설정할 수 있다.
- ClientHttpRequest를 사용하고
RestTemplate.execute
메서드에 의해 호출된다. - request를 close 하는 것과 request error handling은 RestTemplate이 관리한다.
ResponseExtrator
-
ClientHttpRequest
요청 결과로 받은ClientHttpResponse
에서 데이터를 추출하는 작업을 수행.
uriVariables
-
uriTemplate의 queryString에 해당하는 값을 명시
String uriTemplate = "http://localhost:8080?value={value}"; Map<String, String> uriParamMap = new HashMap<String, String>(); uriParamMap.put("value", "1"); restTemplate.execute(uriTemplate, HttpMethod.GET, requestCallback, responseExtractor, uriParamMap);
- 전달받은 URI template과 HTTP method로 http request 요청을 수행한다.
-
HttpEntity<?> requestEntity
파라미터로 request를 작성한다. -
Class<T> responseType
파라미터로 request에 대한 reponse를ReponseEntity<T>
으로 반환한다. -
ParameterizedTypeReference<T> responseType
파라미터로 response의 type을 다양하게 설정할 수 있다.
파라미터로 봤을 때는 execute
와 달라보이지만 사실 내부 로직은 동일하다.
- 결국
exeute()
메서드를 호출한다.@Override public <T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException { RequestCallback requestCallback = httpEntityCallback(requestEntity, responseType); ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return nonNull(execute(url, method, requestCallback, responseExtractor, uriVariables)); }
requestEntity 파라미터
-
requestEntity
를 전달할 때 다양한 방법이 있다.-
http header만 있는 경우
```java HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); HttpEntity<String> httpEntity = new HttpEntity<>(headers); ResponseEntity<byte[]> responseEntity = restTemplate.exchange(downloadUrl, HttpMethod.GET, httpEntity, byte[].class); ```
-
http body만 있는 경우
```java String body = "request body"; ResponseEntity<byte[]> responseEntity = restTemplate.exchange(downloadUrl, HttpMethod.GET, body, byte[].class); ```
-
http header + body 있는 경우
```java HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.MULTIPART_FORM_DATA); String body = "request body"; HttpEntity<String> httpEntity = new HttpEntity<>(body, headers); ResponseEntity<byte[]> responseEntity = restTemplate.exchange(downloadUrl, HttpMethod.GET, httpEntity, byte[].class); ```
-
-
전달받은
requestEntity
,responseType
으로RequestCallback
을 생성한다.- 이때 생성되는
RequestCallback
은HttpEntityRequestCallback
이다.
- 이때 생성되는
-
HttpEntityRequestCallback
을 생성할 때 request의 headers, body가 설정되고 responseType이 설정된다.public HttpEntityRequestCallback(@Nullable Object requestBody, @Nullable Type responseType) { super(responseType); if (requestBody instanceof HttpEntity) { this.requestEntity = (HttpEntity<?>) requestBody; } else if (requestBody != null) { this.requestEntity = new HttpEntity<>(requestBody); } else { this.requestEntity = HttpEntity.EMPTY; } }
-
super(responseType)
로 response를 읽을 때 어떤 타입으로 읽을지 설정한다.- 이후
RequsetCallback
인터페이스doWithRequest
메서드에서 response를 등록된messageConverters
사용하여responseType
으로 읽을 수 있는지 판단한다.
- 이후
-
-
exchange
메서드와 동일하다 -
httpEntityCallback
메서드로requestCallback
을 생성하고 -
responseEntityExtractor
메서드로ResponseExtractor<ResponseEntity<T>>
를 만들어 response의 데이터를 추출한다.ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType); return nonNull(execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables));
-
exchange
메서드와거의
동일하다 -
httpEntityCallback
메서드로requestCallback
을 생성하고 -
HttpMessageConverterExtractor
를 생성하여 response에서 데이터를 주어진 Type으로 추출한다.HttpMessageConverterExtractor<T> responseExtractor = new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger); return execute(url, HttpMethod.POST, requestCallback, responseExtractor, uriVariables);