[백엔드 기초] RestTemplate

2025. 10. 24. 20:39·Spring/백엔드 기초

Spring 에서는 서버에서 다른 서버로 간편하게 요청할 수 있도록 RestTemplate 기능을 제공하고 있다.

Servcer To Server로 Client 입장의 서버로 다른 서버의 API를 활용하면 간단하게 기능 구현을 할 수 있게 된다.

 

실습과정에서 경험했던 가벼운 RestTemplate 개념을 정리하고 넘어가고자 한다.

 

2개의 프로젝트를 통해 Client 입장의 서버는 8080 포트를 이용, Servcer 입장의 서버는 7070 포트로 동시에 실행을 시켜 보는 과정이다.

 

Client 입장 서버

  • RestTemplateController
package com.sparta.springresttemplateclient.controller;

import com.sparta.springresttemplateclient.dto.ItemDto;
import com.sparta.springresttemplateclient.service.RestTemplateService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/api/client")
public class RestTemplateController {

    private final RestTemplateService restTemplateService;

    public RestTemplateController(RestTemplateService restTemplateService) {
        this.restTemplateService = restTemplateService;
    }

    @GetMapping("/get-call-obj")
    public ItemDto getCallObject(String query) {
        return restTemplateService.getCallObject(query);
    }

    @GetMapping("/get-call-list")
    public List<ItemDto> getCallList() {
        return restTemplateService.getCallList();
    }

    @GetMapping("/post-call")
    public ItemDto postCall(String query) {
        return restTemplateService.postCall(query);
    }

    @GetMapping("/exchange-call")
    public List<ItemDto> exchangeCall(@RequestHeader("Authorization") String token) {
        return restTemplateService.exchangeCall(token);
    }
}
  • ItemDto
package com.sparta.springresttemplateclient.dto;

import lombok.Getter;
import lombok.NoArgsConstructor;
import org.json.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");
    }
}
  • ItemDto에 받아온 JSONObject를 사용하여 초기화하는 생성자를 추가

 

  • User
package com.sparta.springresttemplateclient.entity;

import lombok.Getter;

@Getter
public class User {
    private String username;
    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}
  • RestTemplateService
package com.sparta.springresttemplateclient.service;

import com.sparta.springresttemplateclient.dto.ItemDto;
import org.springframework.stereotype.Service;

import java.util.List;

@Slf4j
@Service
public class RestTemplateService {

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();
}

    public List<ItemDto> getCallList() {
    // 요청 URL 만들기
    URI uri = UriComponentsBuilder
            .fromUriString("http://localhost:7070")
            .path("/api/server/get-call-list")
            .encode()
            .build()
            .toUri();
    log.info("uri = " + uri);

    ResponseEntity<String> responseEntity = restTemplate.getForEntity(uri, String.class);

    log.info("statusCode = " + responseEntity.getStatusCode());
    log.info("Body = " + responseEntity.getBody());

    return fromJSONtoItems(responseEntity.getBody());
}

    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();
}

    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());
}
    
    public List<ItemDto> fromJSONtoItems(String responseEntity) {
    JSONObject jsonObject = new JSONObject(responseEntity);
    JSONArray items  = jsonObject.getJSONArray("items");
    List<ItemDto> itemDtoList = new ArrayList<>();

    for (Object item : items) {
        ItemDto itemDto = new ItemDto((JSONObject) item);
        itemDtoList.add(itemDto);
    }

    return itemDtoList;
}
}
  • Spring의 UriComponentsBuilder를 사용하여 URI를 손쉽게 만들 수 있음
  • getForEntity는 Get 방식으로 해당 URI의 서버에 요청을 진행
  • getCallList : 결과값이 다중 JSON으로 넘어오기 때문에 JSON To Object를 사용하지 않고 일단 String 값 그대로를 가져옴
  • exchangeCall : exchange 메서드의 첫 번째 파라미터에 RequestEntity 객체를 만들어 전달해주면 uri, header, body의 정보를 한번에 전달할 수 있음

 


Server 입장 서버

  • ItemController
package com.sparta.springresttemplateserver.controller;

import com.sparta.springresttemplateserver.dto.ItemResponseDto;
import com.sparta.springresttemplateserver.dto.UserRequestDto;
import com.sparta.springresttemplateserver.entity.Item;
import com.sparta.springresttemplateserver.service.ItemService;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api/server")
public class ItemController {

    private final ItemService itemService;

    public ItemController(ItemService itemService) {
        this.itemService = itemService;
    }

    @GetMapping("/get-call-obj")
    public Item getCallObject(@RequestParam String query) {
        return itemService.getCallObject(query);
    }

    @GetMapping("/get-call-list")
    public ItemResponseDto getCallList() {
        return itemService.getCallList();
    }

    @PostMapping("/post-call/{query}")
    public Item postCall(@PathVariable String query, @RequestBody UserRequestDto requestDto) {
        return itemService.postCall(query, requestDto);
    }

