package com.interplug.qcast.util; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.interplug.qcast.biz.user.dto.SyncResponse; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.HttpURLConnection; import java.net.URL; import java.util.Map; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpMethod; import org.springframework.stereotype.Component; @Slf4j @Component @RequiredArgsConstructor public class InterfaceQsp { @Value("${qsp.url}") private String qspUrl; @Value("${front.url}") private String frontUrl; /** * API Call * * @param apiPath * @param requestObject * @return String * @throws Exception */ public String callApi(HttpMethod httpMethod, String apiPath, Object requestObject) throws Exception { URL url = null; HttpURLConnection con = null; OutputStreamWriter osw = null; BufferedReader br = null; StringBuilder sb = null; long startAt = System.currentTimeMillis(); String requestType = requestObject == null ? "none" : requestObject.getClass().getSimpleName(); try { // GET 요청 시 requestObject를 쿼리 스트링으로 변환 if (HttpMethod.GET.equals(httpMethod) && requestObject != null) { ObjectMapper om = new ObjectMapper(); Map params = om.convertValue(requestObject, Map.class); // Object -> Map 변환 String queryString = params.entrySet().stream() .map(entry -> entry.getKey() + "=" + entry.getValue()) .reduce((p1, p2) -> p1 + "&" + p2) .orElse(""); apiPath += "?" + queryString; // 쿼리 스트링 추가 } log.debug( "QSP API call start: method={}, url={}, requestType={}", httpMethod, apiPath, requestType); url = new URL(apiPath); con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(120000); // 서버에 연결되는 Timeout 시간 설정 con.setReadTimeout(120000); // InputStream 읽어 오는 Timeout 시간 설정 con.setRequestMethod(httpMethod.toString()); con.setRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Referer", frontUrl); con.setDoInput(true); con.setUseCaches(false); con.setDefaultUseCaches(false); if (HttpMethod.GET.equals(httpMethod)) { con.setDoOutput(false); } else { con.setDoOutput(true); // POST 데이터를 OutputStream으로 넘겨 주겠다는 설정 if (requestObject != null) { ObjectMapper om = new ObjectMapper(); osw = new OutputStreamWriter(con.getOutputStream()); osw.write(om.writeValueAsString(requestObject)); // json 형식의 message 전달 osw.flush(); } } sb = new StringBuilder(); int status = con.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8")); String line; while ((line = br.readLine()) != null) { sb.append(line); } } log.debug( "QSP API call end: method={}, url={}, status={}, durationMs={}", httpMethod, apiPath, status, System.currentTimeMillis() - startAt); } catch (Exception e) { log.error( "QSP API call failed: method={}, url={}, durationMs={}", httpMethod, apiPath, System.currentTimeMillis() - startAt, e); throw e; } finally { try { if (osw != null) osw.close(); if (br != null) br.close(); } catch (Exception e) { throw e; } } return sb != null ? sb.toString() : null; } /** * API 호출후 Response 객체로 Return * * @param method * @param qspInterUrl * @param requestObject * @param responseObject * @return * @throws Exception */ public T callApiData( HttpMethod method, String qspInterUrl, Object requestObject, Object responseObject) throws Exception { // 데이터 읽기 SyncResponse syncResponse = new SyncResponse(); String strResponse = this.callApi(method, qspUrl + qspInterUrl, requestObject); ObjectMapper om = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); String dataJson = ""; if (!"".equals(strResponse)) { syncResponse = om.readValue(strResponse, SyncResponse.class); // 'data' 필드를 직접 사용하여 BatchResponse로 변환 if (syncResponse.getData() != null) { dataJson = om.writeValueAsString(syncResponse.getData()); } } if (responseObject == null) { return (T) dataJson; } else if (responseObject instanceof Class) { return om.readValue(dataJson, (Class) responseObject); } else if (responseObject instanceof TypeReference) { return om.readValue(dataJson, (TypeReference) responseObject); } else { throw new IllegalArgumentException("Unsupported responseType"); } } /** * API Call - byte return, file down 사용 * * @param apiPath * @param requestObject * @return String * @throws Exception */ public byte[] callApi( HttpMethod httpMethod, String apiPath, Object requestObject, Map result) throws Exception { URL url = null; HttpURLConnection con = null; OutputStreamWriter osw = null; BufferedReader br = null; byte[] bt = null; long startAt = System.currentTimeMillis(); String requestType = requestObject == null ? "none" : requestObject.getClass().getSimpleName(); try { log.debug( "QSP API call start: method={}, url={}, requestType={}", httpMethod, apiPath, requestType); url = new URL(apiPath); con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(30000); // 서버에 연결되는 Timeout 시간 설정 con.setReadTimeout(30000); // InputStream 읽어 오는 Timeout 시간 설정 con.setRequestMethod(httpMethod.toString()); con.setRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Referer", frontUrl); con.setDoInput(true); con.setUseCaches(false); con.setDefaultUseCaches(false); if (HttpMethod.GET.equals(httpMethod)) { con.setDoOutput(false); } else { con.setDoOutput(true); // POST 데이터를 OutputStream으로 넘겨 주겠다는 설정 if (requestObject != null) { ObjectMapper om = new ObjectMapper(); osw = new OutputStreamWriter(con.getOutputStream()); osw.write(om.writeValueAsString(requestObject)); // json 형식의 message 전달 osw.flush(); } } int status = con.getResponseCode(); if (status == HttpURLConnection.HTTP_OK) { // response 헤더 값 결과 셋팅 result.put("type", con.getHeaderField("Content-Type")); result.put("disposition", con.getHeaderField("Content-Disposition")); InputStream inputStream = con.getInputStream(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, bytesRead); } bt = outputStream.toByteArray(); // 파일 데이터 반환 } log.debug( "QSP API call end: method={}, url={}, status={}, durationMs={}", httpMethod, apiPath, status, System.currentTimeMillis() - startAt); } catch (Exception e) { log.error( "QSP API call failed: method={}, url={}, durationMs={}", httpMethod, apiPath, System.currentTimeMillis() - startAt, e); throw e; } finally { try { if (osw != null) osw.close(); if (br != null) br.close(); } catch (Exception e) { throw e; } } return bt != null ? bt : null; } }