Merge branch 'jenkins_with_weblogic' of ssh://git@192.168.240.178:18081/eapim/eapim-online.git into jenkins_with_weblogic
This commit is contained in:
@@ -138,11 +138,12 @@ public class ApiAdapterController implements HttpAdapterServiceKey {
|
||||
// if (RESPONSE_TYPE_ASYNC.equals(responseType)) { // table의 값이 ASYNC 로 들어가 있는데 response_type_async는 ASYN 로 되어 있어 아래처럼 비교함 jwhong 2025
|
||||
if ("ASYNC".equals(responseType)) {
|
||||
//responseEntity = ResponseEntity.ok("dummy"); // comment by jwhong
|
||||
servletResponse.addHeader("traceId", responseData); // uuid를 response header에
|
||||
//servletResponse.addHeader("traceId", responseData); // uuid를 response header에
|
||||
servletResponse.addHeader("traceId", transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID)); // uuid를 response header에
|
||||
int httpStatus = servletResponse.getStatus();
|
||||
if (httpStatus == 200) {
|
||||
// 업체별 aync response message 가 다르다.
|
||||
String asyncMsgStyle = httpProp.getProperty("ASYNC_RTNMSG_TYPE", "").toUpperCase();
|
||||
String asyncMsgStyle = httpProp.getProperty("ASYNC_RTNMSG_TYPE", "");
|
||||
String responseBody ="";
|
||||
if (asyncMsgStyle == null || asyncMsgStyle.trim().isEmpty()) {
|
||||
responseBody = makeResponseBodyMsg();
|
||||
@@ -158,6 +159,8 @@ public class ApiAdapterController implements HttpAdapterServiceKey {
|
||||
// responseEntity = ResponseEntity.ok().contentType(mediaType).body(responseData);
|
||||
// 버즈빌 포인트 적립 처리하기 위하여 정상응답이더라도 응답코드(apiRsltCd) 값이 200이 아닌 경우 처리를 위하여 수정
|
||||
// Filter에서 설정한 response status값을 responseEntity 생성시 적용 modify by lwk 2025.03.24
|
||||
|
||||
servletResponse.addHeader("traceId", transactionProp.getProperty(TransactionContextKeys.TRANSACTION_UUID)); // uuid를 response header에
|
||||
int httpStatus = servletResponse.getStatus();
|
||||
if (httpStatus != 200) {
|
||||
responseEntity = ResponseEntity.status(httpStatus).contentType(mediaType).body(responseData);
|
||||
|
||||
@@ -1,85 +1,150 @@
|
||||
package com.eactive.eai.adapter.controller;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletInputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.json.simple.JSONArray;
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import com.eactive.eai.adapter.AdapterGroupVO;
|
||||
import com.eactive.eai.adapter.AdapterManager;
|
||||
import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager;
|
||||
import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterUri;
|
||||
import com.eactive.eai.common.stdmessage.STDMessageManager;
|
||||
import com.eactive.eai.common.stdmessage.STDMsgInfoAddOnVO;
|
||||
|
||||
|
||||
public class ApiRequestBodyFilter extends OncePerRequestFilter {
|
||||
|
||||
static final String KJB_ROOTLESS_ARRAY = "{ \"KJB_ROOTLESS_ARRAY\" : ";
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
|
||||
// 1. 필터 대상
|
||||
|
||||
String encoding = getInboundGroupAdapterEncoding(request);
|
||||
|
||||
if (!isTarget(request)) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 요청 전문 읽기
|
||||
String body = readBody(request);
|
||||
if (body == null || body.isEmpty()) {
|
||||
//원본 바디를 byte[]로 읽기 (개행 포함 그대로) 왜? 뒤에 필터에서 HMAC값 계산할수도 있어서 변조되면 안됨. 개행문자도 그대로 가야함.
|
||||
byte[] rawBody = readBodyAsBytes(request);
|
||||
|
||||
if (rawBody == null || rawBody.length == 0) {
|
||||
filterChain.doFilter(request, response);
|
||||
return;
|
||||
}
|
||||
|
||||
String modifiedBody = body;
|
||||
byte[] finalBody = rawBody;
|
||||
|
||||
try {
|
||||
Object json = JSONValue.parse(body);
|
||||
|
||||
// 3. 예제: ROOTLESS ARRAY 보정
|
||||
String bodyStr = new String(rawBody, encoding);
|
||||
Object json = JSONValue.parse(bodyStr);
|
||||
|
||||
if (json instanceof JSONArray) {
|
||||
JSONObject wrap = new JSONObject();
|
||||
wrap.put("KJB_ROOTLESS_ARRAY", json);
|
||||
modifiedBody = wrap.toJSONString();
|
||||
bodyStr = KJB_ROOTLESS_ARRAY + bodyStr + "}";
|
||||
finalBody = bodyStr.getBytes(encoding);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 변조 실패 → 원본 유지
|
||||
modifiedBody = body;
|
||||
// JSON 파싱 실패 시 원본 유지
|
||||
finalBody = rawBody;
|
||||
}
|
||||
|
||||
byte[] bytes = modifiedBody.getBytes(request.getCharacterEncoding() != null ? request.getCharacterEncoding() : Charset.defaultCharset().name() );
|
||||
|
||||
// 5. Wrapper로 재주입
|
||||
// Wrapper로 재주입
|
||||
HttpServletRequest wrapped =
|
||||
new CachedBodyHttpServletRequest(request, bytes);
|
||||
new CachedBodyHttpServletRequest(request, finalBody);
|
||||
|
||||
filterChain.doFilter(wrapped, response);
|
||||
}
|
||||
|
||||
private boolean isTarget(HttpServletRequest request) {
|
||||
String uri = request.getRequestURI();
|
||||
|
||||
|
||||
return ("POST".equals(request.getMethod()) || "PUT".equals(request.getMethod()))
|
||||
&& (uri.startsWith("/api") || uri.startsWith("/mapi") ) && !uri.startsWith("/mapi/oauth2/token");
|
||||
&& (uri.startsWith("/api") || uri.startsWith("/mapi"))
|
||||
&& !uri.startsWith("/mapi/oauth2/token");
|
||||
}
|
||||
|
||||
private String readBody(HttpServletRequest request) throws IOException {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try (BufferedReader br = request.getReader()) {
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
sb.append(line);
|
||||
|
||||
private byte[] readBodyAsBytes(HttpServletRequest request) throws IOException {
|
||||
try (ServletInputStream is = request.getInputStream();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int len;
|
||||
while ((len = is.read(buffer)) != -1) {
|
||||
baos.write(buffer, 0, len);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private String getInboundGroupAdapterEncoding(HttpServletRequest request) {
|
||||
String apiUri = request.getRequestURI();
|
||||
apiUri = StringUtils.removeStart(apiUri, request.getContextPath());
|
||||
apiUri = StringUtils.removeEnd(apiUri, "/");
|
||||
|
||||
String methodAndUri = request.getMethod() + "|" + apiUri;
|
||||
String adapterGrpName;
|
||||
HttpDynamicInAdapterUri adptUri = null;
|
||||
|
||||
try {
|
||||
STDMessageManager manager = STDMessageManager.getInstance();
|
||||
STDMsgInfoAddOnVO stdMsgInfo = manager.getStdMsgInfoAddOn(methodAndUri);
|
||||
adapterGrpName = stdMsgInfo.gAdapterGroupName();
|
||||
|
||||
adptUri = findAdptUri(apiUri, HttpDynamicInAdapterManager.getInstance(), adapterGrpName);
|
||||
} catch (Exception e) {
|
||||
adptUri = null;
|
||||
}
|
||||
|
||||
AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO( adptUri.getAdptGrpName());
|
||||
|
||||
if( adapterGroupVO == null ) {
|
||||
return Charset.defaultCharset().name();
|
||||
}
|
||||
|
||||
return StringUtils.isNotBlank(adapterGroupVO.getMessageEncode()) ? adapterGroupVO.getMessageEncode() : Charset.defaultCharset().name(); //서버 jvm file.encoding 확인, file.encoding=utf-8 주고있음.
|
||||
|
||||
}
|
||||
|
||||
private HttpDynamicInAdapterUri findAdptUri(String apiUri, HttpDynamicInAdapterManager manager, String adapterGrpName) throws Exception {
|
||||
if (StringUtils.isBlank(apiUri)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
HttpDynamicInAdapterUri adptUri = manager.getAdptUri(apiUri);
|
||||
if (adptUri != null) {
|
||||
if (adptUri.getAdptGrpName().equals(adapterGrpName)) {
|
||||
return adptUri;
|
||||
}
|
||||
}
|
||||
|
||||
apiUri = StringUtils.substringBeforeLast(apiUri, "/");
|
||||
if (apiUri.length() < 4) { // /api
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
|
||||
|
||||
@RestControllerAdvice
|
||||
public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
|
||||
|
||||
static final String KJB_ROOTLESS_ARRAY = "{ \"KJB_ROOTLESS_ARRAY\" : ";
|
||||
|
||||
@Override
|
||||
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||
@@ -34,6 +36,7 @@ public class ApiResponseAdvice implements ResponseBodyAdvice<Object> {
|
||||
}
|
||||
|
||||
String removeRootlessArrayKeyFormResponseBody(String body) {
|
||||
|
||||
try {
|
||||
Object root = JSONValue.parse(body);
|
||||
|
||||
|
||||
@@ -239,8 +239,12 @@ public class ApiAdapterService extends HttpAdapterServiceSupport {
|
||||
|
||||
if (paramValue == null) { // parameter가 없는 경우때문에 처리
|
||||
paramValue = "";
|
||||
}
|
||||
else { // jwhong decrypt
|
||||
}
|
||||
// 순수한 Body값을 저장을 위해 위치 변경.
|
||||
transactionProp.put(INBOUND_REQUEST_MESSAGE, paramValue);
|
||||
|
||||
// paramValue가 null이 아닌 빈문자열(""," ")인 경우에 대비하여 조건 수정.
|
||||
if (StringUtils.isNotBlank(paramValue)) { // jwhong decrypt
|
||||
paramValue = doPreDecryption(paramValue, transactionProp, request);
|
||||
}
|
||||
|
||||
@@ -296,7 +300,8 @@ public class ApiAdapterService extends HttpAdapterServiceSupport {
|
||||
message = "";
|
||||
}
|
||||
|
||||
transactionProp.put(INBOUND_REQUEST_MESSAGE, message);
|
||||
// 위치변경 : 가공되지 않은 Body값을 저장하기 위하여 위쪽으로 이동.
|
||||
// transactionProp.put(INBOUND_REQUEST_MESSAGE, message);
|
||||
// 로컬 서비스 호출 ,encoding 처리 추가
|
||||
String result = (String) service(adptGrpName, adptName, message, transactionProp, request, response);
|
||||
|
||||
|
||||
+8
@@ -14,6 +14,7 @@ public class AsyncReponseFilter implements HttpClientAdapterFilter, HttpAdapterS
|
||||
|
||||
public static final String X_TRACE_ID = "partnerTraceId";
|
||||
public static final String TRACE_ID = "traceId";
|
||||
|
||||
|
||||
@Override
|
||||
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
|
||||
@@ -21,6 +22,7 @@ public class AsyncReponseFilter implements HttpClientAdapterFilter, HttpAdapterS
|
||||
|
||||
logger.debug("AsyncReponseFilter] PreFilter Processing Start!!");
|
||||
String traceId = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID, "");
|
||||
String xloanToken = tempProp.getProperty(TransactionContextKeys.X_LOAN_TOKEN, "");
|
||||
|
||||
Properties filterHeaders = (Properties) tempProp.get("FILTERHEADER");
|
||||
if (filterHeaders == null) {
|
||||
@@ -35,7 +37,13 @@ public class AsyncReponseFilter implements HttpClientAdapterFilter, HttpAdapterS
|
||||
filterHeaders.put(X_TRACE_ID, inboundHeaderMap.get(X_TRACE_ID));
|
||||
logger.debug("AsyncReponseFilter] Processing Key ["+X_TRACE_ID+"], value ["+inboundHeaderMap.get(X_TRACE_ID)+"]");
|
||||
}
|
||||
|
||||
if (inboundHeaderMap.containsKey(TransactionContextKeys.X_LOAN_TOKEN)||inboundHeaderMap.containsKey(TransactionContextKeys.X_LOAN_TOKEN.toLowerCase())) {
|
||||
filterHeaders.put(TransactionContextKeys.X_LOAN_TOKEN, inboundHeaderMap.get(TransactionContextKeys.X_LOAN_TOKEN));
|
||||
logger.debug("AsyncReponseFilter] Processing Key ["+TransactionContextKeys.X_LOAN_TOKEN+"], value ["+inboundHeaderMap.get(TransactionContextKeys.X_LOAN_TOKEN)+"]");
|
||||
}
|
||||
}
|
||||
|
||||
filterHeaders.setProperty(TRACE_ID, traceId);
|
||||
logger.debug("AsyncReponseFilter] Processing Key ["+TRACE_ID+"], value ["+traceId+"]");
|
||||
|
||||
|
||||
+3
@@ -24,6 +24,9 @@ public class HttpClient5AdapterFilterFactory {
|
||||
case SIMPLEFRAMEWORK:
|
||||
filter = new SimpleFrameworkFilter();
|
||||
break;
|
||||
case SIMPLEFRAMEWORKBODY:
|
||||
filter = new SimpleframeworkBodyFilter();
|
||||
break;
|
||||
case JBOBP:
|
||||
filter = new JBOBPFilter();
|
||||
break;
|
||||
|
||||
+1
@@ -2,6 +2,7 @@ package com.eactive.eai.custom.kjb.adapter.http.client.filter;
|
||||
|
||||
public enum HttpClient5AdapterFilterType {
|
||||
SIMPLEFRAMEWORK,
|
||||
SIMPLEFRAMEWORKBODY,
|
||||
JBOBP,
|
||||
KFTCFACE,
|
||||
KFTCP2P,
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.eactive.eai.custom.kjb.adapter.http.client.filter;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.json.simple.JSONObject;
|
||||
import org.json.simple.JSONValue;
|
||||
|
||||
import com.eactive.eai.common.TransactionContextKeys;
|
||||
|
||||
public class SimpleframeworkBodyFilter extends SimpleFrameworkFilter {
|
||||
@Override
|
||||
public Object doPreFilter(String adptGrpName, String adptName, Properties prop, Object message, Properties tempProp)
|
||||
throws Exception {
|
||||
|
||||
Object returnMessage = super.doPreFilter(adptGrpName, adptName, prop, message, tempProp);
|
||||
|
||||
JSONObject bizJsonStr = null;
|
||||
|
||||
if ( returnMessage instanceof String ) {
|
||||
bizJsonStr = (JSONObject) JSONValue.parse( (String)returnMessage);
|
||||
bizJsonStr.put("GUID", tempProp.get(TransactionContextKeys.GUID));
|
||||
}
|
||||
|
||||
return bizJsonStr != null ? bizJsonStr.toJSONString() : returnMessage;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user