diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java index 7588d87..3f55fb0 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -81,6 +81,7 @@ import com.eactive.eai.common.util.TxFileLogger; import com.eactive.eai.common.util.XMLUtils; import com.eactive.eai.util.JsonPathUtil; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; @@ -127,6 +128,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp private boolean useAdapterToken; + private ObjectMapper mapper = new ObjectMapper(); + /** * 1. 기능 : REST API 통신에 사용
* 2. 처리 개요 : - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다.
@@ -876,18 +879,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } - /* nice on 나이스 지키미 용으로 생성함 - * jwhong 2015-11-04 - */ - private void setNiceOnAuthHeaders(HttpUriRequestBase method, String auth) throws Exception { - method.setHeader("Authorization", - String.format("%s %s", "bearer", auth)); // 나이스지키미 format임, bearer을 소문자로 보내야함 - String productId = PropManager.getInstance().getProperty("NiceOnProperty","productId.value"); - method.setHeader("ProductID", productId); - //method.setHeader("Authorization", - // String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); - } - private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, String encode) { if (responseMessage == null) { @@ -923,12 +914,17 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if ( httpHeader instanceof ObjectNode) { ObjectNode objectNode = (ObjectNode) httpHeader; objectNode.fields().forEachRemaining(e -> { + if ("Content-Length".equalsIgnoreCase(e.getKey())) + return; JsonNode value = e.getValue(); method.setHeader((String) e.getKey(), value.isNull() ? null : value.asText()); }); } else if (httpHeader instanceof JSONObject) { JSONObject jsonObject = (JSONObject) httpHeader; for (Object key : jsonObject.keySet()) { + if ("Content-Length".equalsIgnoreCase((String) key)) + continue; + Object obj = jsonObject.get(key); if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { continue; @@ -939,7 +935,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp if (logger.isDebugEnabled()) { logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); } - } } } @@ -1046,6 +1041,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp body = ((Document)eaiBody).asXML(); } else if(eaiBody instanceof JSONObject) { body = ((JSONObject)eaiBody).toJSONString(); + } else if(eaiBody instanceof ObjectNode) { + body = mapper.writeValueAsString((ObjectNode) eaiBody); } else { body = eaiBody.toString(); } diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRestAddFilter.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRestAddFilter.java index d034ceb..d9979c6 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRestAddFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRestAddFilter.java @@ -9,6 +9,9 @@ import org.json.simple.JSONObject; import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; import com.eactive.eai.adapter.http.client.impl.filter.HttpClient5AdapterFilterFactory; import com.eactive.eai.adapter.http.client.impl.filter.HttpClientAdapterFilter; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; /** * 1. 기능 : HttpClient5AdapterServiceRest 호출 전후 Filter 적용할 수 있는 기능을 제공한다.
@@ -34,6 +37,8 @@ public class HttpClient5AdapterServiceRestAddFilter extends HttpClient5AdapterSe // // Adapter에서 Exception이 발생한 경우, 처리할 필터 // static final String EXCEPTION_FILTER = "EXCEPTION_FILTER"; + private ObjectMapper mapper = new ObjectMapper(); + /** * 1. 기능 : HttpClient 호출 전후 Filter 적용용 2. 처리 개요 :
* 3. 주의사항
@@ -54,8 +59,9 @@ public class HttpClient5AdapterServiceRestAddFilter extends HttpClient5AdapterSe adapterResponse = doPostFilters(adptGrpName, adptName, prop, adapterResponse, tempProp); if (adapterResponse instanceof JSONObject) adapterResponse = ((JSONObject) adapterResponse).toJSONString(); - - if (adapterResponse instanceof Node) + else if (adapterResponse instanceof ObjectNode) + adapterResponse = mapper.writeValueAsString((ObjectNode) adapterResponse); + else if (adapterResponse instanceof Node) adapterResponse = ((Node) adapterResponse).asXML(); return adapterResponse; diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/filter/OutCryptoFilter.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/filter/OutCryptoFilter.java index 3c7633e..cded4c0 100644 --- a/src/main/java/com/eactive/eai/adapter/http/client/impl/filter/OutCryptoFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/filter/OutCryptoFilter.java @@ -31,7 +31,15 @@ public class OutCryptoFilter extends AbstractCryptoFilter implements HttpClientA * 서브클래스에서 오버라이드하여 tempProp으로부터 값을 추출할 수 있다. */ protected Map buildRuntimeContext(Properties prop, Properties tempProp) { - return new HashMap<>(); + Map context = new HashMap<>(); + for (String key : prop.stringPropertyNames()) { + context.put(key, prop.getProperty(key)); + } + + for (String key : tempProp.stringPropertyNames()) { + context.put(key, tempProp.getProperty(key)); + } + return context; } /** @@ -39,11 +47,10 @@ public class OutCryptoFilter extends AbstractCryptoFilter implements HttpClientA * 미설정 또는 값 없으면 null을 반환하여 GCM 기본 동작(IV를 AAD 대체값으로 사용)을 따른다. */ protected byte[] buildAad(Properties prop, Properties tempProp) { - String propKey = prop.getProperty(PROP_AAD_HEADER); - if (StringUtils.isBlank(propKey) || tempProp == null) { - return null; - } - String value = tempProp.getProperty(propKey); + if (tempProp == null) { + return null; + } + String value = tempProp.getProperty(PROP_AAD_HEADER); return StringUtils.isBlank(value) ? null : value.getBytes(StandardCharsets.UTF_8); } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java index bcb1ca3..128d253 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java @@ -6,7 +6,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; -import org.slf4j.MDC; +import org.json.simple.JSONObject; import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterManager; @@ -21,6 +21,8 @@ import com.eactive.eai.common.TransactionContextKeys; import com.eactive.eai.common.util.Logger; import com.eactive.eai.common.util.TxSiftContext; import com.eactive.eai.common.util.UUIDGenerator; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; public abstract class HttpAdapterServiceSupport implements HttpAdapterService, HttpAdapterServiceKey { private static final String LOG_PREFIX = "HttpAdapterServiceSupport] "; @@ -28,7 +30,8 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H public static final String HEADER_NAME_CLIENT_ID = "x-elink-client-id"; public static final String PROPERTIES_NAME_CLIENT_ID = "clientId"; static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); - + private ObjectMapper mapper = new ObjectMapper(); + public Object service(String adptGrpName, String adptName, Object message, Properties prop, HttpServletRequest request, HttpServletResponse response) throws Exception { String uuid = prop.getProperty(TransactionContextKeys.TRANSACTION_UUID); @@ -63,6 +66,13 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H Object obj = null; try { message = doPreFilters(adptGrpName, adptName, message, prop, request, response); + + if (message instanceof JSONObject) { + message = ((JSONObject) message).toJSONString(); + } else if (message instanceof JsonNode) { + message = mapper.writeValueAsString((JsonNode) message); + } + obj = RequestDispatcher.getRequestDispatcher(adptGrpName).handle(adptName, message, prop); obj = doPostFilters(adptGrpName, adptName, obj, prop, request, response); } catch (HttpStatusException e) { // inbound error @@ -86,6 +96,10 @@ public abstract class HttpAdapterServiceSupport implements HttpAdapterService, H return (byte[]) obj; } else if (obj instanceof String) { return (String) obj; + } else if (obj instanceof JSONObject) { + return ((JSONObject) obj).toJSONString(); + } else if (obj instanceof JsonNode) { + return mapper.writeValueAsString((JsonNode) obj); } else { throw new Exception("RECEAIAHA001"); } diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/InCryptoFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/InCryptoFilter.java index a9c9847..062d77e 100644 --- a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/InCryptoFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/InCryptoFilter.java @@ -25,7 +25,9 @@ import com.eactive.eai.adapter.http.filter.AbstractCryptoFilter; */ public class InCryptoFilter extends AbstractCryptoFilter implements HttpAdapterFilter { - /** + public static final String ERROR_DEC_FAIL = "E.DECRYPT_FAIL"; + public static final String ERROR_ENC_FAIL = "E.ENCRYPT_FAIL"; + /** * DYNAMIC 키 도출용 컨텍스트를 구성한다. * STATIC 키 모듈이면 빈 Map({@code new HashMap<>()})을 반환한다. * 서브클래스에서 오버라이드하여 HttpServletRequest로부터 값을 추출할 수 있다. diff --git a/src/main/java/com/eactive/eai/adapter/http/filter/AbstractCryptoFilter.java b/src/main/java/com/eactive/eai/adapter/http/filter/AbstractCryptoFilter.java index f83cc51..4577e53 100644 --- a/src/main/java/com/eactive/eai/adapter/http/filter/AbstractCryptoFilter.java +++ b/src/main/java/com/eactive/eai/adapter/http/filter/AbstractCryptoFilter.java @@ -66,7 +66,7 @@ public abstract class AbstractCryptoFilter { * fromPath의 Base64 값을 복호화하여 toPath에 반영. JSON 파싱 1회. * toPath = "/" → fromPath 필드를 제거하고 복호화된 JSON을 body에 병합. */ - protected String decryptField(String body, String moduleName, Map runtimeCtx, + protected Object decryptField(String body, String moduleName, Map runtimeCtx, byte[] aad, String fromPath, String toPath) throws Exception { JsonNode root = JsonPathUtil.toTree(body); String encBase64 = JsonPathUtil.getAt(root, fromPath); @@ -81,7 +81,7 @@ public abstract class AbstractCryptoFilter { return JsonPathUtil.mergeAtRoot(root, fromPath, plainText); } JsonPathUtil.setAt(root, toPath, plainText); - return JsonPathUtil.fromTree(root); + return root; } // ------------------------------------------------------------------ @@ -99,7 +99,7 @@ public abstract class AbstractCryptoFilter { * fromPath 값을 암호화하여 toPath(Base64)에 반영. JSON 파싱 1회. * fromPath = "/" → body 전체를 암호화하여 toPath 필드명으로 래핑 (파싱 불필요). */ - protected String encryptField(String body, String moduleName, Map runtimeCtx, + protected Object encryptField(String body, String moduleName, Map runtimeCtx, byte[] aad, String fromPath, String toPath) throws Exception { if (PATH_ROOT.equals(fromPath)) { byte[] cipherBytes = CryptoModuleService.getInstance().encrypt(moduleName, runtimeCtx, aad, @@ -112,13 +112,13 @@ public abstract class AbstractCryptoFilter { String plainText = JsonPathUtil.getAt(root, fromPath); if (StringUtils.isBlank(plainText)) { logger.warn("CryptoFilter] 암호화 대상 필드 없음: path=" + fromPath); - return body; + return root; } byte[] cipherBytes = CryptoModuleService.getInstance().encrypt(moduleName, runtimeCtx, aad, plainText.getBytes(StandardCharsets.UTF_8)); String encBase64 = Base64.getEncoder().encodeToString(cipherBytes); JsonPathUtil.setAt(root, toPath, encBase64); - return JsonPathUtil.fromTree(root); + return root; } // ------------------------------------------------------------------ diff --git a/src/main/java/com/eactive/eai/util/JsonPathUtil.java b/src/main/java/com/eactive/eai/util/JsonPathUtil.java index d1eff79..ff24a96 100644 --- a/src/main/java/com/eactive/eai/util/JsonPathUtil.java +++ b/src/main/java/com/eactive/eai/util/JsonPathUtil.java @@ -145,12 +145,12 @@ public class JsonPathUtil { * @param mergeJson 병합할 JSON 문자열 * @return 병합된 JSON 문자열, 병합 불가 시 mergeJson 그대로 반환 */ - public static String mergeAtRoot(JsonNode bodyNode, String removeFromPath, String mergeJson) { + public static JsonNode mergeAtRoot(JsonNode bodyNode, String removeFromPath, String mergeJson) { try { JsonNode mergeNode = objectMapper.readTree(mergeJson); if (!bodyNode.isObject() || !mergeNode.isObject()) { - return mergeJson; + return bodyNode; } ObjectNode result = (ObjectNode) bodyNode.deepCopy(); @@ -169,9 +169,10 @@ public class JsonPathUtil { // mergeJson 필드를 body에 병합 (기존 필드 덮어쓰기) result.setAll((ObjectNode) mergeNode); - return objectMapper.writeValueAsString(result); +// return objectMapper.writeValueAsString(result); + return result; } catch (Exception e) { - return mergeJson; + return bodyNode; } } @@ -192,7 +193,7 @@ public class JsonPathUtil { */ public static String mergeAtRoot(String body, String removeFromPath, String mergeJson) { try { - return mergeAtRoot(objectMapper.readTree(body), removeFromPath, mergeJson); + return objectMapper.writeValueAsString(mergeAtRoot(objectMapper.readTree(body), removeFromPath, mergeJson)); } catch (Exception e) { return mergeJson; }