From ea09113dbe6d304858cbf75f91c3ee36e30323a0 Mon Sep 17 00:00:00 2001 From: curry772 Date: Tue, 2 Jun 2026 08:29:11 +0900 Subject: [PATCH] =?UTF-8?q?XML=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=A7=80?= =?UTF-8?q?=EC=9B=90=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../impl/CustomUrlEncodedFormEntity.java | 24 + .../impl/HttpClient5AdapterServiceRest.java | 337 +++++++++----- .../eactive/eai/common/util/JSONUtils.java | 423 ++++++++++++++++++ .../com/eactive/eai/common/util/XMLUtils.java | 93 ++++ 4 files changed, 772 insertions(+), 105 deletions(-) create mode 100644 src/main/java/com/eactive/eai/adapter/http/client/impl/CustomUrlEncodedFormEntity.java create mode 100644 src/main/java/com/eactive/eai/common/util/JSONUtils.java create mode 100644 src/main/java/com/eactive/eai/common/util/XMLUtils.java diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/CustomUrlEncodedFormEntity.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/CustomUrlEncodedFormEntity.java new file mode 100644 index 0000000..3733c9f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/CustomUrlEncodedFormEntity.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.nio.charset.Charset; + +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.net.WWWFormCodec; + +/** + * HttpComponent5에서 지원하는 UrlEncodedFormEntity 클래스는 chunked 옵션 설정을 지원하지 않아 새롭게 만들었음. + */ +public class CustomUrlEncodedFormEntity extends StringEntity { + + public CustomUrlEncodedFormEntity(final Iterable parameters, final Charset charset, + final boolean chunked) { + super(WWWFormCodec.format(parameters, + charset != null ? charset : ContentType.APPLICATION_FORM_URLENCODED.getCharset()), + charset != null ? ContentType.APPLICATION_FORM_URLENCODED.withCharset(charset) + : ContentType.APPLICATION_FORM_URLENCODED, + chunked); + } + +} 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 68ce6bf..aded95f 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 @@ -6,6 +6,7 @@ import java.math.BigDecimal; import java.net.ConnectException; import java.net.SocketTimeoutException; import java.net.URI; +import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; import java.util.ArrayList; @@ -76,6 +77,7 @@ import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.CommonLib; import com.eactive.eai.common.util.TxFileLogger; +import com.eactive.eai.common.util.XMLUtils; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import com.kjbank.encrypt.exchange.crypto.AES256Cipher; @@ -117,7 +119,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; // jwhong - static final String KJB_ROOTLESS_ARRAY = "{ \"KJB_ROOTLESS_ARRAY\" : "; + static final String DJB_ROOTLESS_ARRAY = "{ \"DJB_ROOTLESS_ARRAY\" : "; private boolean useAdapterToken; private boolean encryptResponseApply; @@ -139,17 +141,6 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // 2025.04.09 Authorization 헤더값을 프로퍼티(AUTH_TOKEN)에서 지정하여 설정할 수 있도록 수정 // 2025.05.29 프로퍼티 그룹 AUTH_TOKEN이 없을때 Null Point Exception 발생하여 수정 String bizCode = ""; - String authToken = ""; - try { - Properties authProp = PropManager.getInstance().getProperties(AUTH_TOKEN); //Authorization - bizCode = vo.getAdapterGroupName().substring(1, 4); - authToken = authProp.getProperty(bizCode, ""); - } catch (Exception e) { - logger.debug("Property Group AUTH_TOKEN is not Exist !!"); - } - - logger.debug("authToken :::::::::::::::::::::::::::::::::::" + authToken); - String headerGroupName = prop.getProperty(HEADER_GROUP); String relayResponseHeaderKeys = prop.getProperty(HEADER_KEYS, ""); useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); @@ -195,10 +186,27 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String rmethod = (String) restOptionObject.getOrDefault("method", inboundMethod); String contentType = (String) restOptionObject.getOrDefault("contentType", "application/json"); + + ContentType oContentType = ContentType.parse(contentType); + Charset contentTypeCharset = oContentType.getCharset(); + String charset = vo.getEncode(); + if(contentTypeCharset != null) + charset = contentTypeCharset.displayName(); + + logger.debug("HttpClient5AdapterServiceRest] charset = {}", charset); + + String mimeType = oContentType.getMimeType(); + String adapterTokenUseYn = (String) restOptionObject.get("adapterTokenUseYn"); if (StringUtils.isNotBlank(adapterTokenUseYn)) { // interface 에 설정된게 우선한다. useAdapterToken = StringUtils.equalsIgnoreCase(adapterTokenUseYn, "Y"); } + + String cnkUseYn = (String) restOptionObject.get("cnkUseYn"); + boolean chunked = false; + if (StringUtils.isNotBlank(cnkUseYn)) { + chunked = StringUtils.equalsIgnoreCase(cnkUseYn, "Y"); + } HttpClient mclient = this.client; String sendData = ""; @@ -210,27 +218,39 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp ////mclient.getParams().setContentCharset(vo.getEncode()); - JSONObject dataObject = null; + Object dataObject = null; Object httpHeader = null; - Object dataContent = null; + //Object dataContent = null; if (MessageType.JSON.equals(messageType)) { Object parsed = parseJsonGeneric(sendData); if(parsed instanceof JSONObject) { - dataObject = parseJson(sendData); - if (dataObject != null && StringUtils.isNotBlank(headerGroupName)) { - httpHeader = dataObject.get(headerGroupName); - dataObject.remove(headerGroupName); + JSONObject jsonObject = (JSONObject) parsed; + if (jsonObject != null && StringUtils.isNotBlank(headerGroupName)) { + httpHeader = jsonObject.get(headerGroupName); + jsonObject.remove(headerGroupName); } - dataContent = dataObject; - if (dataObject.containsKey("innerList")) { - JSONArray innerList = (JSONArray) dataObject.get("innerList"); - dataContent = innerList; + dataObject = jsonObject; + + if (jsonObject.containsKey("innerList")) { + JSONArray innerList = (JSONArray) jsonObject.get("innerList"); + dataObject = innerList; } + } else if(parsed instanceof JSONArray) { + // not support } + } else if (MessageType.XML.equals(messageType)) { + Document doc = XMLUtils.convertXmlDocument(sendData); + if (doc != null && StringUtils.isNotBlank(headerGroupName)) { + Element root = doc.getRootElement(); + Element httpHeaderElement = root.element(headerGroupName); + root.remove(httpHeaderElement); + httpHeader = httpHeaderElement; + } + dataObject = doc; } // if (MessageType.JSON.equals(messageType)) { @@ -350,6 +370,18 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + ") RequestHeader [" + method.getHeader("Authorization").getName() + ": " + method.getHeader("Authorization").getValue() + "]"); } } + + // 업무별 고정 token + String authToken = ""; + try { + Properties authProp = PropManager.getInstance().getProperties(AUTH_TOKEN); //Authorization + bizCode = vo.getAdapterGroupName().substring(1, 4); + authToken = authProp.getProperty(bizCode, ""); + } catch (Exception e) { + logger.debug("Property Group AUTH_TOKEN is not Exist !!"); + } + + logger.debug("authToken :::::::::::::::::::::::::::::::::::" + authToken); if(!StringUtils.isBlank(authToken)) { setAuthHeaders(method, authToken); @@ -383,8 +415,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp // assignPostBody(dataObject, contentType, vo.getEncode(), method); //assignPostBody(dataContent, contentType, vo.getEncode(), method); // jwhong commnet // KJBank API 추적정보를 Header에 제공. jwhong - String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); - assignPostBody(dataContent, contentType, vo.getEncode(), method, vo.getAdapterName(), auth, inboundToken, currentDate); +// String inboundToken= assignRequestKJHeaders(method, prop, tempProp ); + assignPostBody(dataObject, mimeType, charset, method, chunked); break; default: break; @@ -405,15 +437,16 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp try { byte[] responseMessage = null; - byte[] responseMessageOri = null; +// byte[] responseMessageOri = null; + String responseContentType = null; Header[] responseHeaders; if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { - if (dataObject != null) { + if (dataObject instanceof JSONObject) { logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = [" - + dataObject.toJSONString() + "]"); + + ((JSONObject)dataObject).toJSONString() + "]"); logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = " - + CommonLib.getDumpMessage(dataObject.toJSONString())); + + CommonLib.getDumpMessage(((JSONObject)dataObject).toJSONString())); } else { logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = [" + sendData + "]"); @@ -442,8 +475,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } // encrypt algorithm type 추출 from adapter property jwhong - Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong - String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong +// Properties properties = AdapterPropManager.getInstance().getProperties(vo.getAdapterName()); // jwhong +// String encryptAlgorithm = properties.getProperty("ENCRYPT_ALGORITHM"); // jwhong try { if (logger.isDebug()) { @@ -468,13 +501,22 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp //responseMessage = EntityUtils.toByteArray(response.getEntity()); // 역기서 responseMessage를 decryption 해야 하나 by jwhong - responseMessageOri = EntityUtils.toByteArray(response.getEntity()); - logger.debug("[responseMessageOri 바이트 배열 길이 ]" + responseMessageOri.length); + responseMessage = EntityUtils.toByteArray(response.getEntity()); + logger.debug("[responseMessage 바이트 배열 길이 ]" + responseMessage.length); - responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong +// responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong // 여기까지 responseHeaders = response.getHeaders(); + Header headerContentType = response.getHeader("Content-Type"); + if(headerContentType != null) { + responseContentType = headerContentType.getValue(); + } + + if(responseContentType == null) + responseContentType = ContentType.APPLICATION_JSON.getMimeType(); + + tempProp.setProperty("RES_CONTENT_TYPE", responseContentType); TxFileLogger.logTxFile(tempProp, new String(responseMessage, vo.getEncode()), "[OUT_RECV]"); @@ -508,16 +550,8 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp */ boolean needReissue = false; - Properties responseHeaderProp = assignRelayDataToInbound(tempProp, responseHeaders); String responseString = new String(responseMessage, vo.getEncode()); - Map map = new HashMap(); - tempProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); - map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, responseHeaderProp); - map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_MESSAGE, responseString); - map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_STATUS, status); - - if (isStatusInIgnore(status,errIgnore )) { // 이경우 정상으로 처리함 } else if (status >= 200 && status <= 207) { @@ -586,10 +620,35 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp + ") RETRY TOKEN = [" + newaccessToken + "]"); } - try (CloseableHttpResponse response = (CloseableHttpResponse) mclient.execute(method)) { + // executor 생성 (mclient, timeout은 기존 설정 그대로) + DeadlineAwareRetryExecutor executor = + new DeadlineAwareRetryExecutor((CloseableHttpClient)mclient, + vo.getConnectionTimeout(), + vo.getTimeout()); + + // Properties에서 RetryPolicy 로드 + RetryPolicy policy = RetryPolicy.from(prop); // 설정 로드 방식에 맞게 + + try (CloseableHttpResponse response = (CloseableHttpResponse) executor.execute(method, context, policy)) { +// try (CloseableHttpResponse response = (CloseableHttpResponse) mclient.execute(method)) { status = response.getCode(); responseMessage = EntityUtils.toByteArray(response.getEntity()); - // 여기서도 decryption 해야 할듯 하나.. by jwhong + logger.debug("[responseMessageOri 바이트 배열 길이 ]" + responseMessage.length); + +// responseMessage = doOutboundPostFilter(responseMessageOri, encryptAlgorithm, vo.getAdapterName(), accessToken); // jwhong + + responseHeaders = response.getHeaders(); + Header headerContentType = response.getHeader("Content-Type"); + if(headerContentType != null) { + responseContentType = headerContentType.getValue(); + } + + if(responseContentType == null) + responseContentType = ContentType.APPLICATION_JSON.getMimeType(); + + tempProp.setProperty("RES_CONTENT_TYPE", responseContentType); + + TxFileLogger.logTxFile(tempProp, new String(responseMessage, vo.getEncode()), "[OUT_RECV]"); if (logger.isDebug()) { logger.debug("[received status]" + status); @@ -633,12 +692,19 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp String jsonStr = new String(responseMessage, vo.getEncode()); if ( jsonStr.trim().startsWith("[") ) { - jsonStr = KJB_ROOTLESS_ARRAY + jsonStr + "}"; + jsonStr = DJB_ROOTLESS_ARRAY + jsonStr + "}"; responseMessage = jsonStr.getBytes(vo.getEncode()); } + + Properties responseHeaderProp = assignRelayDataToInbound(tempProp, responseHeaders); + Map map = new HashMap(); + tempProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, responseHeaderProp); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_MESSAGE, responseString); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_STATUS, status); - - return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), messageType, + + return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), responseContentType, relayResponseHeaderKeys, status, responseHeaderProp); } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 if (vo.getTraceLevel() >= 3) { @@ -705,57 +771,99 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp * @throws Exception */ @SuppressWarnings("unchecked") - private String assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName, - String encode, String messageType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { - if (!MessageType.JSON.equals(messageType) || StringUtils.isBlank(headerGroupName) + private Object assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName, + String encode, String responseContentType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { + String messageType = MessageType.JSON; + if (StringUtils.startsWith(responseContentType, ContentType.APPLICATION_XML.getMimeType())) { + logger.debug("Content-Type xml received."); + messageType = MessageType.XML; + } else if (StringUtils.startsWith(responseContentType, ContentType.APPLICATION_JSON.getMimeType())) { + logger.debug("Content-Type json received."); + messageType = MessageType.JSON; + } else { + messageType = "ETC"; + } + + // charset 추출, 없으면 파라미터 encdoe 이용 + ContentType oContentType = ContentType.parse(responseContentType); + Charset contentTypeCharset = oContentType.getCharset(); + String charset = encode; + if (contentTypeCharset != null) + charset = contentTypeCharset.displayName(); + + if (!StringUtils.equalsAny(messageType, MessageType.JSON, MessageType.XML) || StringUtils.isBlank(headerGroupName) || StringUtils.isBlank(relayHeaderKeys)) { - return new String(responseMessage, encode); + return new String(responseMessage, charset); } - JSONObject headerJson = new JSONObject(); - if (StringUtils.equalsIgnoreCase(relayHeaderKeys, "ALL")) { - for (Enumeration e = responseHeaderProp.keys(); e.hasMoreElements(); ) { - String key = (String)e.nextElement(); - headerJson.put(StringUtils.lowerCase(key), responseHeaderProp.getProperty(key)); - } - } else { - String[] relayKeyArr = org.springframework.util.StringUtils.tokenizeToStringArray(relayHeaderKeys, ","); - for (String key : relayKeyArr) { - String value = responseHeaderProp.getProperty(key); - if (StringUtils.isNotBlank(value)) { - headerJson.put(StringUtils.lowerCase(key), value); + if(StringUtils.equalsAny(messageType, MessageType.JSON)) { + JSONObject headerJson = new JSONObject(); + if (StringUtils.equalsIgnoreCase(relayHeaderKeys, "ALL")) { + for (Enumeration e = responseHeaderProp.keys(); e.hasMoreElements(); ) { + String key = (String)e.nextElement(); + headerJson.put(StringUtils.lowerCase(key), responseHeaderProp.getProperty(key)); + } + } else { + String[] relayKeyArr = org.springframework.util.StringUtils.tokenizeToStringArray(relayHeaderKeys, ","); + for (String key : relayKeyArr) { + String value = responseHeaderProp.getProperty(key); + if (StringUtils.isNotBlank(value)) { + headerJson.put(StringUtils.lowerCase(key), value); + } } } - } - - headerJson.put(HTTP_STATUS, String.valueOf(status)); - - if (headerJson.size() <= 0) { - return new String(responseMessage, encode); - } - - JSONObject message = null; - if (responseMessage == null || responseMessage.length == 0) { - message = new JSONObject(); - } else { - message = parseJson(new String(responseMessage, encode)); - if (message == null) { - message = new JSONObject(); - message.put("Malformed_Response_Message", new String(responseMessage, encode)); + + headerJson.put(HTTP_STATUS, String.valueOf(status)); + + if (headerJson.size() <= 0) { + return new String(responseMessage, charset); } + + JSONObject message = null; + if (responseMessage == null || responseMessage.length == 0) { + message = new JSONObject(); + } else { + message = parseJson(new String(responseMessage, charset)); + if (message == null) { + message = new JSONObject(); + message.put("Malformed_Response_Message", new String(responseMessage, charset)); + } + } + + if (StringUtils.isNotBlank(headerGroupName) && message != null) + message.put(headerGroupName, headerJson); + + return message; + } else if (StringUtils.equalsAny(messageType, MessageType.XML)) { + Document doc = XMLUtils.convertXmlDocument(new String(responseMessage, charset)); + Element root = doc.getRootElement(); + Element headerGroupEle = root.addElement(headerGroupName); + if (StringUtils.equalsIgnoreCase(relayHeaderKeys, "ALL")) { + for (Enumeration e = responseHeaderProp.keys(); e.hasMoreElements(); ) { + String key = (String)e.nextElement(); + headerGroupEle.addElement(StringUtils.lowerCase(key)).setText(responseHeaderProp.getProperty(key)); + } + } else { + String[] relayKeyArr = org.springframework.util.StringUtils.tokenizeToStringArray(relayHeaderKeys, ","); + for (String key : relayKeyArr) { + String value = responseHeaderProp.getProperty(key); + if (StringUtils.isNotBlank(value)) { + headerGroupEle.addElement(StringUtils.lowerCase(key)).setText(value); + } + } + } + return doc.asXML(); + } else { + return new String(responseMessage, charset); } - - if (StringUtils.isNotBlank(headerGroupName) && message != null) - message.put(headerGroupName, headerJson); - return message.toJSONString(); } - private void setAuthHeaders(HttpUriRequestBase method, String authorization) throws Exception { + protected void setAuthHeaders(HttpUriRequestBase method, String authorization) throws Exception { method.setHeader("Authorization", String.format("%s", authorization)); } - private void setAuthHeaders(HttpUriRequestBase method, OAuth2AccessTokenVO accessToken) throws Exception { + protected void setAuthHeaders(HttpUriRequestBase method, OAuth2AccessTokenVO accessToken) throws Exception { method.setHeader("Authorization", String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); } @@ -822,7 +930,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return false; } - private void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader, Properties prop) { + protected void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader, Properties prop) { if (httpHeader != null) { if (httpHeader instanceof JSONObject) { JSONObject jsonObject = (JSONObject) httpHeader; @@ -876,7 +984,7 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp } - private void assignFilterHeaders(HttpUriRequestBase method, Properties tempProp) { + protected void assignFilterHeaders(HttpUriRequestBase method, Properties tempProp) { try { Properties filterHeaders = (Properties)tempProp.get("FILTERHEADER"); if (filterHeaders != null){ @@ -969,45 +1077,64 @@ public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupp return map; } - @SuppressWarnings("deprecation") - private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method, String adapterName, String niceAuth, String inboundToken, Date currentDate) throws Exception { + protected String assignPostBody(Object eaiBody, String mimeType, String charset, HttpUriRequestBase method, + boolean chunked) throws Exception { if (eaiBody == null) { - return; + return ""; } if (eaiBody instanceof JSONObject) { JSONObject jsonObject = (JSONObject) eaiBody; - if( jsonObject.containsKey("KJB_ROOTLESS_ARRAY") ) { - eaiBody = jsonObject.get("KJB_ROOTLESS_ARRAY"); + if( jsonObject.containsKey("DJB_ROOTLESS_ARRAY") ) { + eaiBody = jsonObject.get("DJB_ROOTLESS_ARRAY"); } } - if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { + if (StringUtils.contains(mimeType, "application/x-www-form-urlencoded")) { + List params = new ArrayList<>(); if (eaiBody instanceof JSONObject) { - List params = new ArrayList<>(); JSONObject jsonObject = (JSONObject) eaiBody; - for (Object key : jsonObject.keySet()) { - - if( jsonObject.get(key) instanceof String ) { params.add(new BasicNameValuePair((String) key, (String) jsonObject.get(key))); - } - } - - UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, StandardCharsets.UTF_8); - method.setEntity(entity); + } else if (eaiBody instanceof Document) { + Document bodyDoc = (Document) eaiBody; + Element root = bodyDoc.getRootElement(); + List childrenEle = XMLUtils.getChilds(root); + for (Element child : childrenEle) { + params.add(new BasicNameValuePair(child.getName(), child.getText())); + } } + ContentType contentTypeObj = ContentType.create(mimeType, charset); + CustomUrlEncodedFormEntity entity = new CustomUrlEncodedFormEntity(params, contentTypeObj.getCharset(), chunked); + method.setEntity(entity); + return params.toString(); } else { - ContentType contentTypeObj = ContentType.create(contentType, charset); + ContentType contentTypeObj = ContentType.create(mimeType, charset); - String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken, currentDate); // jwhong - StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); // 요청 본문을 StringEntity 객체로 생성 - //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); + String body = ""; + if (eaiBody instanceof Document) { + body = ((Document)eaiBody).asXML(); + } else if(eaiBody instanceof JSONObject) { + body = ((JSONObject)eaiBody).toJSONString(); + } else { + body = eaiBody.toString(); + } + StringEntity entity = new StringEntity(body, contentTypeObj, chunked); // 요청에 본문 추가 method.setEntity(entity); + return body; +// ContentType contentTypeObj = ContentType.create(contentType, charset); +// +// String eaiBodyMessage = doOutboundPreFilter(eaiBody, adapterName, niceAuth, inboundToken, currentDate); // jwhong +// StringEntity entity = new StringEntity(eaiBodyMessage, contentTypeObj); +// // 요청 본문을 StringEntity 객체로 생성 +// //StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); +// +// // 요청에 본문 추가 +// method.setEntity(entity); } } diff --git a/src/main/java/com/eactive/eai/common/util/JSONUtils.java b/src/main/java/com/eactive/eai/common/util/JSONUtils.java new file mode 100644 index 0000000..8834488 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/JSONUtils.java @@ -0,0 +1,423 @@ +package com.eactive.eai.common.util; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.json.simple.parser.ParseException; + +public class JSONUtils { + + private JSONUtils() { + throw new IllegalStateException("Utility class"); + } + + public static JSONObject parseJson(Object message) { + if (message == null) { + return new JSONObject(); + } + if (message instanceof JSONObject) + return (JSONObject) message; + else if (message instanceof String) + try { + return (JSONObject) JSONValue.parseWithException((String) message); + } catch (ParseException e) { + throw new RuntimeException("json parsing exception : " + message, e); + } + else + throw new IllegalArgumentException("not support json type. " + message.getClass()); + } + + public static JSONArray parseJsonArray(Object message) { + if (message == null) { + return new JSONArray(); + } + if (message instanceof JSONArray) + return (JSONArray) message; + else if (message instanceof String) + try { + return (JSONArray) JSONValue.parseWithException((String) message); + } catch (ParseException e) { + throw new RuntimeException("json parsing exception : " + message, e); + } + else + throw new IllegalArgumentException("not support json type. " + message.getClass()); + } + + @SuppressWarnings("unchecked") + public static Set> getField(JSONObject json) { + return json.entrySet(); + } + + public static JSONObject getChildJson(JSONObject json, String childName) { + return (JSONObject)json.get(childName); + } + + @SuppressWarnings("unchecked") + public static void setChild(JSONObject json, String childName, Object value) { + json.put(childName, value); + } + + @SuppressWarnings("unchecked") + public static void setChildWithPath(JSONObject json, String path, Object value) { + String[] keys = path.split("\\."); + JSONObject current = json; + for(int i = 0; i < keys.length - 1; i++) { + current = (JSONObject) current.get(keys[i]); + if(current == null) + return; + } + current.put(keys[keys.length - 1], value); + } + + /** + * json array의 String 값의 ',' 구분자 + * @param jsonArray + * @return + */ + public static String toString(JSONArray jsonArray) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + for(Object ele : jsonArray ) { + if(ele instanceof String || ele instanceof Number) { + if(first) + first = false; + else + sb.append(","); + sb.append(ele); + } + else + throw new IllegalArgumentException("not support type - " + ele.getClass().getName()); + } + + return sb.toString(); + } + + public static String toString2(JSONArray jsonArray) { + String strJsonArray = jsonArray.toJSONString(); + strJsonArray = replace(strJsonArray); + + return strJsonArray; + } + + private static String replace(String strJsonArray) { + strJsonArray = StringUtils.replace(strJsonArray, "\"", ""); + strJsonArray = StringUtils.replace(strJsonArray, "[", ""); + strJsonArray = StringUtils.replace(strJsonArray, "]", ""); + return strJsonArray; + } + + public static JSONArray getJSONArray(JSONObject jsonObject, String path) { + if(jsonObject == null || path == null || path.isEmpty()) + return null; + + String[] keys = path.split("\\."); + JSONObject current = jsonObject; + for(int i = 0; i < keys.length - 1; i++) { + current = (JSONObject) current.get(keys[i]); + if(current == null) + return null; + } + + return (JSONArray)current.get(keys[keys.length - 1]); + } + + public static String getStringWithPath(JSONObject jsonObject, String path) { + if(jsonObject == null || path == null || path.isEmpty()) + return null; + + String[] keys = path.split("\\."); + JSONObject current = jsonObject; + for(int i = 0; i < keys.length - 1; i++) { + current = (JSONObject) current.get(keys[i]); + if(current == null) + return null; + } + + return (String)current.get(keys[keys.length - 1]); + } + + public static String removeStringWithPath(JSONObject jsonObject, String path) { + if(jsonObject == null || path == null || path.isEmpty()) + return null; + + String[] keys = path.split("\\."); + JSONObject current = jsonObject; + for(int i = 0; i < keys.length - 1; i++) { + current = (JSONObject) current.get(keys[i]); + if(current == null) + return null; + } + + return (String)current.remove(keys[keys.length - 1]); + } + + public static void removeEmptyWithPath(JSONObject jsonObject, String path) { + if(jsonObject == null || path == null || path.isEmpty()) + return; + + String[] keys = path.split("\\."); + JSONObject current = jsonObject; + for(int i = 0; i < keys.length - 1; i++) { + current = (JSONObject) current.get(keys[i]); + if(current == null) + return; + } + String value = (String) current.get(keys[keys.length - 1]); + if (StringUtils.isEmpty(value)) { + current.remove(keys[keys.length - 1]); + return; + } else { + return; + } + } + + protected static com.eactive.eai.common.util.Logger logger = com.eactive.eai.common.util.Logger + .getLogger(com.eactive.eai.common.util.Logger.LOGGER_DEFAULT); + + public static void removeEmptyWithPath2(JSONObject jsonObject, String path) { + if (jsonObject == null || path == null || path.isEmpty()) + return; + + String[] keys = path.split("\\."); + Object current = jsonObject; + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + if (current instanceof JSONObject) { + JSONObject currentObj = (JSONObject) current; + if (currentObj.get(key) == null) { + if (i == keys.length - 1) { + // 마지막 + currentObj.remove(key); + return; + } else { + logger.debug("경로를 찾을 수 없음. {} of {}", path, key); + return; + } + } else { + if (i == keys.length - 1) { + if (currentObj.get(key) instanceof String && StringUtils.isEmpty((String)currentObj.get(key))) { + // 마지막 + currentObj.remove(key); + return; + } else { + logger.debug("경로 값이 빈값이 아님. {} of {}'s value [{}]", path, key, currentObj.get(key)); + return; + } + } else { + current = currentObj.get(key); + } + } + } else if (current instanceof JSONArray) { + JSONArray currentArray = (JSONArray) current; + for (int j = 0; j < currentArray.size(); j++) { + Object arrayElement = currentArray.get(j); + if (arrayElement instanceof JSONObject) { + List lastPath = new ArrayList<>(); + for (int k = i; k < keys.length; k++) + lastPath.add(keys[k]); + + removeEmptyWithPath2((JSONObject) arrayElement, String.join(".", lastPath)); + } + } + } + } + } + + public static void removeZeroWithPath2(JSONObject jsonObject, String path) { + if (jsonObject == null || path == null || path.isEmpty()) + return; + + String[] keys = path.split("\\."); + Object current = jsonObject; + for (int i = 0; i < keys.length; i++) { + String key = keys[i]; + if (current instanceof JSONObject) { + JSONObject currentObj = (JSONObject) current; + if (currentObj.get(key) == null) { + if (i == keys.length - 1) { + logger.debug("경로 값이 null. {} of {}", path, key); + return; + } else { + logger.debug("경로를 찾을 수 없음. {} of {}", path, key); + return; + } + } else { + if (i == keys.length - 1) { + if (isZero(key, currentObj)) { + // 마지막 + currentObj.remove(key); + return; + } else { + logger.debug("경로 값이 0이 아님. {} of {}'s value [{}]", path, key, currentObj.get(key)); + return; + } + } else { + current = currentObj.get(key); + } + } + } else if (current instanceof JSONArray) { + JSONArray currentArray = (JSONArray) current; + for (int j = 0; j < currentArray.size(); j++) { + Object arrayElement = currentArray.get(j); + if (arrayElement instanceof JSONObject) { + List lastPath = new ArrayList<>(); + for (int k = i; k < keys.length; k++) + lastPath.add(keys[k]); + + removeZeroWithPath2((JSONObject) arrayElement, String.join(".", lastPath)); + } + } + } + } + } + + private static final Pattern numberPattern = Pattern.compile("[+-]?\\d*(\\.\\d+)?"); + + private static boolean isZero(String key, JSONObject currentObj) { + Object value = currentObj.get(key); + if (value instanceof Number && ((Number) value).doubleValue() == 0) { + return true; + } else if (value instanceof String && StringUtils.isNotEmpty((String) value) + && numberPattern.matcher((String) value).matches()) { + try { + return Double.parseDouble((String) value) == 0.0; + } catch (NumberFormatException e) { + logger.debug("숫자 형식이 아님. [{}]", value); + return false; + } + } + + return false; + } + + /** + * (문자열)'"aaa", "bbb", "ccc"' -> (json array)["aaa", "bbb", "ccc"] + * @param doublequotedSeperatedStr + * @return + */ + public static JSONArray createJSONArray(String doublequotedSeperatedStr) { + return (JSONArray) JSONValue.parse("[" + doublequotedSeperatedStr + "]"); + } + + @SuppressWarnings("unchecked") + public static JSONArray createJSONArray(String[] strArray ) { + JSONArray jsonArray = new JSONArray(); + for(String str : strArray) { + jsonArray.add(str); + } + return jsonArray; + } + + @SuppressWarnings("unchecked") + public static JSONArray createJSONArray(List strList ) { + JSONArray jsonArray = new JSONArray(); + for(String str : strList) { + jsonArray.add(str); + } + return jsonArray; + } + + @SuppressWarnings("unchecked") + public static JSONObject replaceSpacesWith(JSONObject json, String plus) { + if (json == null || plus == null || plus.isEmpty()) + return json; + + JSONObject result = new JSONObject(); + + for (Object key : json.keySet()) { + Object value = json.get(key); + + if(value instanceof String) { + result.put(key, ((String)value).replace(" ", plus)); + } else if (value instanceof JSONObject) { + result.put(key, replaceSpacesWith((JSONObject)value, plus)); + } else if ( value instanceof JSONArray) { + result.put(key, replaceSpacesInArrayWith((JSONArray)value, plus)); + } else { + result.put(key, value); + } + } + return result; + } + + @SuppressWarnings("unchecked") + public static JSONArray replaceSpacesInArrayWith(JSONArray array, String plus) { + JSONArray result = new JSONArray(); + for(int i =0; i < array.size(); i++) { + Object value = array.get(i); + + if(value instanceof String) { + result.add(((String)value).replace(" ", plus)); + } else if(value instanceof JSONObject) { + result.add(replaceSpacesWith((JSONObject)value, plus)); + } else if(value instanceof JSONArray) { + result.add(replaceSpacesInArrayWith((JSONArray)value, plus)); + } else { + result.add(value); + } + } + return result; + } + + @SuppressWarnings("unchecked") + public static JSONObject stripTrailingZeros(JSONObject json, String exceptionHeaderName) { + if (json == null) + return json; + + JSONObject result = new JSONObject(); + + for (Object key : json.keySet()) { + Object value = json.get(key); + + if(value instanceof Number) { + BigDecimal bd = new BigDecimal(value.toString()); + BigDecimal stripped = bd.stripTrailingZeros(); + if(stripped.scale() <= 0) + result.put(key, stripped.intValue()); + else + result.put(key, stripped); + + } else if (value instanceof JSONObject) { + result.put(key, stripTrailingZeros((JSONObject)value, exceptionHeaderName)); + } else if ( value instanceof JSONArray) { + result.put(key, stripTrailingZerosInArrayWith((JSONArray)value, exceptionHeaderName)); + } else { + result.put(key, value); + } + } + return result; + } + + @SuppressWarnings("unchecked") + public static JSONArray stripTrailingZerosInArrayWith(JSONArray array, String exceptionHeaderName) { + JSONArray result = new JSONArray(); + for(int i =0; i < array.size(); i++) { + Object value = array.get(i); + + if(value instanceof Number) { + BigDecimal bd = new BigDecimal(value.toString()); + BigDecimal stripped = bd.stripTrailingZeros(); + if(stripped.scale() <= 0) + result.add(stripped.intValue()); + else + result.add(stripped); + } else if(value instanceof JSONObject) { + result.add(stripTrailingZeros((JSONObject)value, exceptionHeaderName)); + } else if(value instanceof JSONArray) { + result.add(stripTrailingZerosInArrayWith((JSONArray)value, exceptionHeaderName)); + } else { + result.add(value); + } + } + return result; + } +} diff --git a/src/main/java/com/eactive/eai/common/util/XMLUtils.java b/src/main/java/com/eactive/eai/common/util/XMLUtils.java new file mode 100644 index 0000000..3240dec --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/XMLUtils.java @@ -0,0 +1,93 @@ +package com.eactive.eai.common.util; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.dom4j.Document; +import org.dom4j.DocumentException; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +public class XMLUtils { + + private XMLUtils() { + throw new IllegalStateException("Utility class"); + } + + public static Document convertXmlDocument(Object message) throws DocumentException { + if (message == null) + return DocumentHelper.createDocument(); + else if (message instanceof Document) + return (Document) message; + else if (message instanceof String) { + SAXReader builder = new SAXReader(); + return builder.read(new StringReader((String)message)); + } else + throw new IllegalArgumentException("not support xml type. " + message.getClass()); + } + + public static List getChilds(Element parent) { + List elements = new ArrayList<>(); + Iterator iterator = parent.elementIterator(); + while(iterator.hasNext()) { + Element child = iterator.next(); + elements.add(child); + elements.addAll(getChilds(child)); + } + return elements; + } + + public static List getChildsLevel1(Element parent) { + List elements = new ArrayList<>(); + Iterator iterator = parent.elementIterator(); + while(iterator.hasNext()) { + Element child = iterator.next(); + elements.add(child); + } + return elements; + } + + @SuppressWarnings("unchecked") + public static Object elementToJSONObject(Element element) { + JSONObject json = new JSONObject(); + + List children = element.elements(); + if(children.isEmpty()) { + return element.getText(); + } + for(Element child : children) { + String childName = child.getName(); + if(json.containsKey(childName)) { + Object existing = json.get(childName); + if(existing instanceof JSONArray) { + ((JSONArray) existing).add(elementToJSONObject(child)); + } else { + JSONArray list = new JSONArray(); + list.add(existing); + list.add(elementToJSONObject(child)); + json.put(childName, list); + } + } else { + json.put(childName, elementToJSONObject(child)); + } + } + + return json; + } + + public static Element getElement(Element parent, String path) { + String[] keys = path.split("\\."); + Element current = parent; + for(String key : keys) { + current = current.element(key); + } + return (Element) current.elements().get(0); + } + + +}