feat/infer_dev_260107 #20

Merged
teddy merged 2 commits from feat/infer_dev_260107 into develop 2026-01-30 16:53:05 +09:00

View File

@@ -1,10 +1,14 @@
package com.kamco.cd.kamcoback.config.resttemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.nio.charset.StandardCharsets;
import java.util.List;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.HttpStatusCodeException;
@@ -16,15 +20,53 @@ import org.springframework.web.client.RestTemplate;
public class ExternalHttpClient {
private final RestTemplate restTemplate;
private final com.fasterxml.jackson.databind.ObjectMapper objectMapper;
private final ObjectMapper objectMapper;
/**
* - responseType이 DTO면: DTO로 역직렬화 - responseType이 String.class면: 응답을 byte[]로 받아 UTF-8 원문 문자열로 반환
* (배열/객체 등 유동 JSON 안전)
*/
public <T> ExternalCallResult<T> call(
String url, HttpMethod method, Object body, HttpHeaders headers, Class<T> responseType) {
if (headers == null) headers = new HttpHeaders();
headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
headers.setAccept(java.util.List.of(org.springframework.http.MediaType.APPLICATION_JSON));
HttpHeaders resolvedHeaders = resolveJsonHeaders(headers);
logRequestBody(body);
HttpEntity<Object> entity = new HttpEntity<>(body, resolvedHeaders);
try {
if (responseType == String.class) {
ResponseEntity<byte[]> res = restTemplate.exchange(url, method, entity, byte[].class);
String raw =
(res.getBody() == null) ? null : new String(res.getBody(), StandardCharsets.UTF_8);
@SuppressWarnings("unchecked")
T casted = (T) raw; // responseType == String.class 이므로 안전
return new ExternalCallResult<>(res.getStatusCodeValue(), true, casted, null);
}
ResponseEntity<T> res = restTemplate.exchange(url, method, entity, responseType);
return new ExternalCallResult<>(res.getStatusCodeValue(), true, res.getBody(), null);
} catch (HttpStatusCodeException e) {
return new ExternalCallResult<>(
e.getStatusCode().value(), false, null, e.getResponseBodyAsString());
}
}
private HttpHeaders resolveJsonHeaders(HttpHeaders headers) {
HttpHeaders h = (headers == null) ? new HttpHeaders() : headers;
if (h.getContentType() == null) {
h.setContentType(MediaType.APPLICATION_JSON);
}
if (h.getAccept() == null || h.getAccept().isEmpty()) {
h.setAccept(List.of(MediaType.APPLICATION_JSON));
}
return h;
}
private void logRequestBody(Object body) {
try {
if (body != null) {
log.info("[HTTP-REQ-BODY-JSON] {}", objectMapper.writeValueAsString(body));
@@ -32,16 +74,6 @@ public class ExternalHttpClient {
} catch (Exception e) {
log.warn("[HTTP-REQ-BODY-JSON] serialize failed: {}", e.getMessage());
}
HttpEntity<Object> entity = new HttpEntity<>(body, headers);
try {
ResponseEntity<T> res = restTemplate.exchange(url, method, entity, responseType);
return new ExternalCallResult<>(res.getStatusCodeValue(), true, res.getBody(), null);
} catch (HttpStatusCodeException e) {
return new ExternalCallResult<>(
e.getStatusCode().value(), false, null, e.getResponseBodyAsString());
}
}
public record ExternalCallResult<T>(int statusCode, boolean success, T body, String errBody) {}