http 요청을 사용하여 외부의 자원을 호출하여 사용할 때가 많이 있습니다. 이와 관련된 기본 예제를 살펴 보겠습니다. Spring boot 프로젝트라고 가정하겠습니다.
라이브러리 추가
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
기본 설정 추가
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.
HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
HttpComponentsClientHttpRequestFactory requestFactory =
new HttpComponentsClientHttpRequestFactory();
requestFactory.setConnectTimeout(1000); // 소켓 연결 타임아웃
requestFactory.setReadTimeout(3000); // 소켓 연결 이후 응답 타임아웃
RestTemplate restTemplate = new RestTemplate(requestFactory);
return restTemplate;
}
}
클래스 객체 응답 받기
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@RestController
@Slf4j
public class BookController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/books/{id}")
public Book getBooks(@PathVariable Integer id) {
return Book.builder()
.id(id)
.title("title" + id)
.createdDate(LocalDateTime.now()).build();
}
@GetMapping("/restBooks/{id}")
public Book getRestBooks(@PathVariable Integer id) {
Book result = restTemplate.
getForObject("http://localhost:8080/books/{id}",
Book.class, id);
log.debug("result === {}", result);
return result;
}
}
(예제 코드라 한눈에 편하게 볼 수 있도록 동일한 파일에 작성하였습니다.)
클래스 타입은 getForObject를 통해서 바로 원하는 클래스로 형변환이 가능합니다. 그리고 호출 주소 부분에 {id} 와 치환할 대상을 선언하고, 마지막 가변 파라미터를 사용하면 String.format 같은 것을 사용하지 않아도 됩니다.
Map 타입 응답 받기
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@RestController
@Slf4j
public class BookController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/bookMap")
public Map<Integer, Book> getBookMap(@RequestParam int size) {
if (size < 0) {
size = 1;
}
Map<Integer, Book> bookMap = new HashMap<>();
for (int i =1; i <= size; i++) {
bookMap.put(i, Book.builder()
.id(i)
.title("title" + i)
.createdDate(LocalDateTime.now()).build());
}
return bookMap;
}
@GetMapping("/restBookMap")
public Map<Integer, Book> getRestBookMap(@RequestParam int size) {
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity httpEntity = new HttpEntity(httpHeaders);
ResponseEntity<Map<Integer, Book>> result = restTemplate.
exchange("http://localhost:8080/bookMap?size={size}",
HttpMethod.GET, httpEntity,
new ParameterizedTypeReference<Map<Integer, Book>>() {
}, size);
log.debug("result === {}", result);
return result.getBody();
}
}
호출 header를 설정하고 싶거나 Map 타입 형태로 데이터를 받고 싶은 경우 exchange 를 사용하면 됩니다.
간혹 응답이 xml이나 다른 형태로 오는경우 Accept Header를 설정해야 JSON 응답으로 처리가 됩니다.
댓글
댓글 쓰기