diff --git a/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java b/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java index 8c2e36b1..e4e656d2 100644 --- a/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java +++ b/src/main/java/com/kamco/cd/kamcoback/config/resttemplate/ExternalHttpClient.java @@ -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 ExternalCallResult call( String url, HttpMethod method, Object body, HttpHeaders headers, Class responseType) { - HttpHeaders resolvedHeaders = resolveJsonHeaders(headers); + // responseType 기반으로 Accept 동적 세팅 + HttpHeaders resolvedHeaders = resolveHeaders(headers, responseType); logRequestBody(body); HttpEntity entity = new HttpEntity<>(body, resolvedHeaders); try { + // String: raw bytes -> UTF-8 string if (responseType == String.class) { ResponseEntity 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 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 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) { diff --git a/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java b/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java index 53e5c216..e1dbccbf 100755 --- a/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java +++ b/src/main/java/com/kamco/cd/kamcoback/layer/dto/WmtsLayerInfo.java @@ -18,17 +18,20 @@ public class WmtsLayerInfo { private List keywords = new ArrayList<>(); private BoundingBox boundingBox; - private List formats = new ArrayList<>(); private List tileMatrixSetLinks = new ArrayList<>(); private List resourceUrls = new ArrayList<>(); private List