This commit is contained in:
Rinjae
2025-09-05 18:57:45 +09:00
commit aacc1a389e
1229 changed files with 167963 additions and 0 deletions
@@ -0,0 +1,588 @@
package com.eactive.eai.common.util;
import com.eactive.eai.common.EAIKeys;
import com.eactive.eai.common.message.MessageType;
import com.eactive.eai.common.monitor.EAIServiceMonitor;
import com.eactive.eai.transformer.message.ISO8583Message;
import com.eactive.eai.transformer.message.ISO8583MessageFactory;
import com.eactive.eai.transformer.util.IConv;
import com.eactive.eai.transformer.util.ISO8583DumpUtil;
import com.ext.eai.common.stdmessage.STDMessageErrorKeys;
import com.jayway.jsonpath.JsonPath;
import com.solab.iso8583.IsoMessage;
import org.apache.commons.lang3.StringUtils;
import org.apache.tools.ant.filters.StringInputStream;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import java.io.BufferedInputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public final class MessageUtil {
static Logger logger = LoggerFactory.getLogger(MessageUtil.class);
private MessageUtil() {
}
// ASCII Bytes에서 특정길이의 값을 추출하는 Method
public static String getAscBytes(byte[] message, int startPos, int length) {
if (message == null || message.length < startPos) {
return null;
}
byte[] outBytes = new byte[length];
System.arraycopy(message, startPos, outBytes, 0, length);
return new String(outBytes);
}
// EBCDIC Bytes에서 특정길이의 값을 추출하는 Method
public static String getEbcdicBytes(byte[] message, int startPos, int length) {
if (message == null || message.length < startPos) {
return null;
}
byte[] outBytes = new byte[length];
System.arraycopy(message, startPos, outBytes, 0, length);
String key = null;
try {
key = IConv.ebcdicToASCII(outBytes);
} catch (Exception e) {
return null;
}
return key;
}
// XML 에서 특정TAG name 의 값을 추출하는 Method
public static String getXmlFld(String xmlMessage, String tagName) {
try {
String sTag = "<" + tagName + ">";
String eTag = "</" + tagName + ">";
int s_idx = xmlMessage.indexOf(sTag);
int e_idx = xmlMessage.indexOf(eTag);
if (s_idx == -1 || e_idx == -1) {
return "";
} else {
return xmlMessage.substring(s_idx + sTag.length(), e_idx);
}
} catch (Exception e) {
return "";
}
}
public static String getJSONValue(Object message, String key) {
try {
if (message instanceof JSONObject) {
JSONObject json = (JSONObject) message;
Iterator i = json.keySet().iterator();
while (i.hasNext()) {
String keys = (String) i.next();
Object obj = json.get(keys);
if (obj instanceof String) {
if (keys.equals(key)) {
return (String) json.get(key);
}
} else {
String value = getJSONValue(obj, key);
if (!"".equals(value))
return value;
}
}
} else if (message instanceof JSONArray) {
JSONArray arr = (JSONArray) message;
for (int i = 0; i < arr.size(); i++) {
JSONObject json = (JSONObject) arr.get(i);
if (json.containsKey(key)) {
return (String) ((JSONObject) message).get(key);
} else {
String value = getJSONValue(json, key);
if (!"".equals(value))
return value;
}
}
}
return "";
} catch (Exception e) {
return "";
}
}
public static String getISO8583Fld(IsoMessage isoMessage, int index) {
// Field는 Max 128까지만 정의
if (index <= 128) {
return isoMessage.getObjectValue(index);
} else {
return "";
}
}
public static IsoMessage parseIsoMessage(byte[] message, String messageType) throws Exception {
// ISO8583Message iso8583Message = null;
// if (StringUtils.equals(messageType, EAITable.ISO8583_TYPE)) {
// iso8583Message = new ISO8583Message();
// } else if (StringUtils.equals(messageType, EAITable.ISO8583_H2H_TYPE)) {
// iso8583Message = new ISO8583H2HMessage();
// }
ISO8583Message iso8583Message = ISO8583MessageFactory.create(messageType);
if (iso8583Message == null) {
throw new Exception("Cannot create ISO8583Message, messageType=" + messageType);
}
// MessageFactory<IsoMessage> mf = iso8583Message.createMessageFactory();
//
// // Message Type으로 parseMap을 등록해야 MessageFactory에서 사용가능
// byte[] _type = new byte[4];
// System.arraycopy(message, 0, _type, 0, 4);
//
// HashMap<Integer, FieldParseInfo> parseMap = iso8583Message.getFullSpecMap(mf.getCharacterEncoding());
//
// mf.setParseMap(Integer.parseInt(new String(_type), 16), parseMap);
//
// IsoMessage m = mf.parseMessage(message, 0);
IsoMessage m = iso8583Message.parseIsoMessage(message, 0);
if (logger.isDebugEnabled())
logger.debug("Parsed Key ISO Message: \n" + dumpIsoMessage(m));
return m;
}
public static String dumpIsoMessage(IsoMessage isoMessage) {
return dumpIsoMessage(isoMessage, null);
}
public static String dumpIsoMessage(IsoMessage isoMessage, ISO8583Message iso8583Message) {
return ISO8583DumpUtil.dumpIsoMessage(isoMessage, iso8583Message);
}
// EAI헤더의 응답코드가 오류인지 판별하는 기능
public static boolean checkRspErrCd(String rspErrCd) {
if (rspErrCd == null) {
return false;
} else if (rspErrCd.startsWith("RE") || rspErrCd.startsWith("RF")) {
return false;
} else {
return true;
}
}
// Message내의 특정 byte를 다른 byte로 치환
public static byte[] removeBytes(byte[] source, byte removeByte, byte replace) {
byte[] seBytes = new byte[source.length];
int sPos = 0;
for (int i = 0; i < source.length; i++) {
if (source[i] == removeByte) {
seBytes[sPos] = replace;
sPos++;
} else {
seBytes[sPos] = source[i];
sPos++;
}
}
byte[] newBytes = new byte[sPos];
System.arraycopy(seBytes, 0, newBytes, 0, newBytes.length);
return newBytes;
}
// 업무오류메시지응답에 대한 XML을 생성
public static byte[] makeErrMsgXml(String errMsg) {
if (errMsg == null) {
errMsg = "";
}
StringBuffer sb = new StringBuffer();
sb.append("<ERRMSG>");
sb.append(errMsg);
sb.append("</ERRMSG>");
return sb.toString().getBytes();
}
public static String makeErrMsgXmlString(String errMsg) {
if (errMsg == null) {
errMsg = "";
}
StringBuffer sb = new StringBuffer();
sb.append("<ERRMSG>");
sb.append(errMsg);
sb.append("</ERRMSG>");
return sb.toString();
}
public static byte[] makeErrMsgXml(byte[] errMsg) {
if (errMsg == null)
errMsg = new byte[0];
return makeErrMsgXml(new String(errMsg));
}
// public static byte[] makeStandardErrMsgJson(String errCode, String errMsg, String encode) {
// if (errCode == null) {
// errCode = "";
// } else {
// errCode = getTobeCode(errCode);
// }
// STDErrorCodeVO vo = STDErrorCodeManager.getInstance().getSTDErrorCode(errCode);
//
// String errCodeCtnt = ""; // 에러내용
// String actCtnt = ""; // 조치내용
//
// if (vo != null) {
// errCodeCtnt = vo.getIsdErrCasCt();
// if (vo.getActnCode() != null) {
// actCtnt = vo.getActnCode().getActnMsgCtnt();
// }
// }
//
// StringBuffer sb = new StringBuffer();
// sb.append("{\"messageHeader\":{");
// sb.append(" \"messageList\" : ");
// sb.append(" [");
// sb.append(" {\"MSG_CODE\":\"" + errCode + "\",\"MSG_CNTT\":\"" + errCodeCtnt + "\",\"addMessageList\": ");
// sb.append(" [");
// sb.append(" {\"ADTN_MSG_CODE\":\"\",\"ADTN_MSG_CNTT\":\"\"} ");
// sb.append(" ] ");
// sb.append(" }");
// sb.append(" ]");
// sb.append(" }");
// sb.append("}");
//
// try {
// return sb.toString().getBytes(encode);
// } catch (UnsupportedEncodingException e) {
// return sb.toString().getBytes();
// }
// }
public static byte[] makeStandardErrMsgXml(byte[] errCode) {
if (errCode == null)
errCode = new byte[0];
return makeErrMsgXml(new String(errCode));
}
public static String makeStandardErrMsgXmlString(String errCode) {
return makeErrMsgXmlString(errCode);
}
public static String replaceMsgXmlString(String Msg) {
if (Msg == null) {
Msg = "";
}
Msg = Msg.replaceAll("<", "[");
Msg = Msg.replaceAll(">", "]");
return Msg;
}
public static byte[] replaceMsgXml(String Msg) {
if (Msg == null) {
Msg = "";
}
Msg = Msg.replaceAll("<", "[");
Msg = Msg.replaceAll(">", "]");
return Msg.getBytes();
}
public static byte[] replaceMsgXml(byte[] Msg) {
if (Msg == null)
Msg = new byte[0];
return replaceMsgXml(new String(Msg));
}
// 요청,응답 유무를 판단하는 메소드
public static String transClassify(String tmpTrans) {
String result = "0";
if (tmpTrans.equals(EAIKeys.TR_REQ) || tmpTrans.equals(EAIKeys.TR_RE_REQ)
|| tmpTrans.equals(EAIKeys.TR_CANCEL_REQ)) {
// 요청 거래
result = "0";
} else if (tmpTrans.equals(EAIKeys.TR_RES) || tmpTrans.equals(EAIKeys.TR_CANCEL_RES)) {
// 응답거래
result = "1";
}
return result;
}
public static String removeXMLHeader(String xmlMsg) {
if (xmlMsg == null) {
return "";
} else {
xmlMsg = xmlMsg.trim();
}
int sPos = xmlMsg.indexOf("<?");
int ePos = xmlMsg.indexOf("?>");
// 중간에 있는 경우 - CDATA 의 내용
if (sPos == 0 && ePos > -1) {
xmlMsg = xmlMsg.substring(ePos + 2);
}
return xmlMsg;
}
public static byte[] removeXMLHeader(byte[] xmlMsg) {
return removeXMLHeader(new String(xmlMsg)).getBytes();
}
public static String addXMLHeader(String encode, String xmlMsg) {
if (xmlMsg != null) {
xmlMsg = "<?xml version=\"1.0\" encoding=\"" + encode + "\" ?>" + xmlMsg;
}
return xmlMsg;
}
public static byte[] addXMLHeader(String encode, byte[] xmlMsg) throws UnsupportedEncodingException {
return addXMLHeader(encode, new String(xmlMsg, encode)).getBytes(encode);
}
public static String removeXMLRootItem(String xmlString, String rootItemName) {
String prefix = "<" + rootItemName + ">";
String suffix = "</" + rootItemName + ">";
int s_idx = xmlString.indexOf(prefix);
int e_idx = xmlString.indexOf(suffix);
if (s_idx == -1 || e_idx == -1) {
return xmlString;
} else {
return xmlString.substring(s_idx + prefix.length(), e_idx);
}
}
public static boolean isBizDataEmpty(Object bizData) {
boolean isEmpty = false;
if (bizData == null) {
isEmpty = true;
} else {
if (bizData instanceof byte[]) {
if (((byte[]) bizData).length == 0) {
isEmpty = true;
}
} else if (bizData instanceof String) {
if (((String) bizData).length() == 0) {
isEmpty = true;
}
}
}
return isEmpty;
}
public static String getTobeCode(String oldErrCode){
if ("".equals(oldErrCode)){
return STDMessageErrorKeys.SYSTEM_ERROR_CODE_VALUE;
}
if ("RECEAIOWP010".equals(oldErrCode)){ //책임자 승인 타임아웃
return STDMessageErrorKeys.APPROVE_ERROR_CODE_VALUE;
}
if ("RECEAIFBF010".equals(oldErrCode)){ //책임자 승인자가 존재하지 않는 오류
return STDMessageErrorKeys.APPROVE_NOT_FOUND_ERROR_CODE_VALUE;
}
if ("RECEAIIRP020,RECEAIIRP120,RECEAIIRP110".indexOf(oldErrCode) >= 0 ){ //유효값 오류
return STDMessageErrorKeys.VALID_VALUE_ERROR_CODE_VALUE;
}
if ("RECEAIAHA020".equals(oldErrCode)) { // 미로그인 에러
return STDMessageErrorKeys.NOT_LOGIN_ERROR_CODE_VALUE;
}
if ("RECEAIAHA021".equals(oldErrCode)) { // 중복로그인 에러
return STDMessageErrorKeys.DUP_LOGIN_ERROR_CODE_VALUE;
}
if ("RECEAIAHA022".equals(oldErrCode)) { // UUID가 같지 않은 에러
return STDMessageErrorKeys.UUID_MISMATCH_ERROR_CODE_VALUE;
}
if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러
return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE;
}
if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode)){ //TIMEOUT일경우
return STDMessageErrorKeys.TIMEOUT_ERROR_CODE_VALUE;
}else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우
return STDMessageErrorKeys.BIZ_ERROR_CODE_VALUE;
}else{
return STDMessageErrorKeys.SYSTEM_ERROR_CODE_VALUE;
}
}
public static String getTobeMessage(String oldErrCode){
if ("".equals(oldErrCode)){
return STDMessageErrorKeys.SYSTEM_ERROR_MSG_VALUE;
}
if ("RECEAIOWP010".equals(oldErrCode)){//책임자승인 타임아웃
return STDMessageErrorKeys.APPROVE_ERROR_MSG_VALUE;
}
if ("RECEAIFBF010".equals(oldErrCode)){ //책임자 승인자가 존재하지 않는 오류
return STDMessageErrorKeys.APPROVE_NOT_FOUND_ERROR_MSG_VALUE;
}
if ("RECEAIIRP020,RECEAIIRP120,RECEAIIRP110".indexOf(oldErrCode) >= 0 ){//유효값 오류
return STDMessageErrorKeys.VALID_VALUE_ERROR_MSG_VALUE;
}
if ("RECEAIAHA020".equals(oldErrCode)) { // 미로그인 에러
return STDMessageErrorKeys.NOT_LOGIN_ERROR_MSG_VALUE;
}
if ("RECEAIAHA021".equals(oldErrCode)) { // 중복로그인 에러
return STDMessageErrorKeys.DUP_LOGIN_ERROR_MSG_VALUE;
}
if ("RECEAIAHA022".equals(oldErrCode)) { // UUID가 같지 않은 에러
return STDMessageErrorKeys.UUID_MISMATCH_ERROR_MSG_VALUE;
}
if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러
return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE;
}
if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode) ){ //TIMEOUT일경우
return STDMessageErrorKeys.TIMEOUT_ERROR_MSG_VALUE;
}else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우
return STDMessageErrorKeys.BIZ_ERROR_MSG_VALUE;
}else{
return STDMessageErrorKeys.SYSTEM_ERROR_MSG_VALUE;
}
}
// TODO json tunning 요소 다시 확인해봐야됨(불필요한 파싱)
public static String addJsonRootItem(String jsonString, String rootItemName) {
JSONObject value = (JSONObject) JSONValue.parse(jsonString);
JSONObject root = new JSONObject();
root.put(rootItemName, value);
return root.toJSONString();
}
// TODO json tunning 요소 다시 확인해봐야됨(불필요한 파싱)
public static String removeJsonRootItem(String jsonString, String rootItemName) {
JSONObject value = (JSONObject) JSONValue.parse(jsonString);
JSONObject sub = (JSONObject) value.get(rootItemName);
return sub.toJSONString();
}
public static String toAdapterTypeString(Object data, String charset) throws Exception {
if (data instanceof String) {
return (String) data;
} else if (data instanceof byte[]) {
String encode = StringUtils.defaultIfBlank(charset, Charset.defaultCharset().name());
return new String((byte[]) data, encode);
} else {
throw new Exception("unsupported object - " + data.getClass());
}
}
public static boolean isBytesMessage(String messageType) {
return StringUtils.equalsAny(messageType, MessageType.ASC, MessageType.EBC);
}
/**
* 표준전문에 내외부구분이 없는 사이트를 고려하여 서비스정보(he01)에 internalExternalDvcd 추가 <br>
* 표준전문의 값을 우선으로 한다(없으면 서비스정보(he01)의 값으로 설정)
*/
public static String getInExDivision(String mapperValue, String eaiSvcValue) {
if (StringUtils.isNotBlank(mapperValue)) {
return mapperValue;
} else {
return eaiSvcValue;
}
}
public static String makeErrorMessageByMessageType(String msgType, String msgCharset, String code, String msg,
String errorFormat) {
if (StringUtils.equals(msgType, MessageType.JSON)) {
return makeJsonErrorMessage(code, msg, errorFormat);
} else if (StringUtils.equals(msgType, MessageType.XML)) {
return makeXmlErrorMessage(code, msg, msgCharset, errorFormat);
} else {
return "[errCd]" + code + "[/errCd]" + "[errMsg]" + msg + "[/errMsg]";
}
}
public static String makeJsonErrorMessage(String code, String msg) {
return makeJsonErrorMessage(code, msg, null);
}
public static String makeXmlErrorMessage(String code, String msg, String charset) {
return makeXmlErrorMessage(code, msg, charset, null);
}
public static String makeJsonErrorMessage(String code, String msg, String errorFormat) {
if (StringUtils.isNotBlank(errorFormat)) {
try {
return String.format(errorFormat, code, JSONValue.escape(msg));
} catch (Exception e) {
logger.error(e.getMessage());
}
}
return String.format("{\"error\":\"%s\",\"error_description\":\"%s\"}", code, JSONValue.escape(msg));
}
public static String makeXmlErrorMessage(String code, String msg, String charset, String errorFormat) {
if (StringUtils.isNotBlank(errorFormat)) {
try {
return String.format(errorFormat, StringUtils.defaultIfBlank(charset, "UTF-8"), code, msg);
} catch (Exception e) {
logger.error(e.getMessage());
}
}
return String.format(
"<?xml version=\"1.0\" encoding=\"%s\"?><error>%s</error><error_description>%s</error_description>",
StringUtils.defaultIfBlank(charset, "UTF-8"), code, msg);
}
/**
* XPath를 이용하여 XML 메시지에서 값을 추출
* @param xmlMessage XML 메시지
* @param xpath XPath 표현식
* @return 추출된 값 (실패 시 빈 문자열)
*/
public static String getXmlFldByXPath(String xmlMessage, String xpath) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new BufferedInputStream(new StringInputStream(xmlMessage)));
XPath xPath = XPathFactory.newInstance().newXPath();
String value = (String) xPath.evaluate(xpath, document, XPathConstants.STRING);
return value != null ? value.trim() : "";
} catch (Exception e) {
logger.error("XPath 처리 중 오류 발생: " + e.getMessage());
return "";
}
}
/**
* JSONPath를 이용하여 JSON 메시지에서 값을 추출
* @param json JSON 객체
* @param jsonPath JSONPath 표현식
* @return 추출된 값 (실패 시 빈 문자열)
*/
public static String getJSONValueByPath(Object json, String jsonPath) {
try {
if(json == null || jsonPath == null) return "";
JsonPath path = JsonPath.compile(jsonPath);
Object result = path.read(json);
if(result == null) return "";
// 결과가 기본 타입인 경우
if(result instanceof String || result instanceof Number || result instanceof Boolean) {
return String.valueOf(result);
}
// JSON 객체나 배열인 경우
else if(result instanceof JSONObject || result instanceof JSONArray) {
return result.toString();
}
return "";
} catch (Exception e) {
logger.error("JSONPath 처리 중 오류 발생: " + e.getMessage());
return "";
}
}
}