1) RestTemplate
: 서버에서 다른 서버로 간편하게 요청할 수 있도록 스프링에서 제공하는 기능
RestTemplate의 Get 요청 방법
client 입장 서버
- RestTemplate 주입 받기
- RestTemplateBuilder의 build() 메서드를 사용해 주입 받음.
- 요청 받은 검색어를 Query String 방식으로 Server 입장의 서버로 RestTemplate를 사용해 요청
public ItemDto getCallObject(String query) { // 요청 URL 만들기 URI uri = UriComponentsBuilder .fromUriString("http://localhost:7070") .path("/api/server/get-call-obj") .queryParam("query", query) .encode() .build() .toUri(); log.info("uri = " + uri); ResponseEntity<ItemDto> responseEntity = restTemplate.getForEntity(uri, ItemDto.class); log.info("statusCode = " + responseEntity.getStatusCode()); return responseEntity.getBody(); }
- UriComponentsBuilder를 사용해 URI class 객체를 쉽게 만들 수 있음.
- getForEntity는 특정 URI로 GET 요청을 보내고, 응답 데이터를 지정한 클래스 타입(두번째 파라미터)의 객체로 자동변환해줌.
- getForEntity를 통해 받는 것의 타입을 ResponseEntity 타입으로 받을 수 있음.
- responseEntity.getBody()를 사용해 두 번째 파라미터로 전달한 클래스 타입으로 자동 변환된 객체를 가져올 수 있음.
server 입장 서버
public Item getCallObject(String query) {
for (Item item : itemList) {
if(item.getTitle().equals(query)) {
return item;
}
}
return null;
}
- server 입장의 서버에서 itemList를 조회하여 요청받은 검색어에 맞는 Item을 반환
요청한 Item이 여러 개일 경우
client 입장 서버
build.gradle 에 아래 내용 추가. (json 라이브러리 사용하기 위해)
// json
implementation 'org.json:json:20230227'
- 요청 URL을 만듦.
- 중첩 JSON 형태로 넘어올 경우, String 타입으로 한 번에 데이터를 받아 변환
- JSONObject 라이브러리의 JSONArray를 사용해 String으로 되어있는 중첩 JSON 조작.
- 조작하여 변환 후 ItemDto 타입의 리스트로 만들어 반환
- ItemDto에 받아온 JSONObject를 사용해 초기화하는 생성자 추가
@Getter @NoArgsConstructor public class ItemDto { private String title; private int price; public ItemDto(JSONObject itemJson) { this.title = itemJson.getString("title"); this.price = itemJson.getInt("price"); } }
server 입장 서버
- server 입장의 서버에서 itemList를 ItemResponseDto에 담아 반환
public ItemResponseDto getCallList() { ItemResponseDto responseDto = new ItemResponseDto(); for (Item item : itemList) { responseDto.setItems(item); } return responseDto; }
RestTemplate의 Post 요청 방법
client 입장 서버
public ItemDto postCall(String query) {
// 요청 URL 만들기
URI uri = UriComponentsBuilder
.fromUriString("http://localhost:7070")
.path("/api/server/post-call/{query}")
.encode()
.build()
.expand(query)
.toUri();
log.info("uri = " + uri);
User user = new User("Robbie", "1234");
ResponseEntity<ItemDto> responseEntity = restTemplate.postForEntity(uri, user, ItemDto.class);
log.info("statusCode = " + responseEntity.getStatusCode());
return responseEntity.getBody();
}
- 요청 받은 검색어를 PathVariable 방식으로 Server 입장의 서버로 RestTemplate를 사용하여 요청
- .expand()한 후 .path에서 중괄호에 들어갈 값을 넣어주면 됨.
- Get과는 다르게 Post방식에서는 Body 부분에 데이터를 넘길 수 있기 때문에 RestTemplate에서는 postForEntity를 가지고 있음. (postForEntity => post 방식일 때 사용하는 메서드)
- 첫번째 인자로는 uri, 두번째인자로는 httpBody에 넣어줄 데이터를, 세번째 인자로 전달받은 데이터랑 mapping 할 거.
- 두번째 인자는 객체를 넣어주면 RestTemplate이 자동으로 변환해줌.
server 입장 서버
@PostMapping("/post-call/{query}")
public Item postCall(@PathVariable String query, @RequestBody UserRequestDto requestDto) {
return itemService.postCall(query, requestDto);
}
- Server 입장의 서버에서 itemList를 조회하여 요청 받은 Item을 반환
RestTemplate의 exchange
RestTemplate으로 요청을 보낼 때 Header에 특정 정보를 같이 전달하고 싶다면?
client입장 서버
public List<ItemDto> exchangeCall(String token) {
// 요청 URL 만들기
URI uri = UriComponentsBuilder
.fromUriString("http://localhost:7070")
.path("/api/server/exchange-call")
.encode()
.build()
.toUri();
log.info("uri = " + uri);
User user = new User("Robbie", "1234");
RequestEntity<User> requestEntity = RequestEntity
.post(uri)
.header("X-Authorization", token)
.body(user);
ResponseEntity<String> responseEntity = restTemplate.exchange(requestEntity, String.class);
return fromJSONtoItems(responseEntity.getBody());
}
- RestTemplate의 exchange 메서드 사용
(이전에는 getForEntity나 postForEntity를 사용해 get, post 를 지정하였었음.)- 첫번째 인자로 RequestEntity 타입의 필드를 줌
(uri, header, body의 정보를 http에 넣어 한 번에 전달 가능.)- header에 첫번째로 X-Authorization을 키로 주고, 두번째로는 받아온 토큰 넣어줌.
- 두번째는 받아올 데이터를 String 타입으로 받아옴.
- 첫번째 인자로 RequestEntity 타입의 필드를 줌
server 입장 서버
@PostMapping("/exchange-call")
public ItemResponseDto exchangeCall(@RequestHeader("X-Authorization") String token, @RequestBody UserRequestDto requestDto) {
return itemService.exchangeCall(token, requestDto);
}
- header에서 키가 X-Authorization인 값(토큰)을 받고, 클라이언트 서버에서 httpBody 쪽에 넣어준 userData를 가져오기 위해 @RequestBody annotation, UseRequestDto를 사용해 그 데이터를 받아와 파라미터로 넣어준 후 서비스쪽으로 보냄.
- 전달된 header와 body의 정보를 확인할 수 있음.
public ItemResponseDto exchangeCall(String token, UserRequestDto requestDto) {
System.out.println("token = " + token);
System.out.println("requestDto.getUsername() = " + requestDto.getUsername());
System.out.println("requestDto.getPassword() = " + requestDto.getPassword());
return getCallList();
}
용어 정리
- UriComponentsBuilder
: URI를 쉽게 생성하게 돕는 도구 - ResponseEntity
: HTTP 관련된 데이터에 응답할 때 사용하는 클래스.
'내일배움캠프(Sparta) > Spring' 카테고리의 다른 글
[Spring] Entity 클래스 간의 관계 (0) | 2023.11.20 |
---|---|
[Spring] Entity 연관관계 (1) | 2023.11.14 |
[Spring] Spring Security / Validation (1) | 2023.11.09 |
[Spring] Filter (0) | 2023.11.09 |
[Spring] JWT / 패스워드 암호화 (0) | 2023.11.08 |