09.10 변경분 반영
This commit is contained in:
@@ -111,27 +111,27 @@ public class DBInboudSqlAdapterListener extends AdapterListenerSupport {
|
||||
}
|
||||
// TODO : Application Test Code.
|
||||
// in real system, remove this block
|
||||
else {
|
||||
prop = new Properties();
|
||||
|
||||
prop.setProperty(DBAdapterKeys.RUN_CRONEXP, "0/10 * * * * ?");
|
||||
prop.setProperty(DBAdapterKeys.RUN_INTVL, "1000");
|
||||
prop.setProperty(DBAdapterKeys.RUN_RETRY, "N");
|
||||
prop.setProperty(DBAdapterKeys.RUN_RETRYCNT, "2");
|
||||
prop.setProperty(DBAdapterKeys.RUN_RETRYINTVL, "5000");
|
||||
prop.setProperty(DBAdapterKeys.RUN_MSGTYPE, "JSON");
|
||||
|
||||
prop.setProperty(DBAdapterKeys.DRIVER, "oracle.jdbc.driver.OracleDriver");
|
||||
prop.setProperty(DBAdapterKeys.URL, "jdbc:oracle:thin:@localhost:1521:XE");
|
||||
prop.setProperty(DBAdapterKeys.USER, "eai");
|
||||
prop.setProperty(DBAdapterKeys.PVAL, "eaiadmin");
|
||||
// prop.setProperty(DBAdapterKeys.SELECT, "select * from APIJOBSCHE");
|
||||
prop.setProperty(DBAdapterKeys.SELECT, "select * from EAIINF01 where RFLAG IS null ORDER BY UNID");
|
||||
prop.setProperty(DBAdapterKeys.UPDATE, "update EAIINF01 set RFLAG = 'C' where UNID = '%UNID%' ");
|
||||
|
||||
debug("Start Scheduler");
|
||||
adapterName = "_EAI_IN_DBQ_SyC";
|
||||
}
|
||||
// else {
|
||||
// prop = new Properties();
|
||||
//
|
||||
// prop.setProperty(DBAdapterKeys.RUN_CRONEXP, "0/10 * * * * ?");
|
||||
// prop.setProperty(DBAdapterKeys.RUN_INTVL, "1000");
|
||||
// prop.setProperty(DBAdapterKeys.RUN_RETRY, "N");
|
||||
// prop.setProperty(DBAdapterKeys.RUN_RETRYCNT, "2");
|
||||
// prop.setProperty(DBAdapterKeys.RUN_RETRYINTVL, "5000");
|
||||
// prop.setProperty(DBAdapterKeys.RUN_MSGTYPE, "JSON");
|
||||
//
|
||||
// prop.setProperty(DBAdapterKeys.DRIVER, "oracle.jdbc.driver.OracleDriver");
|
||||
// prop.setProperty(DBAdapterKeys.URL, "jdbc:oracle:thin:@localhost:1521:XE");
|
||||
// prop.setProperty(DBAdapterKeys.USER, "eai");
|
||||
// prop.setProperty(DBAdapterKeys.PVAL, "eaiadmin");
|
||||
//// prop.setProperty(DBAdapterKeys.SELECT, "select * from APIJOBSCHE");
|
||||
// prop.setProperty(DBAdapterKeys.SELECT, "select * from EAIINF01 where RFLAG IS null ORDER BY UNID");
|
||||
// prop.setProperty(DBAdapterKeys.UPDATE, "update EAIINF01 set RFLAG = 'C' where UNID = '%UNID%' ");
|
||||
//
|
||||
// debug("Start Scheduler");
|
||||
// adapterName = "_EAI_IN_DBQ_SyC";
|
||||
// }
|
||||
// TODO : Application Test Code End.
|
||||
|
||||
prop.setProperty(DBAdapterKeys.ADAPTER_NAME, adapterName);
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.eactive.eai.common.util.Logger;
|
||||
import com.eactive.eai.data.entity.onl.authoutbound.OutboundOAuthCredential;
|
||||
import com.eactive.eai.data.entity.onl.lifecycle.LifeCycle;
|
||||
import com.eactive.eai.data.entity.onl.property.PropGroup;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -60,7 +61,9 @@ public class OutboundOAuthCredentialDao extends BaseDAO {
|
||||
|
||||
public void decryptClientSecret(OutboundOAuthCredentialVo vo) throws Exception {
|
||||
String clientSecret = vo.getClientSecret();
|
||||
String decrypted = Seed.decrypt(clientSecret);
|
||||
vo.setClientSecret(decrypted);
|
||||
if (StringUtils.isNotBlank(clientSecret)) {
|
||||
String decrypted = Seed.decrypt(clientSecret);
|
||||
vo.setClientSecret(decrypted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.eactive.eai.authoutbound;
|
||||
|
||||
import lombok.Data;
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.mapstruct.Mapping;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -29,4 +30,10 @@ public class OutboundOAuthCredentialVo {
|
||||
private LocalDateTime createdAt;
|
||||
|
||||
private LocalDateTime updatedAt;
|
||||
|
||||
private String contentType;
|
||||
|
||||
private String bodyJson;
|
||||
|
||||
private String headerJson;
|
||||
}
|
||||
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
|
||||
package com.eactive.eai.authoutbound.client.impl;
|
||||
|
||||
import com.eactive.eai.adapter.AdapterGroupVO;
|
||||
import com.eactive.eai.adapter.AdapterManager;
|
||||
import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey;
|
||||
import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory;
|
||||
import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo;
|
||||
import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB;
|
||||
import com.eactive.eai.common.util.Logger;
|
||||
import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager;
|
||||
import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO;
|
||||
import com.eactive.eai.util.TestModeChecker;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.openbanking.eai.common.token.AccessTokenVO;
|
||||
import com.openbanking.eai.common.token.OAuth2AccessTokenVO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||
import org.apache.hc.client5.http.config.RequestConfig;
|
||||
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
|
||||
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
|
||||
import org.apache.hc.client5.http.ssl.NoopHostnameVerifier;
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.ssl.TrustAllStrategy;
|
||||
import org.apache.hc.core5.http.HttpEntity;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.NameValuePair;
|
||||
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||
import org.apache.hc.core5.http.message.BasicNameValuePair;
|
||||
import org.apache.hc.core5.ssl.SSLContextBuilder;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.springframework.security.web.util.UrlUtils;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.UnrecoverableKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24
|
||||
* retry 로직 제거 : 요청 3. 주의사항
|
||||
*
|
||||
* @author :
|
||||
* @version : v 1.0.0
|
||||
* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java
|
||||
* @since :
|
||||
*
|
||||
*/
|
||||
public class HttpClientAccessTokenServiceWithDefault implements HttpClientAccessTokenServiceByDB {
|
||||
|
||||
public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
|
||||
|
||||
private static boolean testMode = TestModeChecker.isTestMode();
|
||||
|
||||
/**
|
||||
* 1. 기능 : 토큰 발급에 사용 2. 처리 개요 : - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. 3. 주의사항
|
||||
*
|
||||
* @param adapterProp Http Adapter 속성 정보
|
||||
* @return 반환 된 AccessTokenVO
|
||||
* @exception Exception 수동 시스템 간 통신 중 발생
|
||||
**/
|
||||
public AccessTokenVO execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo)
|
||||
throws Exception {
|
||||
AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(name);
|
||||
String adapterUrl = adapterProp.getProperty("URL");
|
||||
String encode = gvo.getMessageEncode();
|
||||
String timeoutTemp = adapterProp.getProperty("HTTP_TIME_OUT");
|
||||
if (StringUtils.isBlank(timeoutTemp)) {
|
||||
timeoutTemp = "30000";
|
||||
}
|
||||
String connectionTimeoutTemp = adapterProp.getProperty("CONNECTION_TIMEOUT");
|
||||
if (StringUtils.isBlank(connectionTimeoutTemp)) {
|
||||
connectionTimeoutTemp = "30000";
|
||||
}
|
||||
|
||||
int timeout = Integer.parseInt(timeoutTemp);
|
||||
int connectionTimeout = Integer.parseInt(connectionTimeoutTemp);
|
||||
long currentTime = System.currentTimeMillis();
|
||||
|
||||
String uri = oAuthCredentialVo.getUrl();
|
||||
|
||||
if (!UrlUtils.isAbsoluteUrl(uri)) {
|
||||
uri = appendPath(adapterUrl, uri);
|
||||
}
|
||||
String contentType = oAuthCredentialVo.getContentType();
|
||||
|
||||
if(StringUtils.isBlank(contentType)){
|
||||
contentType="application/x-www-form-urlencoded";
|
||||
if(logger.isDebug()){
|
||||
logger.debug("Content-Type not specified. Using default: application/x-www-form-urlencoded");
|
||||
}
|
||||
}
|
||||
|
||||
Charset charset;
|
||||
if (StringUtils.isNotBlank(encode)) {
|
||||
charset = Charset.forName(encode);
|
||||
} else {
|
||||
charset = Charset.defaultCharset();
|
||||
encode = charset.toString();
|
||||
}
|
||||
|
||||
boolean useForwardProxy = StringUtils.equalsIgnoreCase(adapterProp.getProperty("FORWARD_PROXY_USE_YN"), "Y");
|
||||
String forwardProxyUrl = adapterProp.getProperty("FORWARD_PROXY_URL");
|
||||
|
||||
if(logger.isDebug()) {
|
||||
logger.debug(
|
||||
"contentType:{}, uri:{}, charset:{}, transactionTimeout:{}, connectionTimeout:{}, useForwardProxy:{}, forwardProxyUrl:{}",
|
||||
contentType, uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl);
|
||||
}
|
||||
|
||||
|
||||
// mTLS config with default connection parameters
|
||||
boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS),
|
||||
"Y");
|
||||
AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroup(name);
|
||||
String clientId = adapterGroup.getClientId();
|
||||
|
||||
if (logger.isInfo()) {
|
||||
logger.info("MTLS adapterGroupName. : {}, useMtls. : {}, clientId : {}", name, useMtls, clientId);
|
||||
}
|
||||
|
||||
int maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS;
|
||||
int maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST;
|
||||
|
||||
HttpOutTlsInfoVO mtlsInfo = null;
|
||||
SSLContext sslContext = null;
|
||||
PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create();
|
||||
PoolingHttpClientConnectionManager connectionManager = null;
|
||||
|
||||
try {
|
||||
if (useMtls) {
|
||||
HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance();
|
||||
if (StringUtils.isNotEmpty(clientId)) {
|
||||
mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId);
|
||||
}
|
||||
}
|
||||
|
||||
if (useMtls && mtlsInfo != null) {
|
||||
String storeType = mtlsInfo.getStoreType();
|
||||
String keyStoreInfo = mtlsInfo.getKeystoreInfo();
|
||||
String keyStorePassword = mtlsInfo.getKeystorePassword();
|
||||
String trustStoreInfo = mtlsInfo.getTruststoreInfo();
|
||||
String trustStorePassword = mtlsInfo.getTruststorePassword();
|
||||
|
||||
String[] tlsVersions = null;
|
||||
String[] cipherSuites = null;
|
||||
|
||||
if (StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword)) {
|
||||
throw new Exception("mTLS keyStore config error");
|
||||
}
|
||||
|
||||
boolean skipTrust = false;
|
||||
if (StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword)) {
|
||||
if (logger.isWarn())
|
||||
logger.warn("Skip trustStore validation adapterGroupName : " + name);
|
||||
skipTrust = true;
|
||||
}
|
||||
|
||||
sslContext = HttpClient5SSLContextFactory.createMTLSContextFromContent(storeType, keyStoreInfo,
|
||||
keyStorePassword, trustStoreInfo, trustStorePassword, skipTrust, tlsVersions, cipherSuites);
|
||||
|
||||
SSLConnectionSocketFactory sslSocketFactory = null;
|
||||
if (testMode) {
|
||||
sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
|
||||
} else {
|
||||
sslSocketFactory = new SSLConnectionSocketFactory(sslContext);
|
||||
}
|
||||
cmBuilder.setSSLSocketFactory(sslSocketFactory);
|
||||
} else {
|
||||
sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build();
|
||||
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
|
||||
cmBuilder.setSSLSocketFactory(csf);
|
||||
}
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException
|
||||
| IOException | UnrecoverableKeyException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
connectionManager = cmBuilder.build();
|
||||
connectionManager.setMaxTotal(maxTotalConnections);
|
||||
connectionManager.setDefaultMaxPerRoute(maxHostConnections);
|
||||
|
||||
|
||||
|
||||
try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) {
|
||||
HttpPost httpPost = new HttpPost(uri);
|
||||
|
||||
//HTTP HEADER Setting
|
||||
httpPost.setHeader("Content-Type", contentType+"; charset=" + encode);
|
||||
// 화면에서 추가 한 bodyJson을 Map으로 변환 후 합치기
|
||||
String addHeaderJson = oAuthCredentialVo.getHeaderJson();
|
||||
if (addHeaderJson != null && !addHeaderJson.isEmpty()) {
|
||||
ObjectMapper headerJsonMapper = new ObjectMapper();
|
||||
Map<String, Object> addHeaderMap = headerJsonMapper.readValue(addHeaderJson, Map.class);
|
||||
for (Map.Entry<String, Object> entry : addHeaderMap.entrySet()) {
|
||||
httpPost.setHeader(entry.getKey(), entry.getValue().toString());
|
||||
}
|
||||
}
|
||||
|
||||
//HTTP BODY Setting
|
||||
// content Type 에 따라 전달 방법 분기
|
||||
if(contentType.equals("application/json")){
|
||||
|
||||
//json body 개별 컬럼 setting
|
||||
Map<String, Object> jsonMap = new HashMap<>();
|
||||
jsonMap.put("client_id", oAuthCredentialVo.getClientId());
|
||||
jsonMap.put("client_secret", oAuthCredentialVo.getClientSecret());
|
||||
jsonMap.put("scope", oAuthCredentialVo.getScope());
|
||||
jsonMap.put("grant_type", oAuthCredentialVo.getGrantType());
|
||||
|
||||
// 화면에서 추가 한 bodyJson을 Map으로 변환 후 합치기
|
||||
String addBodyJson = oAuthCredentialVo.getBodyJson();
|
||||
if (addBodyJson != null && !addBodyJson.isEmpty()) {
|
||||
ObjectMapper bodyJsonMapper = new ObjectMapper();
|
||||
Map<String, Object> addBodyMap = bodyJsonMapper.readValue(addBodyJson, Map.class);
|
||||
jsonMap.putAll(addBodyMap);
|
||||
}
|
||||
ObjectMapper objMapper = new ObjectMapper();
|
||||
objMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY); //빈값이 아닐 때만 param에 담기
|
||||
String authJsonBody = objMapper.writeValueAsString(jsonMap);
|
||||
|
||||
httpPost.setEntity(new StringEntity(authJsonBody));
|
||||
|
||||
} else if (contentType.equals("application/x-www-form-urlencoded")){
|
||||
|
||||
//빈값이 아닐 때만 param에 담기
|
||||
List<NameValuePair> formParams = new ArrayList<>();
|
||||
addIfNotNull(formParams, "client_id", oAuthCredentialVo.getClientId());
|
||||
addIfNotNull(formParams, "client_secret", oAuthCredentialVo.getClientSecret());
|
||||
addIfNotNull(formParams, "scope", oAuthCredentialVo.getScope());
|
||||
addIfNotNull(formParams, "grant_type", oAuthCredentialVo.getGrantType());
|
||||
|
||||
// 화면에서 추가 한 bodyJson을 Map으로 변환 후 추가
|
||||
String addBodyJson = oAuthCredentialVo.getBodyJson();
|
||||
if (addBodyJson != null && !addBodyJson.isEmpty()) {
|
||||
ObjectMapper bodyJsonMapper = new ObjectMapper();
|
||||
Map<String, Object> addBodyMap = bodyJsonMapper.readValue(addBodyJson, Map.class);
|
||||
for (Map.Entry<String, Object> entry : addBodyMap.entrySet()) {
|
||||
formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue().toString()));
|
||||
}
|
||||
}
|
||||
httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset));
|
||||
|
||||
}
|
||||
|
||||
RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
|
||||
|
||||
if (useForwardProxy) {
|
||||
java.net.URL url = new java.net.URL(forwardProxyUrl);
|
||||
|
||||
// 프로토콜, 호스트, 포트 추출
|
||||
String protocol = url.getProtocol();
|
||||
String host = url.getHost();
|
||||
int port = url.getPort();
|
||||
HttpHost proxy = new HttpHost(protocol, host, port);
|
||||
requestConfigBuilder.setProxy(proxy);
|
||||
}
|
||||
|
||||
RequestConfig requestConfig = requestConfigBuilder
|
||||
.setConnectTimeout(Timeout.ofMilliseconds(connectionTimeout))
|
||||
.setResponseTimeout(Timeout.ofMilliseconds(timeout)).build();
|
||||
httpPost.setConfig(requestConfig);
|
||||
|
||||
logger.debug("uri = [" + uri + "]");
|
||||
logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]");
|
||||
logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]");
|
||||
logger.debug("oauthScope = [" + oAuthCredentialVo.getScope() + "]");
|
||||
logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]");
|
||||
logger.debug("contentType = [" + contentType + "]");
|
||||
logger.debug("encode = [" + encode + "]");
|
||||
logger.debug("bodyJson = ["+ oAuthCredentialVo.getBodyJson() + "]");
|
||||
logger.debug("bodyHeader = ["+ oAuthCredentialVo.getHeaderJson() + "]");
|
||||
|
||||
try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
|
||||
if (response.getCode() != 200) {
|
||||
throw new Exception("OAuth token receive status fail value= " + response.getCode());
|
||||
}
|
||||
|
||||
HttpEntity entity = response.getEntity();
|
||||
String responseString = EntityUtils.toString(entity, encode);
|
||||
logger.debug("oauthToken RECV = [" + responseString + "]");
|
||||
|
||||
if (StringUtils.isNotBlank(responseString)) {
|
||||
OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO();
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper();
|
||||
JsonNode responseJSON = objectMapper.readTree(responseString);
|
||||
|
||||
if (responseJSON.has("access_token") && responseJSON.has("token_type")
|
||||
&& responseJSON.has("expires_in") && responseJSON.has("scope")) {
|
||||
accessToken.setAccessToken(responseJSON.get("access_token").asText());
|
||||
accessToken.setTokenType(responseJSON.get("token_type").asText());
|
||||
|
||||
long expiresIn = responseJSON.get("expires_in").asLong();
|
||||
accessToken.setExpiration(new Date(currentTime + expiresIn * 1000L));
|
||||
accessToken.setScope(responseJSON.get("scope").asText());
|
||||
}
|
||||
|
||||
if (responseJSON.has("client_use_code")) {
|
||||
accessToken.setClientUseCode(responseJSON.get("client_use_code").asText());
|
||||
}
|
||||
|
||||
logger.debug("oauthToken =" + accessToken.toString());
|
||||
|
||||
return accessToken;
|
||||
} else {
|
||||
throw new Exception("oauth token return null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* URL에 경로를 추가합니다. 중복되는 슬래시를 방지합니다.
|
||||
*
|
||||
* @param baseUrl 기본 URL
|
||||
* @param pathToAdd 추가할 경로
|
||||
* @return 완성된 URL 문자열
|
||||
*/
|
||||
public static String appendPath(String baseUrl, String pathToAdd) {
|
||||
if (!baseUrl.endsWith("/") && !pathToAdd.startsWith("/")) {
|
||||
return baseUrl + "/" + pathToAdd;
|
||||
} else if (baseUrl.endsWith("/") && pathToAdd.startsWith("/")) {
|
||||
return baseUrl + pathToAdd.substring(1);
|
||||
} else {
|
||||
return baseUrl + pathToAdd;
|
||||
}
|
||||
}
|
||||
private void addIfNotNull(List<NameValuePair> params, String name, String value) {
|
||||
if (StringUtils.isNotBlank(value)) {
|
||||
params.add(new BasicNameValuePair(name, value));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user