HTTP기반의 통신하는 경우 스프링에서 이를 위해 RestTemplate를 제공
RestTemplate은 동기적인 Http Client 클래스
RESTfult HTTP Server와의 커뮤니케이션을 간단하게 해준다.
HTTP Connection으로 작동되며, URL과 결과를 제공하는 코드가 있다.
기본 RestTemplate은 HTTP connection을 맺기 위해 기본 JDK에 의존한다. 개발자는 setRequestFactory 속성을 통해 Apache HttpComponents, Netty, OkHttp 등 같이 다른 HTTP 라이브러리로 바꿀 수 있다.
1. RestTemplate 기본 사용법
- RestTemplate 객체 생성
- 접근 메서드 사용해서 결과 받음
RestTemplate template = new RestTemplate();
String body = template.getForObject("http://www.naver.com", String.class);
보통 필드로 많이 사용
getForObject()
메서드는 HTTP GET 방식으로 URL에 연결하여 결과를 String으로 구한다.
String 말고 HttpMessageConverter
를 사용하면 JSON이나 XML응답으로 바로 자바 객체로 변환하는것이 가능.
postForObject()
put()
delete()
headForHeaders()
등 각 HTTP 방식별 메서드 존재
RESTful 방식의 URL을 쉽게 구성할 수 있다
경로 변수를 사용할 수 있는 메서드 제공
http://localhost:8080/stores/1
경로를 통해 데이터를 가져올 경우,
String response = template.getForObject("http://localhost:8080/stores/{storesId}", String.class, "1");
마지막 매개변수가 String...
형 이므로 여러 경로 변수를 입력받을 수 있다.
String response = template.getForObject("http://../users/{userId}/stores/{storesId}", String.class, "333", "1");
가변인자 대신 Map 사용
Map<String, Object> params = new HashMap<>();
params.put("userId", "333");
params.put("storesId", "1");
String response = template.getForObject("http://../users/{userId}/stores/{storesId}", String.class, params);
1.1. 서버 에러 응답 처리
HTTP 통신하는 과정에서 문제 발생하면 RestClientException
을 발생시킨다.
상황별로 발생되는 RestClientException
의 종류
- HttpStatusCodeException : 응답 코드가 에러
- HttpClientErrorException : 응답 코드가 4xx
- HttpServerErrorException : 응답 코드가 5xx
- ResourceAccessException : 네트워크 연결에 문제가 있을 경우
- UnknownHttpStatusCodeException : 알 수 없는 응답코드일 경우
에러처리할 때 해당 코드를 익셉션 처리한다.
try {
String response = template.getForObject("http://localhost:8080/stores/{storesId}", String.class, "1");
...
} catch (HttpStatusCodeException e) {
if (e.getStatusCode() == HttpStatus.NOT_FOUND) {
...
}
}
각 익셉션 마다 제공하는 메서드
1)
HttpStatusCodeException
HttpClientErrorException
HttpServerErrorException
은 상태 코드를 구할 수 있도록 HttpStatus getStatus()
메서드 제공,
2)
UnknownHttpStatusCodeException
은 int getRawStatusCode()
제공
3)ResourceAccessException
을 제외한 나머지 익셉션에서 제공하는 메서드들
- String getStatusText() : 상태 문자값
- HttpHeaders getResponseHeaders() : 응답 헤더 리턴
- String getResponseBodyAsString() : ResponseBody 리턴
1.2. RestTemplate 주요 메서드 : GET/POST/PUT/DELETE
GET
getForObject
메서드 사용.
결과를 ResponseType으로 지정한 타입
으로 가져오거나 ResponseEntity
타입으로 가져올 수 있다.
ResponseEntity
- getStatusCode() : HttpStatus 상태 코드
- getHeaders() : HttpHeaders 리턴
- getBody()
메서드 제공
POST
postForObject
postForEntity
postForLocation
메서드를 사용할 수 있다.
request 파라미터는 Body로 전송되며 나머지는 GET과 동일.
postForObject
postForEntity
메서드는 ReponseBody를 구할 때 사용되고,postForLocation
메서드는 결과로 응답의 Location
헤더값을 구할 때 사용된다.
Location
새로 생성된 데이터에 접근할 수 있는 URL을 Location 헤더에 담아 주는 경우.
PUT
void put(String url, Object request, Object... uriVariables)
void put(String url, Object request, Map<String, ?> uriVariables)
void put(String url, Object request)
DELETE
void delete(String url, Object... uriVariables)
void delete(String url, Map<String, ?> uriVariables)
void delete(URI url)
1.3. HttpMessageConverter를 이용한 타입 변환
GET/POST는 Body를 특정 객체로 변환하여 리턴.
POST/PUT을 위한 메서드로 전달한 객체를 Body로 변환.
getForObject
, postForLocation
메서드에서
JSON ==> Object
or
Object ==> JSON
방식으로 변환해주는 역할.
기본으로
MappingJackson2HttpMessageConverter
Jaxb2RootElementHttpMessageConverter
컨버터가 사용되는데, 'RestTemplate'이 사용하는 'MessageConverter' 구현체를 변경하고 싶으면 ``setMessageConverter` 메서드를 사용한다.
1.4. exchange() 메서드로 RequestHeader 설정
RequestHeader 직접 설정할 때 사용.
template.exchange("http://www.naver.com", HttpMethod.GET, requestEntity, Void.class);
HttpMethod, HttpEntity를 이용해서 설정
- HttpMethod : 전송 방식, GET/POST/PUT/DELETE/PATCH/OPTIONS/TRACE ...
- HttpEntity : RequestHeader, RequestBody를 설정할 수 있다.
사용 예
HttpHeaders headers = new HttpHeaders();
headers.add("AUTHKEY", "myKey");
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<Void> requestEntity = new HttpEntity<Void>((Void) null, headers);
1.5. URIBuilder 이용한 URI 생성
연결할 URL을 지정하는 메서드로 사용할 수 있다. UrlComponentsBuilder
클래스와 함께 쉽게 생성할 수 있다.
UriComponentsBuilder builder = UriComponentsBuilder.newInstance();
UriComponents uriComp = builder.scheme("http")
.host("localhost")
.port(8080)
.path("/users/{userId}/stores/{storeId}")
.build();
uriComp = uriComp.expand("333", "1").encode();
Uri uri = uriComp.toUri();
// 채이닝 방식으로
URI uri = UriComponentsBuilder.newInstance()
.scheme("http")
.host("localhost")
.path("/users/{userId}/stores/{storeId}")
.build()
.toUri();
1.6. AsyncRestTemplate 이용한 비동기 처리
RestTemplate와 동일한 메서드를 지원하나 차이점은 결과를 바로 받지 않고 ListableFuture
를 타입으로 받는다. 그리고 RestTemplate은 동기 처리 방식
AsyncRestTemplate template = new AsyncRestTemplate();
template.getForEntity("http://www.naver.com", String.class)
.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
public void onSuccess(ResponseEntity<String> result) {
...
}
public void onFailure(Throwable ex) {
...
}
});
ListableFuture
타입 리턴하는데 결과 타입은 ResponseEntity
를 사용한다.
@Override
public <T> ListenableFuture<ResponseEntity<T>> getForEntity(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException {
...
'Programming > Spring Framework' 카테고리의 다른 글
Spring 빈/컨테이너 생명주기 (Lifecycle) (0) | 2020.05.24 |
---|---|
Spring AOP Proxy에 관하여 (0) | 2020.05.24 |
Spring 트랜잭션에 대해 알아보자 (0) | 2019.11.25 |
Spring MVC (0) | 2019.11.22 |
Spring AOP (Aspect Oriented Programming) (0) | 2018.10.30 |
댓글