RestTemplateConfig 수정, wmts 수정
This commit is contained in:
@@ -22,29 +22,45 @@ public class ExternalHttpClient {
|
||||
private final RestTemplate restTemplate;
|
||||
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) {
|
||||
|
||||
HttpHeaders resolvedHeaders = resolveJsonHeaders(headers);
|
||||
// responseType 기반으로 Accept 동적 세팅
|
||||
HttpHeaders resolvedHeaders = resolveHeaders(headers, responseType);
|
||||
logRequestBody(body);
|
||||
|
||||
HttpEntity<Object> entity = new HttpEntity<>(body, resolvedHeaders);
|
||||
|
||||
try {
|
||||
// String: raw bytes -> UTF-8 string
|
||||
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 이므로 안전
|
||||
T casted = (T) raw;
|
||||
return new ExternalCallResult<>(res.getStatusCodeValue(), true, casted, null);
|
||||
}
|
||||
|
||||
// byte[]: raw bytes로 받고, JSON이면 에러로 처리
|
||||
if (responseType == byte[].class) {
|
||||
ResponseEntity<byte[]> res = restTemplate.exchange(url, method, entity, byte[].class);
|
||||
|
||||
MediaType ct = res.getHeaders().getContentType();
|
||||
byte[] bytes = res.getBody();
|
||||
|
||||
if (isJsonLike(ct)) {
|
||||
String err = (bytes == null) ? null : new String(bytes, StandardCharsets.UTF_8);
|
||||
return new ExternalCallResult<>(res.getStatusCodeValue(), false, null, err);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
T casted = (T) bytes;
|
||||
return new ExternalCallResult<>(res.getStatusCodeValue(), true, casted, null);
|
||||
}
|
||||
|
||||
// DTO 등: 일반 역직렬화
|
||||
ResponseEntity<T> res = restTemplate.exchange(url, method, entity, responseType);
|
||||
return new ExternalCallResult<>(res.getStatusCodeValue(), true, res.getBody(), null);
|
||||
|
||||
@@ -54,18 +70,42 @@ public class ExternalHttpClient {
|
||||
}
|
||||
}
|
||||
|
||||
private HttpHeaders resolveJsonHeaders(HttpHeaders headers) {
|
||||
HttpHeaders h = (headers == null) ? new HttpHeaders() : headers;
|
||||
// 기존 resolveJsonHeaders를 "동적"으로 교체
|
||||
private HttpHeaders resolveHeaders(HttpHeaders headers, Class<?> responseType) {
|
||||
// 원본 headers를 그대로 쓰면 외부에서 재사용할 때 사이드이펙트 날 수 있어서 복사 권장
|
||||
HttpHeaders h = (headers == null) ? new HttpHeaders() : new HttpHeaders(headers);
|
||||
|
||||
// 요청 바디 기본은 JSON이라고 가정 (필요하면 호출부에서 덮어쓰기)
|
||||
if (h.getContentType() == null) {
|
||||
h.setContentType(MediaType.APPLICATION_JSON);
|
||||
}
|
||||
if (h.getAccept() == null || h.getAccept().isEmpty()) {
|
||||
|
||||
// 호출부에서 Accept를 명시했으면 존중
|
||||
if (h.getAccept() != null && !h.getAccept().isEmpty()) {
|
||||
return h;
|
||||
}
|
||||
|
||||
// responseType 기반 Accept 자동 지정
|
||||
if (responseType == byte[].class) {
|
||||
h.setAccept(
|
||||
List.of(
|
||||
MediaType.APPLICATION_OCTET_STREAM,
|
||||
MediaType.valueOf("application/zip"),
|
||||
MediaType.APPLICATION_JSON // 실패(JSON 에러 바디) 대비
|
||||
));
|
||||
} else {
|
||||
h.setAccept(List.of(MediaType.APPLICATION_JSON));
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
private boolean isJsonLike(MediaType ct) {
|
||||
if (ct == null) return false;
|
||||
return ct.includes(MediaType.APPLICATION_JSON)
|
||||
|| "application/problem+json".equalsIgnoreCase(ct.toString());
|
||||
}
|
||||
|
||||
private void logRequestBody(Object body) {
|
||||
try {
|
||||
if (body != null) {
|
||||
|
||||
Reference in New Issue
Block a user