    @PostMapping("/exchange-call")
    public ItemResponseDto exchangeCall(@RequestHeader("X-Authorization") String token, @RequestBody UserRequestDto requestDto) {
        return itemService.exchangeCall(token, requestDto);
    }
}
  • UserRequestDto
package com.sparta.springresttemplateserver.dto;

import lombok.Getter;

@Getter
public class UserRequestDto {
    private String username;
    private String password;
}
  • ItemResponseDto
package com.sparta.springresttemplateserver.dto;

import com.sparta.springresttemplateserver.entity.Item;
import lombok.Getter;

import java.util.ArrayList;
import java.util.List;

@Getter
public class ItemResponseDto {
    private final List<Item> items = new ArrayList<>();

    public void setItems(Item item) {
        items.add(item);
    }
}
  • Item
package com.sparta.springresttemplateserver.entity;

import lombok.Getter;

@Getter
public class Item {
    private String title;
    private int price;

    public Item(String title, int price) {
        this.title = title;
        this.price = price;
    }
}
  • ItemService
package com.sparta.springresttemplateserver.service;

import com.sparta.springresttemplateserver.dto.ItemResponseDto;
import com.sparta.springresttemplateserver.dto.UserRequestDto;
import com.sparta.springresttemplateserver.entity.Item;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;

@Service
public class ItemService {

    private final List<Item> itemList = Arrays.asList(
            new Item("Mac", 3_888_000),
            new Item("iPad", 1_230_000),
            new Item("iPhone", 1_550_000),
            new Item("Watch", 450_000),
            new Item("AirPods", 350_000)
    );

    public Item getCallObject(String query) {
    for (Item item : itemList) {
        if(item.getTitle().equals(query)) {
            return item;
        }
    }
    return null;
}

    public ItemResponseDto getCallList() {
    ItemResponseDto responseDto = new ItemResponseDto();
    for (Item item : itemList) {
        responseDto.setItems(item);
    }
    return responseDto;
}

    public Item postCall(String query, UserRequestDto userRequestDto) {
    System.out.println("userRequestDto.getUsername() = " + userRequestDto.getUsername());
    System.out.println("userRequestDto.getPassword() = " + userRequestDto.getPassword());

    return getCallObject(query);
}

    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();
}
}
  • itemList를 조회하여 요청받은 검색어에 맞는 Item을 반환 
  • getCallList : itemList를 ItemResponseDto에 담아 반환
  • exchangeCall : 전달된 header와 body의 정보를 확인할 수 있음

이 과정들을 실습하면서 실제로 User에서 요청하는 값에 따른 값을 반환하고 얻는 과정을 확인할 수 있었고 서버와 서버 간의 통신과정을 기본적으로 이해해볼 수 있는 경험을 가졌다. 

'Spring > 백엔드 기초' 카테고리의 다른 글

[백엔드 기초] 클라우드 개념 이해하기 (보충작성 필요)  (1) 2025.11.11
[백엔드 기초] Validation 개념 정리  (0) 2025.10.30
[백엔드 기초] Filter, Spring Security  (0) 2025.10.24
[백엔드 기초] 쿠키를 활용한 인증 인가 개념 실습  (0) 2025.10.23
[백엔드 기초] 백엔드 기초 개념정리  (0) 2025.10.22
'Spring/백엔드 기초' 카테고리의 다른 글
  • [백엔드 기초] 클라우드 개념 이해하기 (보충작성 필요)
  • [백엔드 기초] Validation 개념 정리
  • [백엔드 기초] Filter, Spring Security
  • [백엔드 기초] 쿠키를 활용한 인증 인가 개념 실습
stark77
stark77
하마의 IT 자기개발 이모저모, 백엔드 개발자로 거듭나기
  • stark77
    하마의 개발자 성장일기
    stark77
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 컴퓨터구조와 운영체제
        • 컴퓨터구조
        • 운영체제
      • SQL 기초
      • Spring
        • 백엔드 기초
        • Spring 실습
      • JAVA
        • Java 실습
      • HTML&CSS
        • HTML&CSS 실습
      • Git&GitHub
        • Git&GitHub 실습
      • 내배캠 끄적끄적
        • Today I Learned
      • 유용한 툴 및 사이트 정리
      • 취미
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    객체지향
    MVC
    git
    java
    Spriingboot
    HTML&CSS
    Java 문법기초
    thymleaf
    String.format
    백엔드 기초
    웹소켓
    jsp
    네트워크 기초
    algorithm
    WebSocket
    프로세스와 쓰레드
    실시간 데이터 처리
    Spring
    JPA
    BEAN
    경합조건과 교착상태
    Stomp
    RestTemplate
    다형성
    for문
    Til
    객체지향프로그래밍
    Github
    SpringSecurity
    백엔드 기초다지기
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
stark77
[백엔드 기초] RestTemplate
상단으로

티스토리툴바