feat: DJErp 어댑터 URL 매핑을 properties 외부화 및 동적 등록으로 변경
- 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 <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,12 @@
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
">
|
||||
|
||||
<context:component-scan base-package="com.eactive.eai" />
|
||||
<context:component-scan base-package="com.eactive.eai">
|
||||
<context:exclude-filter type="annotation"
|
||||
expression="org.springframework.stereotype.Controller"/>
|
||||
<context:exclude-filter type="annotation"
|
||||
expression="org.springframework.web.bind.annotation.RestController"/>
|
||||
</context:component-scan>
|
||||
|
||||
<bean id="entityManagerFactory" primary="true"
|
||||
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
|
||||
|
||||
@@ -17,6 +17,10 @@
|
||||
http://www.springframework.org/schema/mvc
|
||||
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||
|
||||
<context:property-placeholder
|
||||
location="/WEB-INF/properties/*.${eai.systemmode}.properties"
|
||||
ignore-unresolvable="true" />
|
||||
|
||||
<context:component-scan
|
||||
base-package="com.eactive.eai.authserver" />
|
||||
<context:component-scan
|
||||
@@ -31,4 +35,8 @@
|
||||
<mvc:interceptors>
|
||||
<bean class="com.eactive.eai.adapter.interceptor.HttpResponseLoggingInterceptor"/>
|
||||
</mvc:interceptors>
|
||||
|
||||
<bean class="com.eactive.eai.adapter.controller.DJErpAdapterMappingRegistrar">
|
||||
<property name="paths" value="${dj.erp.adapter.paths}" />
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -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).*$}/**
|
||||
|
||||
@@ -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).*$}/**
|
||||
|
||||
|
||||
@@ -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).*$}/**
|
||||
|
||||
@@ -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<ContextRefreshedEvent> {
|
||||
|
||||
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<String, RequestMappingHandlerMapping> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<String> callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
|
||||
throws Exception {
|
||||
// /ONLWeb/api/v1/public/getUserInfo.svc
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user