feat/infer_dev_260107 #20
@@ -1,10 +1,14 @@
|
|||||||
package com.kamco.cd.kamcoback.config.resttemplate;
|
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.RequiredArgsConstructor;
|
||||||
import lombok.extern.log4j.Log4j2;
|
import lombok.extern.log4j.Log4j2;
|
||||||
import org.springframework.http.HttpEntity;
|
import org.springframework.http.HttpEntity;
|
||||||
import org.springframework.http.HttpHeaders;
|
import org.springframework.http.HttpHeaders;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.web.client.HttpStatusCodeException;
|
import org.springframework.web.client.HttpStatusCodeException;
|
||||||
@@ -16,24 +20,16 @@ import org.springframework.web.client.RestTemplate;
|
|||||||
public class ExternalHttpClient {
|
public class ExternalHttpClient {
|
||||||
|
|
||||||
private final RestTemplate restTemplate;
|
private final RestTemplate restTemplate;
|
||||||
private final com.fasterxml.jackson.databind.ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
/** responseType(예: DTO.class, String.class 등)로 그대로 역직렬화해서 받는 호출. - 응답 타입이 명확히 고정일 때 사용 */
|
||||||
public <T> ExternalCallResult<T> call(
|
public <T> ExternalCallResult<T> call(
|
||||||
String url, HttpMethod method, Object body, HttpHeaders headers, Class<T> responseType) {
|
String url, HttpMethod method, Object body, HttpHeaders headers, Class<T> responseType) {
|
||||||
|
|
||||||
if (headers == null) headers = new HttpHeaders();
|
HttpHeaders resolvedHeaders = resolveJsonHeaders(headers);
|
||||||
headers.setContentType(org.springframework.http.MediaType.APPLICATION_JSON);
|
logRequestBody(body);
|
||||||
headers.setAccept(java.util.List.of(org.springframework.http.MediaType.APPLICATION_JSON));
|
|
||||||
|
|
||||||
try {
|
HttpEntity<Object> entity = new HttpEntity<>(body, resolvedHeaders);
|
||||||
if (body != null) {
|
|
||||||
log.info("[HTTP-REQ-BODY-JSON] {}", objectMapper.writeValueAsString(body));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("[HTTP-REQ-BODY-JSON] serialize failed: {}", e.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpEntity<Object> entity = new HttpEntity<>(body, headers);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ResponseEntity<T> res = restTemplate.exchange(url, method, entity, responseType);
|
ResponseEntity<T> res = restTemplate.exchange(url, method, entity, responseType);
|
||||||
@@ -44,5 +40,51 @@ public class ExternalHttpClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 응답이 배열/객체/문자열/숫자 등 무엇이든 상관없이 "원문(JSON 문자열)"로 안전하게 받는 호출. - 응답 구조가 유동적이거나, String.class로 받았다가
|
||||||
|
* Jackson 컨버터 때문에 깨지는 케이스에 사용
|
||||||
|
*/
|
||||||
|
public ExternalCallResult<String> callRaw(
|
||||||
|
String url, HttpMethod method, Object body, HttpHeaders headers) {
|
||||||
|
|
||||||
|
HttpHeaders resolvedHeaders = resolveJsonHeaders(headers);
|
||||||
|
logRequestBody(body);
|
||||||
|
|
||||||
|
HttpEntity<Object> entity = new HttpEntity<>(body, resolvedHeaders);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ResponseEntity<byte[]> res = restTemplate.exchange(url, method, entity, byte[].class);
|
||||||
|
String raw =
|
||||||
|
(res.getBody() == null) ? null : new String(res.getBody(), StandardCharsets.UTF_8);
|
||||||
|
return new ExternalCallResult<>(res.getStatusCodeValue(), true, raw, 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;
|
||||||
|
|
||||||
|
// 이미 세팅돼 있으면 존중하고, 없으면 JSON 기본값 세팅
|
||||||
|
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));
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("[HTTP-REQ-BODY-JSON] serialize failed: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public record ExternalCallResult<T>(int statusCode, boolean success, T body, String errBody) {}
|
public record ExternalCallResult<T>(int statusCode, boolean success, T body, String errBody) {}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user