Java의 기본 네트워크 통신 클래스로, URL로 표현되는 리소스와의 연결을 나타내고 URL의 내용을 읽어오거나 GET, POST 등의 HTTP 메서드를 사용해 데이터를 주고받을 수 있다. 이를 통해 외부 라이브러리 없이 기본적인 HTTP 통신을 구현할 때 사용한다.
Spring 3.0부터 지원하는 HTTP 클라이언트 템플릿으로, HTTP 서버와의 통신을 단순화하고 다양한 HTTP 메서드(GET, POST, PUT, DELETE 등)에 대응하는 편리한 메서드를 제공한다. 이를 통해 Restful 원칙을 쉽게 준수하며 HTTP 통신을 효율적으로 구현할 수 있다.
// 원래 코드 (URLConnection)
@Slf4j
@Service
@RequiredArgsConstructor
public class HolidayService {
@Value("${holidayKey}")
private String holidayKey;
private final HolidayRepository holidayRepository;
public ArrayList<HashMap<String, Object>> getHoliday(String year) throws IOException {
StringBuilder urlBuilder = new StringBuilder("Holiday-OPEN-API-URL"); /*URL*/
urlBuilder.append("?" + URLEncoder.encode("serviceKey", "UTF-8") + "=" + holidayKey); /*Service Key*/
urlBuilder.append("&" + URLEncoder.encode("pageNo", "UTF-8") + "=" + URLEncoder.encode("1", "UTF-8")); /*페이지번호*/
urlBuilder.append("&" + URLEncoder.encode("_type", "UTF-8") + "=" + URLEncoder.encode("json", "UTF-8")); /*타입*/
urlBuilder.append("&" + URLEncoder.encode("numOfRows", "UTF-8") + "=" + URLEncoder.encode("100", "UTF-8")); /*한 페이지 결과 수*/
urlBuilder.append("&" + URLEncoder.encode("solYear", "UTF-8") + "=" + URLEncoder.encode(year, "UTF-8")); /*연*/
URL url = new URL(urlBuilder.toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Content-type", "application/json");
BufferedReader rd;
if (conn.getResponseCode() >= 200 && conn.getResponseCode() <= 300) {
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
} else {
rd = new BufferedReader(new InputStreamReader(conn.getErrorStream()));
}
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
conn.disconnect();
Map<String, Object> holidayMap = string2Map(sb.toString());
Map<String, Object> response = (Map<String, Object>) holidayMap.get("response");
Map<String, Object> body = (Map<String, Object>) response.get("body");
HashMap<String, Object> items = (HashMap<String, Object>) body.get("items");
ArrayList<HashMap<String, Object>> item = (ArrayList<HashMap<String, Object>>) items.get("item");
return item;
}
}
// 리팩토링 코드 (RestTemplate)
@Slf4j
@Service
@RequiredArgsConstructor
public class HolidayService {
@Value("${holidayKey}")
private String holidayKey;
private final HolidayRepository holidayRepository;
private final RestTemplate restTemplate;
private final ObjectMapper objectMapper;
public List<Map<String, Object>> getHoliday(String year) {
String url = String.format("Holiday-OPEN-API-URL",holidayKey, year);
String response = restTemplate.getForObject(url, String.class);
try {
Map<String, Object> holidayMap = objectMapper.readValue(response, Map.class);
return Optional.ofNullable(holidayMap)
.map(map -> (Map<String, Object>) map.get("response"))
.map(map -> (Map<String, Object>) map.get("body"))
.map(map -> (Map<String, Object>) map.get("items"))
.map(map -> (List<Map<String, Object>>) map.get("item"))
.orElse(Collections.emptyList());
} catch (IOException e) {
log.error("Error parsing holiday data", e);
return Collections.emptyList();
}
}
}
Spring 5.0부터 지원하는 비동기식 논블로킹 웹 클라이언트로, Reactive 스트림을 지원하고 효율적인 네트워크 사용과 확장성을 제공한다. RestTemplate의 대안으로 설계되었으며, Spring WebFlux와 함께 사용되어 반응형 프로그래밍 모델을 구현할 수 있다.
Spring 6.1에서 도입된 기능으로, Java의 인터페이스와 애노테이션을 통해 HTTP 요청을 선언적으로 정의한다. RestTemplate이나 WebClient와 함께 사용할 수 있어 HTTP 클라이언트 코드를 간소화할 수 있다.
Spring Framework 6.1에서 소개된 새로운 동기식 HTTP 클라이언트로, RestTemplate의 장점을 유지한다. 함수형 프로그래밍 스타일과 메서드 체이닝을 지원하여 더 읽기 쉬운 코드를 작성할 수 있다.