From 840136b8cab52fe45d64b226938f87793a74d53e Mon Sep 17 00:00:00 2001 From: curry772 Date: Thu, 30 Apr 2026 16:54:23 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20DJErp=20=EC=96=B4=EB=8C=91=ED=84=B0=20U?= =?UTF-8?q?RL=20=EB=A7=A4=ED=95=91=EC=9D=84=20properties=20=EC=99=B8?= =?UTF-8?q?=EB=B6=80=ED=99=94=20=EB=B0=8F=20=EB=8F=99=EC=A0=81=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - DJErpAdapterMappingRegistrar 신규 추가: ContextRefreshedEvent 시점에 dj.erp.adapter.paths(쉼표 구분)를 읽어 callApi 메서드를 동적으로 등록 OAuth2의 FrameworkEndpointHandlerMapping과 충돌하지 않도록 exact type 비교로 선택 - DJErpApiAdapterController: 하드코딩된 @RequestMapping 제거 (Registrar에 위임) - DJErpApiAdapterService: @Primary 추가 (Root/Servlet Context 중복 스캔 시 충돌 방지) - applicationContext-jpa.xml: Root Context에서 @Controller/@RestController 제외 필터 추가 - authserver-servlet.xml: context:property-placeholder 및 DJErpAdapterMappingRegistrar 빈 선언 추가 - env.D/T/P.properties: dj.erp.adapter.paths 속성 추가 Co-Authored-By: Claude Sonnet 4.6 --- WebContent/WEB-INF/applicationContext-jpa.xml | 7 +- WebContent/WEB-INF/authserver-servlet.xml | 8 ++ .../WEB-INF/properties/env.D.properties | 3 + .../WEB-INF/properties/env.P.properties | 3 + .../WEB-INF/properties/env.T.properties | 3 + .../DJErpAdapterMappingRegistrar.java | 91 +++++++++++++++++++ .../controller/DJErpApiAdapterController.java | 2 - .../service/DJErpApiAdapterService.java | 71 ++++++++------- 8 files changed, 154 insertions(+), 34 deletions(-) create mode 100644 src/main/java/com/eactive/eai/adapter/controller/DJErpAdapterMappingRegistrar.java diff --git a/WebContent/WEB-INF/applicationContext-jpa.xml b/WebContent/WEB-INF/applicationContext-jpa.xml index 8da5bda..e0b19cd 100644 --- a/WebContent/WEB-INF/applicationContext-jpa.xml +++ b/WebContent/WEB-INF/applicationContext-jpa.xml @@ -20,7 +20,12 @@ http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd "> - + + + + diff --git a/WebContent/WEB-INF/authserver-servlet.xml b/WebContent/WEB-INF/authserver-servlet.xml index 58f4c31..f301418 100644 --- a/WebContent/WEB-INF/authserver-servlet.xml +++ b/WebContent/WEB-INF/authserver-servlet.xml @@ -17,6 +17,10 @@ http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> + + + + + + \ No newline at end of file diff --git a/WebContent/WEB-INF/properties/env.D.properties b/WebContent/WEB-INF/properties/env.D.properties index 0bd3db5..181b796 100644 --- a/WebContent/WEB-INF/properties/env.D.properties +++ b/WebContent/WEB-INF/properties/env.D.properties @@ -20,3 +20,6 @@ eai.systemmode=D eai.systemtype=API eai.tableowner=AGWADM eai.server.extractor=[0,2],[0,2],[-2] + +# DJErp API Adapter request mapping paths (comma-separated) +dj.erp.adapter.paths=/dj/{path:^(?!oauth).*$},/dj/{path:^(?!oauth).*$}/** diff --git a/WebContent/WEB-INF/properties/env.P.properties b/WebContent/WEB-INF/properties/env.P.properties index d4b10f6..c721a3c 100644 --- a/WebContent/WEB-INF/properties/env.P.properties +++ b/WebContent/WEB-INF/properties/env.P.properties @@ -12,3 +12,6 @@ hibernate.dialect=org.hibernate.dialect.Oracle12cDialect eai.systemtype=API eai.server.extractor=[0,2],[0,2],[-2] +# DJErp API Adapter request mapping paths (comma-separated) +dj.erp.adapter.paths=/dj/{path:^(?!oauth).*$},/dj/{path:^(?!oauth).*$}/** + diff --git a/WebContent/WEB-INF/properties/env.T.properties b/WebContent/WEB-INF/properties/env.T.properties index dcc97b8..993b717 100644 --- a/WebContent/WEB-INF/properties/env.T.properties +++ b/WebContent/WEB-INF/properties/env.T.properties @@ -18,3 +18,6 @@ eai.systemmode=D eai.systemtype=API eai.tableowner=dapigw eai.server.extractor=[0,2],[0,2],[-2] + +# DJErp API Adapter request mapping paths (comma-separated) +dj.erp.adapter.paths=/dj/{path:^(?!oauth).*$},/dj/{path:^(?!oauth).*$}/** diff --git a/src/main/java/com/eactive/eai/adapter/controller/DJErpAdapterMappingRegistrar.java b/src/main/java/com/eactive/eai/adapter/controller/DJErpAdapterMappingRegistrar.java new file mode 100644 index 0000000..3dedffc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/controller/DJErpAdapterMappingRegistrar.java @@ -0,0 +1,91 @@ +package com.eactive.eai.adapter.controller; + +import java.lang.reflect.Method; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import com.eactive.eai.common.util.Logger; + +/** + * properties 파일의 dj.erp.adapter.paths 값을 읽어 + * DJErpApiAdapterController 의 callApi 메서드를 동적으로 URL에 등록한다. + * + * 경로는 쉼표로 구분하여 여러 개를 지정할 수 있다. + * 예) /dj/{path:^(?!oauth).*$},/dj/{path:^(?!oauth).*$}/** + */ +public class DJErpAdapterMappingRegistrar implements ApplicationListener { + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + @Autowired + private DJErpApiAdapterController djErpApiAdapterController; + + private String paths; + + private boolean registered = false; + + public void setPaths(String paths) { + this.paths = paths; + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + if (registered) { + return; + } + + if (StringUtils.isBlank(paths)) { + logger.warn("DJErpAdapterMappingRegistrar] dj.erp.adapter.paths 가 설정되지 않았습니다."); + return; + } + + // OAuth2의 FrameworkEndpointHandlerMapping 을 제외하고 MVC 기본 매핑만 선택 + Map candidates = + event.getApplicationContext().getBeansOfType(RequestMappingHandlerMapping.class); + + RequestMappingHandlerMapping requestMappingHandlerMapping = candidates.values().stream() + .filter(m -> m.getClass() == RequestMappingHandlerMapping.class) + .findFirst() + .orElse(null); + + if (requestMappingHandlerMapping == null) { + logger.warn("DJErpAdapterMappingRegistrar] RequestMappingHandlerMapping 을 찾을 수 없습니다."); + return; + } + + try { + Method callApi = DJErpApiAdapterController.class.getDeclaredMethod( + "callApi", HttpServletRequest.class, HttpServletResponse.class); + + RequestMappingInfo.BuilderConfiguration options = new RequestMappingInfo.BuilderConfiguration(); + options.setPatternParser(requestMappingHandlerMapping.getPatternParser()); + + for (String path : paths.split(",")) { + path = path.trim(); + if (path.isEmpty()) { + continue; + } + RequestMappingInfo mappingInfo = RequestMappingInfo + .paths(path) + .options(options) + .build(); + requestMappingHandlerMapping.registerMapping(mappingInfo, djErpApiAdapterController, callApi); + logger.warn("DJErpAdapterMappingRegistrar] 등록 완료: " + path); + } + + registered = true; + + } catch (NoSuchMethodException e) { + logger.error("DJErpAdapterMappingRegistrar] callApi 메서드를 찾을 수 없습니다.", e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/controller/DJErpApiAdapterController.java b/src/main/java/com/eactive/eai/adapter/controller/DJErpApiAdapterController.java index d575301..7bc09a2 100644 --- a/src/main/java/com/eactive/eai/adapter/controller/DJErpApiAdapterController.java +++ b/src/main/java/com/eactive/eai/adapter/controller/DJErpApiAdapterController.java @@ -16,7 +16,6 @@ import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.AntPathMatcher; -import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.eactive.eai.adapter.AdapterGroupVO; @@ -57,7 +56,6 @@ public class DJErpApiAdapterController implements HttpAdapterServiceKey { * @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer * endpoints) */ - @RequestMapping(value = { "/dj/{path:^(?!oauth).*$}", "/dj/{path:^(?!oauth).*$}/**" }) public ResponseEntity callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception { // /ONLWeb/api/v1/public/getUserInfo.svc diff --git a/src/main/java/com/eactive/eai/adapter/service/DJErpApiAdapterService.java b/src/main/java/com/eactive/eai/adapter/service/DJErpApiAdapterService.java index 2fde9ef..8c2b4b6 100644 --- a/src/main/java/com/eactive/eai/adapter/service/DJErpApiAdapterService.java +++ b/src/main/java/com/eactive/eai/adapter/service/DJErpApiAdapterService.java @@ -1,5 +1,40 @@ package com.eactive.eai.adapter.service; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.mina.common.ByteBuffer; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.json.simple.parser.JSONParser; +import org.springframework.context.annotation.Primary; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.stereotype.Service; +import org.springframework.util.AntPathMatcher; + import com.eactive.eai.adapter.AdapterGroupVO; import com.eactive.eai.adapter.AdapterPropManager; import com.eactive.eai.adapter.AdapterVO; @@ -8,6 +43,9 @@ import com.eactive.eai.adapter.http.HttpMemoryLogger; import com.eactive.eai.adapter.http.HttpMethodType; import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthFilter; +//for encrypt/decrypt jwhong +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.common.context.ElinkTransactionContext; import com.eactive.eai.common.exception.ExceptionUtil; import com.eactive.eai.common.message.MessageType; import com.eactive.eai.common.util.CommonLib; @@ -19,41 +57,12 @@ import com.eactive.eai.message.StandardMessageUtil; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.time.StopWatch; -import org.apache.mina.common.ByteBuffer; -import org.json.simple.JSONObject; -import org.json.simple.JSONValue; -import org.json.simple.parser.JSONParser; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.stereotype.Service; -import org.springframework.util.AntPathMatcher; - -import javax.servlet.ServletInputStream; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.net.URLDecoder; -import java.util.*; - -//for encrypt/decrypt jwhong -import com.eactive.eai.authserver.service.OAuth2Manager; import com.kjbank.encrypt.exchange.crypto.AES256Cipher; -import com.kjbank.encrypt.exchange.crypto.AESCipher; import com.kjbank.encrypt.exchange.crypto.AES256GCMCipher; -import java.nio.charset.StandardCharsets; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import org.springframework.security.oauth2.provider.ClientDetails; +import com.kjbank.encrypt.exchange.crypto.AESCipher; import com.nimbusds.jwt.SignedJWT; -import com.eactive.eai.common.context.ElinkTransactionContext; - +@Primary @Service public class DJErpApiAdapterService extends HttpAdapterServiceSupport { static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER);