초기소스

This commit is contained in:
jazz
2025-10-29 17:08:05 +09:00
parent e531aa9540
commit 439a379a02
7551 changed files with 1234427 additions and 3 deletions

View File

@@ -0,0 +1,26 @@
package com.wb.domainserver.common.config;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import net.javacrumbs.shedlock.provider.jdbctemplate.JdbcTemplateLockProvider;
import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock;
@Configuration
@EnableSchedulerLock(defaultLockAtMostFor = "10m") // 최대 잠금 시간
public class BnftShedLockConfig {
@Bean
public JdbcTemplateLockProvider lockProvider(DataSource dataSource) {
return new JdbcTemplateLockProvider(
JdbcTemplateLockProvider.Configuration.builder()
.withTableName("gc_benefit_shedlock")
.withJdbcTemplate(new JdbcTemplate(dataSource))
.usingDbTime()
.build()
);
}
}

View File

@@ -0,0 +1,51 @@
package com.wb.domainserver.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.messaging.FirebaseMessaging;
import java.io.IOException;
@Configuration
public class FCMConfig {
@Bean(name = "NCFirebaseMessaging")
public FirebaseMessaging nutricoreFirebaseMessaging() throws IOException {
return createFirebaseMessaging(
"nutricoreeventapp-firebase-adminsdk-iliil-bd9d39ca9c.json",
"nutricore"
);
}
@Bean(name = "DTFirebaseMessaging")
public FirebaseMessaging doctorleanFirebaseMessaging() throws IOException {
return createFirebaseMessaging(
"doctorleaneventapp-firebase-adminsdk-ysdbz-3e5496cb84.json",
"doctorlean"
);
}
private FirebaseMessaging createFirebaseMessaging(String fileName, String appName) throws IOException {
ClassPathResource serviceAccount = new ClassPathResource("firebase/" + fileName);
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredentials(GoogleCredentials.fromStream(serviceAccount.getInputStream()))
.build();
FirebaseApp firebaseApp;
if (FirebaseApp.getApps().stream().noneMatch(app -> app.getName().equals(appName))) {
// FirebaseApp이 존재하지 않으면 새로 초기화
firebaseApp = FirebaseApp.initializeApp(options, appName);
} else {
// 이미 초기화된 FirebaseApp 사용
firebaseApp = FirebaseApp.getInstance(appName);
}
return FirebaseMessaging.getInstance(firebaseApp);
}
}

View File

@@ -0,0 +1,91 @@
package com.wb.domainserver.common.config;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* 멀티 DataSource 구성을 위한 설정 파일
*/
@Configuration
@MapperScan(
basePackages = {
"com.wb.domainserver.domain.admin"
,"com.wb.domainserver.domain.gcone"
,"com.wb.domainserver.domain.itrnt"
,"com.wb.domainserver.domain.extra"
,"com.wb.domainserver.domain.sample"
,"com.wb.domainserver.domain.auth"
,"com.wb.domainserver.domain.crm"
,"com.wb.domainserver.domain.frstlogin"
,"com.wb.domainserver.domain.log"
,"com.wb.domainserver.domain.mngr"
,"com.wb.domainserver.domain.oper"
,"com.wb.domainserver.domain.sopmal"
,"com.wb.domainserver.security.user"
,"com.wb.domainserver.security.jwt"
// ,"com.wb.domainserver.domain.ntcn"
// ,"com.wb.domainserver.batch.atmcsetle"
},
sqlSessionFactoryRef = "ASqlSessionFactory"
)
public class GconeDataSourceConfig {
private final String G_DATA_SOURCE = "GconeDataSource";
@Primary
@Bean(name = G_DATA_SOURCE)
@ConfigurationProperties(prefix = "spring.datasource.gcone.hikari")
public DataSource ADataSource() {
return DataSourceBuilder.create()
.type(HikariDataSource.class)
.build();
}
@Primary
@Bean(name = "ASqlSessionFactory")
public SqlSessionFactory ASqlSessionFactory(@Qualifier(G_DATA_SOURCE) DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources1 = resolver.getResources("classpath:mybatis/xml/mapper/admin/**/*.xml");
Resource[] resources2 = resolver.getResources("classpath:mybatis/xml/mapper/gcone/**/*.xml");
Resource[] resources3 = resolver.getResources("classpath:mybatis/xml/mapper/itrnt/**/*.xml");
Resource[] resources4 = resolver.getResources("classpath:mybatis/xml/mapper/*.xml");
// Resource[] resources4 = resolver.getResources("classpath:mybatis/xml/mapper/SecurityMapper.xml");
Resource[] resources5 = resolver.getResources("classpath:mybatis/xml/mapper/extra/**/*.xml");
Resource[] allResources = new Resource[resources1.length + resources2.length + resources3.length + resources4.length + resources5.length];
System.arraycopy(resources1, 0, allResources, 0, resources1.length);
System.arraycopy(resources2, 0, allResources, resources1.length, resources2.length);
System.arraycopy(resources3, 0, allResources, resources1.length + resources2.length, resources3.length);
System.arraycopy(resources4, 0, allResources, resources1.length + resources2.length + resources3.length, resources4.length);
System.arraycopy(resources5, 0, allResources, resources1.length + resources2.length + resources3.length + resources4.length, resources5.length);
sessionFactoryBean.setMapperLocations(allResources);
Resource myBatisConfig = new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/xml/config/mapper-config.xml");
sessionFactoryBean.setConfigLocation(myBatisConfig);
return sessionFactoryBean.getObject();
}
@Primary
@Bean(name = "ATransactionManager")
public DataSourceTransactionManager ATransactionManager(@Qualifier(G_DATA_SOURCE) DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}

View File

@@ -0,0 +1,156 @@
package com.wb.domainserver.common.config;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.core.io.Resource;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class RefreshableSqlSessionFactoryBean extends SqlSessionFactoryBean implements DisposableBean {
private static final Logger LOG = LoggerFactory.getLogger(RefreshableSqlSessionFactoryBean.class);
private SqlSessionFactory proxy;
private int interval = 1000;
private Timer timer;
private TimerTask task;
private Resource[] mapperLocations;
private boolean running = false;
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
private final Lock r = rwl.readLock();
private final Lock w = rwl.writeLock();
public void setMapperLocations(Resource[] mapperLocations) {
super.setMapperLocations(mapperLocations);
this.mapperLocations = mapperLocations;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void refresh() throws Exception {
w.lock();
try {
super.afterPropertiesSet();
} finally {
w.unlock();
}
LOG.info("sqlMapClient refreshed.");
}
public void afterPropertiesSet() throws Exception {
super.afterPropertiesSet();
}
private void setRefreshable() {
proxy = (SqlSessionFactory) Proxy.newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[]{SqlSessionFactory.class}, new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
return method.invoke(getParentObject(), args);
}
});
task = new TimerTask() {
private Map<Resource, Long> map = new HashMap<Resource, Long>();
public void run() {
if (isModified()) {
try {
refresh();
} catch (Exception e) {
LOG.error("caught exception", e);
}
}
}
private boolean isModified() {
boolean retVal = false;
if (mapperLocations != null) {
for (int i = 0; i < mapperLocations.length; i++) {
Resource mappingLocation = mapperLocations[i];
retVal |= findModifiedResource(mappingLocation);
}
}
return retVal;
}
private boolean findModifiedResource(Resource resource) {
boolean retVal = false;
List<String> modifiedResources = new ArrayList<String>();
try {
long modified = resource.lastModified();
if (map.containsKey(resource)) {
long lastModified = map.get(resource).longValue();
if (lastModified != modified) {
map.put(resource, modified);
modifiedResources.add(resource.getDescription());
retVal = true;
}
} else {
map.put(resource, modified);
}
} catch (IOException e) {
LOG.error("caught exception", e);
}
if (retVal) {
LOG.info("modified files : " + modifiedResources);
}
return retVal;
}
};
timer = new Timer(true);
resetInterval();
}
private Object getParentObject() throws Exception {
r.lock();
try {
return super.getObject();
} finally {
r.unlock();
}
}
public SqlSessionFactory getObject() throws Exception {
if (this.proxy == null) {
setRefreshable();
}
return this.proxy;
}
public Class<? extends SqlSessionFactory> getObjectType() {
return (this.proxy != null ? this.proxy.getClass() : SqlSessionFactory.class);
}
public boolean isSingleton() {
return true;
}
public void setCheckInterval(int ms) {
interval = ms;
if (timer != null) {
resetInterval();
}
}
private void resetInterval() {
if (running) {
timer.cancel();
running = false;
}
if (interval > 0) {
timer.schedule(task, 0, interval);
running = true;
}
}
public void destroy() throws Exception {
timer.cancel();
}
}

View File

@@ -0,0 +1,42 @@
package com.wb.domainserver.common.config;
import com.wb.domainserver.security.config.AdminWebMvcConfig;
import com.wb.domainserver.security.config.CommWebMvcConfig;
import com.wb.domainserver.security.config.WebMvcConfig;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
@Configuration
public class ServletContextConfig {
@Bean
public ServletRegistrationBean<DispatcherServlet> sopmalServlet(ApplicationContext parent) {
AnnotationConfigWebApplicationContext sopmalContext = new AnnotationConfigWebApplicationContext();
sopmalContext.setParent(parent); // Root Context 상속
sopmalContext.register(CommWebMvcConfig.class);
sopmalContext.register(WebMvcConfig.class);
DispatcherServlet servlet = new DispatcherServlet(sopmalContext);
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(servlet, "/sopmal","/sopmal/**");
registration.setName("sopmalServlet");
return registration;
}
@Bean
public ServletRegistrationBean<DispatcherServlet> adminServlet(ApplicationContext parent) {
AnnotationConfigWebApplicationContext adminContext = new AnnotationConfigWebApplicationContext();
adminContext.setParent(parent); // Root Context 상속
adminContext.register(CommWebMvcConfig.class);
adminContext.register(AdminWebMvcConfig.class);
DispatcherServlet servlet = new DispatcherServlet(adminContext);
ServletRegistrationBean<DispatcherServlet> registration = new ServletRegistrationBean<>(servlet, "/admin/**", "/mngr/**", "/mngr","/admin");
registration.setName("adminServlet");
return registration;
}
}

View File

@@ -0,0 +1,102 @@
package com.wb.domainserver.common.config;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* 멀티 DataSource 구성을 위한 설정 파일
*/
@Configuration
@MapperScan(basePackages = "com.wb.domainserver.domain.sure", sqlSessionFactoryRef = "BSqlSessionFactory")
public class SureDataSourceConfig {
private final String B_DATA_SOURCE = "BDataSource";
@Bean(name = B_DATA_SOURCE)
@ConfigurationProperties(prefix = "spring.datasource.sure.hikari")
public DataSource BDataSource() {
return DataSourceBuilder.create()
.type(HikariDataSource.class)
.build();
}
@Bean(name = "BSqlSessionFactory")
public SqlSessionFactory BSqlSessionFactory(@Qualifier(B_DATA_SOURCE) DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource);
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource configLocation = resolver.getResource("classpath:mybatis/xml/config/mapper-config.xml");
sessionFactoryBean.setConfigLocation(configLocation);
Resource[] resources = resolver.getResources("classpath*:mybatis/xml/mapper/sure/**/*.xml");
sessionFactoryBean.setMapperLocations(resources);
return sessionFactoryBean.getObject();
}
@Bean(name = "BTransactionManager")
public DataSourceTransactionManager BTransactionManager(@Qualifier(B_DATA_SOURCE) DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
//
//
//
//@Configuration
//@MapperScan(value = "com.wb.domainserver.domain.sure", sqlSessionFactoryRef = "BSqlSessionFactory")
//public class SureDataSourceConfig {
//
//
// private final String sureDataSource = "SureDataSource";
//
// @Bean(sureDataSource)
// @ConfigurationProperties(prefix = "spring.datasource.sure.hikari")
// public DataSource BDataSource() {
// return DataSourceBuilder.create()
// .type(HikariDataSource.class)
// .build();
// }
//
// @Bean
// public SqlSessionFactory BSqlSessionFactory(@Qualifier(sureDataSource) DataSource dataSource) throws Exception {
// /*
// * MyBatis 는 JdbcTemplate 대신 Connection 객체를 통한 질의를 위해서 SqlSession 을 사용한다.
// * 내부적으로 SqlSessionTemplate 가 SqlSession 을 구현한다.
// * Thread-Safe 하고 여러 개의 Mapper 에서 공유할 수 있다.
// */
// SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
// bean.setDataSource(dataSource);
//
// // MyBatis Mapper Source
// // MyBatis 의 SqlSession 에서 불러올 쿼리 정보
// Resource[] res = new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/xml/mapper/sure/**/*.xml");
// bean.setMapperLocations(res);
//
// // MyBatis Config Setting
// // MyBatis 설정 파일
// Resource myBatisConfig = new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/xml/config/mapper-config.xml");
// bean.setConfigLocation(myBatisConfig);
//
// return bean.getObject();
// }
//
// // DataSource 에서 Transaction 관리를 위한 Manager 클래스 등록
// @Bean(name = "sureTransactionManager")
// public DataSourceTransactionManager BTransactionManager(@Qualifier(sureDataSource) DataSource dataSource) {
// return new DataSourceTransactionManager(dataSource);
// }
//}

View File

@@ -0,0 +1,66 @@
package com.wb.domainserver.common.msg;
import org.springframework.context.MessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import java.util.Locale;
/**
* 메세지 처리를 지원하는 Object
*
* @author 박철민
* @since 2023-11-28
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-28 박철민 최초 생성
*
* </pre>
*/
public class GconeMessageSource extends ReloadableResourceBundleMessageSource implements MessageSource {
private ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource;
/**
* getReloadableResourceBundleMessageSource()
* @param reloadableResourceBundleMessageSource - resource MessageSource
* @return ReloadableResourceBundleMessageSource
*/
public void setReloadableResourceBundleMessageSource(ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource) {
this.reloadableResourceBundleMessageSource = reloadableResourceBundleMessageSource;
}
/**
* getReloadableResourceBundleMessageSource()
* @return ReloadableResourceBundleMessageSource
*/
public ReloadableResourceBundleMessageSource getReloadableResourceBundleMessageSource() {
return reloadableResourceBundleMessageSource;
}
/**
* 정의된 메세지 조회
* @param code - 메세지 코드
* @return String
*/
public String getMessage(String code) {
return getReloadableResourceBundleMessageSource().getMessage(code, null, Locale.getDefault());
}
/**
* 정의된 메세지 조회
* @param code 메시지 코드
* @param args 변환 변수
* @return String 메시지문자열
*/
public String getMessage(String code, Object[] args) {
return getReloadableResourceBundleMessageSource().getMessage(code, args, Locale.getDefault());
}
}

View File

@@ -0,0 +1,116 @@
package com.wb.domainserver.common.mvc.tags.ui.pagination;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
* 페이징 처리를 위한 데이터 처리용 Bean
*
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public class PaginationInfo implements Serializable{
private static final long serialVersionUID = 1L;
/** 현재 페이지 번호. */
private int currentPageNo;
/** 한 페이지당 게시되는 게시물 건 수 */
private int recordCountPerPage;
/** 한 페이지당 게시되는 게시물 건 수 */
private int pageSize;
/** 페이지 리스트에 게시되는 페이지 건수 */
private int totalRecordCount;
public int getRecordCountPerPage() {
return recordCountPerPage;
}
public void setRecordCountPerPage(int recordCountPerPage) {
this.recordCountPerPage = recordCountPerPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPageNo() {
return currentPageNo;
}
public void setCurrentPageNo(int currentPageNo) {
this.currentPageNo = currentPageNo;
}
public void setTotalRecordCount(int totalRecordCount) {
this.totalRecordCount = totalRecordCount;
}
public int getTotalRecordCount() {
return totalRecordCount;
}
/** 페이지 개수 */
private int totalPageCount;
/** 페이지 리스트의 첫 페이지 번호 */
private int firstPageNoOnPageList;
/** 페이지 리스트의 마지막 페이지 번호 */
private int lastPageNoOnPageList;
/** 페이징 SQL의 조건절에 사용되는 시작 rownum */
private int firstRecordIndex;
/** 페이징 SQL의 조건절에 사용되는 마지막 rownum */
private int lastRecordIndex;
public int getTotalPageCount() {
BigDecimal totalRecordCount = new BigDecimal(getTotalRecordCount());
BigDecimal recordCountPerPage = new BigDecimal(getRecordCountPerPage());
BigDecimal totalPageCount = totalRecordCount.divide(recordCountPerPage, RoundingMode.CEILING);
return totalPageCount.intValue();
}
public int getFirstPageNo() {
return 1;
}
public int getLastPageNo() {
return getTotalPageCount();
}
public int getFirstPageNoOnPageList() {
firstPageNoOnPageList = ((getCurrentPageNo() - 1) / getPageSize()) * getPageSize() + 1;
return firstPageNoOnPageList;
}
public int getLastPageNoOnPageList() {
lastPageNoOnPageList = getFirstPageNoOnPageList() + getPageSize() - 1;
if (lastPageNoOnPageList > getTotalPageCount()) {
lastPageNoOnPageList = getTotalPageCount();
}
return lastPageNoOnPageList;
}
public int getFirstRecordIndex() {
firstRecordIndex = (getCurrentPageNo() - 1) * getRecordCountPerPage();
return firstRecordIndex;
}
public int getLastRecordIndex() {
lastRecordIndex = getCurrentPageNo() * getRecordCountPerPage();
return lastRecordIndex;
}
}

View File

@@ -0,0 +1,34 @@
package com.wb.domainserver.common.prop;
import org.springframework.boot.context.properties.ConfigurationProperties;
import lombok.Data;
import org.springframework.stereotype.Component;
/**
* 페이징 처리를 위한 properties
*
* @author 박철민
* @since 2023-11-27
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-27 박철민 최초 생성
*
* </pre>
*/
@Data
@ConfigurationProperties(prefix = "pagination")
@Component
public class PaginationProperties {
/** 한 페이지당 게시되는 게시물 건 수 */
private Integer pageUnit;
/** 한 페이지당 노출되는 페이지 수 */
private Integer pageSize;
}

View File

@@ -0,0 +1,142 @@
package com.wb.domainserver.common.prop;
import com.wb.domainserver.util.dataaccess.DataMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@RefreshScope
@Component
public class PropertyService {
private static Environment env = null;
@Autowired
public PropertyService(Environment env) {
PropertyService.env = env;
}
public static String getProperty() {
return env.getProperty("prop.test");
}
/**
* pos-milege 프로퍼티 조회
* @param
* @return
*/
public static String getPropertyMlgValue(String corpNm, String propertyNm) {
String propertyPath = String.format("pos-mileage.%s.%s", corpNm, propertyNm);
return env.getProperty(propertyPath);
}
/**
* pos-milege 프로퍼티 List<DataMap> 형식으로 전환
* @param
* @return
*/
public static List<DataMap> getPropertyValueToMapList(String corpNm, String propertyNm) {
String propertyPath = String.format("pos-mileage.%s.%s", corpNm, propertyNm);
String propertyValue = env.getProperty(propertyPath);
List<DataMap> resultList = new ArrayList<DataMap>();
String[] entries = propertyValue.split(",\\s*");
for (String entry : entries) {
DataMap resultMap = new DataMap();
String[] keyValue = entry.split(":\\s*");
if (keyValue.length == 2) {
resultMap.put(keyValue[0], keyValue[1]);
resultList.add(resultMap);
}
}
return resultList;
}
/**
* surem yaml 프로퍼티 조회
* @param
* @return
*/
public static String getPropertySuremSopMal(String sopmalCd, String propertyNm) {
String propertyPath = String.format("surem.sopmal.%s.%s", sopmalCd, propertyNm);
return env.getProperty(propertyPath);
}
/**
* 공통 yaml 프로퍼티 조회 파라미터 기본
* basePath depth1.depth2....
* @param
* @return
*/
public static String getProperty(String basePath) {
return env.getProperty(basePath);
}
/**
* 공통 yaml 프로퍼티 조회 파라미터 1개
* basePath depth1.%s
* path depth2
* @param
* @return
*/
public static String getPropertyOne(String basePath, String path) {
String propertyPath = String.format(basePath, path);
return env.getProperty(propertyPath);
}
/**
* 공통 yaml 프로퍼티 조회 파라미터 2개
* basePath depth1.%s.%s
* path depth2, depth3
* @param
* @return
*/
public static String getPropertyTwo(String basePath, String path1, String path2) {
String propertyPath = String.format(basePath, path1, path2);
return env.getProperty(propertyPath);
}
/**
* 공통 yaml 프로퍼티 조회 파라미터 3개
* basePath depth1.%s.%s.%s
* path depth2, depth3, depth4
* @param
* @return
*/
public static String getPropertyThree(String basePath, String path1, String path2, String path3) {
String propertyPath = String.format(basePath, path1, path2, path3);
return env.getProperty(propertyPath);
}
/**
* 공통 yaml 프로퍼티 조회 파라미터 4개
* basePath depth1.%s.%s.%s.%s
* path depth2, depth3, depth4, depth5
* @param
* @return
*/
public static String getPropertyFour(String basePath, String path1, String path2, String path3, String path4) {
String propertyPath = String.format(basePath, path1, path2, path3, path4);
return env.getProperty(propertyPath);
}
/**
* 공통 yaml 프로퍼티 조회 파라미터 4개
* basePath depth1.%s.%s.%s.%s
* path depth2, depth3, depth4, depth5
* @param
* @return
*/
public static String getPropertyBankdaAccount(String key) {
String propertyPath = String.format("bankda.%s", key);
return env.getProperty(propertyPath);
}
}

View File

@@ -0,0 +1,74 @@
package com.wb.domainserver.common.ui;
import com.wb.domainserver.common.ui.pagination.*;
import com.wb.domainserver.common.ui.pagination.DefaultPaginationManager;
import com.wb.domainserver.common.ui.pagination.DefaultPaginationRenderer;
import com.wb.domainserver.common.ui.pagination.PaginationManager;
import com.wb.domainserver.common.ui.pagination.PaginationRenderer;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.jsp.JspException;
import jakarta.servlet.jsp.JspWriter;
import jakarta.servlet.jsp.tagext.TagSupport;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.servlet.support.RequestContextUtils;
import java.io.IOException;
public class PaginationTag extends TagSupport {
private static final long serialVersionUID = 1L;
private PaginationInfo paginationInfo;
private String type;
private String jsFunction;
public int doEndTag() throws JspException {
try {
JspWriter out = pageContext.getOut();
PaginationManager paginationManager;
WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(pageContext.getServletContext());
WebApplicationContext ctxd = RequestContextUtils.findWebApplicationContext((HttpServletRequest) pageContext.getRequest(), pageContext.getServletContext());
if (ctx.containsBean("paginationManager")) {
paginationManager = (PaginationManager) ctx.getBean("paginationManager");
} else if (ctxd.containsBean("paginationManager")) {
paginationManager = (PaginationManager) ctxd.getBean("paginationManager");
} else {
//bean 정의가 없다면 DefaultPaginationManager를 사용. 빈설정이 없으면 기본 적인 페이징 리스트라도 보여주기 위함.
paginationManager = new DefaultPaginationManager();
}
PaginationRenderer paginationRenderer = null;
String rentererType = !StringUtil.isEmpty(type)? type :"";
paginationRenderer = paginationManager.getRendererType(rentererType);
if(paginationRenderer!=null){
String contents = paginationRenderer.renderPagination(paginationInfo, jsFunction);
out.println(contents);
}else{
paginationRenderer = new DefaultPaginationRenderer();
String contents = paginationRenderer.renderPagination(paginationInfo, jsFunction);
out.println(contents);
}
return EVAL_PAGE;
} catch (IOException e) {
throw new JspException();
}
}
public void setJsFunction(String jsFunction) {
this.jsFunction = jsFunction;
}
public void setPaginationInfo(PaginationInfo paginationInfo) {
this.paginationInfo = paginationInfo;
}
public void setType(String type) {
this.type = type;
}
}

View File

@@ -0,0 +1,94 @@
package com.wb.domainserver.common.ui.pagination;
import java.text.MessageFormat;
/**
* 인터페이스 PaginationRenderer의 구현 추상클래스.
* 기본적인 페이징 기능이 구현되어 있으며, 화면에서 아래와 같이 display 된다.
*
* [처음][이전] 1 2 3 4 5 6 7 8 [다음][마지막]
*
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public abstract class AbstractPaginationRenderer implements PaginationRenderer {
/** [처음] 영역에 노출될 문자 */
protected String firstPageLabel;
/** [이전] 영역에 노출될 문자 */
protected String previousPageLabel;
/** 현재페이지 영역에 노출될 문자 */
protected String currentPageLabel;
/** 다른페이지 영역에 노출될 문자 */
protected String otherPageLabel;
/** [다음] 영역에 노출될 문자 */
protected String nextPageLabel;
/** [마지막] 영역에 노출될 문자 */
protected String lastPageLabel;
/**
* 페이징영역 렌더링
* @param PaginationInfo 페이징처리정보
* @param String 페이지 이동 스크립트 함수명
* @return String 화면에 노출될 Tag 문자열
*/
public String renderPagination(PaginationInfo paginationInfo, String jsFunction) {
StringBuffer strBuff = new StringBuffer();
strBuff.append("<div class=\"pagination\">");
int firstPageNo = paginationInfo.getFirstPageNo();
int firstPageNoOnPageList = paginationInfo.getFirstPageNoOnPageList();
int totalPageCount = paginationInfo.getTotalPageCount();
int pageSize = paginationInfo.getPageSize();
int lastPageNoOnPageList = paginationInfo.getLastPageNoOnPageList();
int currentPageNo = paginationInfo.getCurrentPageNo();
int lastPageNo = paginationInfo.getLastPageNo();
if (totalPageCount > pageSize) {
if (firstPageNoOnPageList > pageSize) {
strBuff.append(MessageFormat.format(firstPageLabel, new Object[] { jsFunction, Integer.toString(firstPageNo) }));
strBuff.append(MessageFormat.format(previousPageLabel, new Object[] { jsFunction, Integer.toString(firstPageNoOnPageList - 1) }));
} else {
strBuff.append(MessageFormat.format(firstPageLabel, new Object[] { jsFunction, Integer.toString(firstPageNo) }));
strBuff.append(MessageFormat.format(previousPageLabel, new Object[] { jsFunction, Integer.toString(firstPageNo) }));
}
}
strBuff.append("<ol class=\"pagination__number-group\">");
for (int i = firstPageNoOnPageList; i <= lastPageNoOnPageList; i++) {
if (i == currentPageNo) {
strBuff.append(MessageFormat.format(currentPageLabel, new Object[] { Integer.toString(i) }));
} else {
strBuff.append(MessageFormat.format(otherPageLabel, new Object[] { jsFunction, Integer.toString(i), Integer.toString(i) }));
}
}
if (totalPageCount > pageSize) {
if (lastPageNoOnPageList < totalPageCount) {
strBuff.append(MessageFormat.format(nextPageLabel, new Object[] { jsFunction, Integer.toString(firstPageNoOnPageList + pageSize) }));
strBuff.append(MessageFormat.format(lastPageLabel, new Object[] { jsFunction, Integer.toString(lastPageNo) }));
} else {
strBuff.append(MessageFormat.format(nextPageLabel, new Object[] { jsFunction, Integer.toString(lastPageNo) }));
strBuff.append(MessageFormat.format(lastPageLabel, new Object[] { jsFunction, Integer.toString(lastPageNo) }));
}
}
strBuff.append("</ol>");
strBuff.append("</div>");
return strBuff.toString();
}
}

View File

@@ -0,0 +1,24 @@
package com.wb.domainserver.common.ui.pagination;
import java.util.Map;
public class DefaultPaginationManager implements PaginationManager {
private Map<String, PaginationRenderer> rendererType;
/**
* Set PaginationRenderer 구현 클래스
* @param rendererType - PaginationRenderer 구현 클래스 집합 Map.
*/
public void setRendererType(Map<String, PaginationRenderer> rendererType) {
this.rendererType = rendererType;
}
/**
* @param type - tag의 파라미터 값.
*/
public PaginationRenderer getRendererType(String type) {
return (rendererType != null && rendererType.containsKey(type)) ? (PaginationRenderer) rendererType.get(type) : new DefaultPaginationRenderer();
}
}

View File

@@ -0,0 +1,38 @@
package com.wb.domainserver.common.ui.pagination;
/**
* 페이징 리스트의 기본적인 포맷을 제공한다.
* 이를 위해 AbstractPaginationRenderer의 클래스 변수들의 값을 세팅한다.
*
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public class DefaultPaginationRenderer extends AbstractPaginationRenderer {
public DefaultPaginationRenderer() {
firstPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">[처음]</a>&#160;";
previousPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">[이전]</a>&#160;";
currentPageLabel = "<strong>{0}</strong>&#160;";
otherPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">{2}</a>&#160;";
nextPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">[다음]</a>&#160;";
lastPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">[마지막]</a>&#160;";
}
@Override
public String renderPagination(PaginationInfo paginationInfo, String jsFunction) {
return super.renderPagination(paginationInfo, jsFunction);
}
}

View File

@@ -0,0 +1,51 @@
package com.wb.domainserver.common.ui.pagination;
import jakarta.servlet.ServletContext;
import org.springframework.web.context.ServletContextAware;
/**
* image pagination renderer Bean
*
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public class ImagePaginationRenderer extends AbstractPaginationRenderer implements ServletContextAware {
// private ServletContext servletContext;
public ImagePaginationRenderer() {
}
public void initVariables(){
//firstPageLabel = "<li>&#160;</li><li><a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/images/egovframework/com/cmm/mod/icon/icon_prevend.gif\" alt=\"처음\" border=\"0\"/></a></li>";
firstPageLabel = "<button class=\"pagination__item first\" onclick=\"{0}({1});return false; \"><span class=\"visually-hidden\">첫 페이지로</span></button>";
//previousPageLabel = "<li><a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/images/egovframework/com/cmm/mod/icon/icon_prev.gif\" alt=\"이전\" border=\"0\"/></a></li>";
previousPageLabel = "<button class=\"pagination__item prev\" onclick=\"{0}({1});return false; \"><span class=\"visually-hidden\">이전 페이지로</span></button>";
//currentPageLabel = "<li><strong>{0}</strong></li>";
currentPageLabel = "<li><button class=\"pagination__item active\"><span>{0}</span></button></li>";
//otherPageLabel = "<li><a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \">{2}</a></li>";
otherPageLabel = "<li><button class=\"pagination__item\" onclick=\"{0}({1});return false; \"><span>{2}</span></button></li>";
//nextPageLabel = "<li>&#160;<a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/images/egovframework/com/cmm/mod/icon/icon_next.gif\" alt=\"다음\" border=\"0\"/></a></li>";
nextPageLabel = "<button class=\"pagination__item next\" onclick=\"{0}({1});return false; \"><span class=\"visually-hidden\">다음 페이지로</span></button>";
//lastPageLabel = "<li><a href=\"?pageIndex={1}\" onclick=\"{0}({1});return false; \"><img src=\"" + servletContext.getContextPath() + "/images/egovframework/com/cmm/mod/icon/icon_nextend.gif\" alt=\"마지막\" border=\"0\"/></a></li>";
lastPageLabel = "<button class=\"pagination__item last\" onclick=\"{0}({1});return false; \"><span class=\"visually-hidden\">마지막 페이지로</span></button>";
}
public void setServletContext(ServletContext servletContext) {
// this.servletContext = servletContext;
initVariables();
}
}

View File

@@ -0,0 +1,120 @@
package com.wb.domainserver.common.ui.pagination;
import java.util.Arrays;
/**
* 페이징 처리를 위한 데이터 처리용 Bean
*
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public class PaginationInfo {
/** 현재 페이지 번호. */
private int currentPageNo;
/** 한 페이지당 게시되는 게시물 건 수 */
private int recordCountPerPage;
/** 한 페이지당 게시되는 게시물 건 수 */
private int pageSize;
/** 페이지 리스트에 게시되는 페이지 건수 */
private int totalRecordCount;
private Integer[] pageUnitArr = {10, 50, 100, 200};
public int getRecordCountPerPage() {
return recordCountPerPage;
}
public void setRecordCountPerPage(int recordCountPerPage) {
this.recordCountPerPage = recordCountPerPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getCurrentPageNo() {
return currentPageNo;
}
public void setCurrentPageNo(int currentPageNo) {
this.currentPageNo = currentPageNo;
}
public void setTotalRecordCount(int totalRecordCount) {
this.totalRecordCount = totalRecordCount;
}
public int getTotalRecordCount() {
return totalRecordCount;
}
/** 페이지 개수 */
private int totalPageCount;
/** 페이지 리스트의 첫 페이지 번호 */
private int firstPageNoOnPageList;
/** 페이지 리스트의 마지막 페이지 번호 */
private int lastPageNoOnPageList;
/** 페이징 SQL의 조건절에 사용되는 시작 rownum */
private int firstRecordIndex;
/** 페이징 SQL의 조건절에 사용되는 마지막 rownum */
private int lastRecordIndex;
public int getTotalPageCount() {
totalPageCount = ((getTotalRecordCount() - 1) / getRecordCountPerPage()) + 1;
return totalPageCount;
}
public int getFirstPageNo() {
return 1;
}
public int getLastPageNo() {
return getTotalPageCount();
}
public int getFirstPageNoOnPageList() {
firstPageNoOnPageList = ((getCurrentPageNo() - 1) / getPageSize()) * getPageSize() + 1;
return firstPageNoOnPageList;
}
public int getLastPageNoOnPageList() {
lastPageNoOnPageList = getFirstPageNoOnPageList() + getPageSize() - 1;
if (lastPageNoOnPageList > getTotalPageCount()) {
lastPageNoOnPageList = getTotalPageCount();
}
return lastPageNoOnPageList;
}
public int getFirstRecordIndex() {
firstRecordIndex = (getCurrentPageNo() - 1) * getRecordCountPerPage();
return firstRecordIndex;
}
public int getLastRecordIndex() {
lastRecordIndex = getCurrentPageNo() * getRecordCountPerPage();
return lastRecordIndex;
}
public Integer[] getPageUnitArr() {
return pageUnitArr.clone();
}
public void setPageUnitArr(Integer[] pageUnitArr) {
this.pageUnitArr = Arrays.copyOf(pageUnitArr, pageUnitArr.length);
}
}

View File

@@ -0,0 +1,24 @@
package com.wb.domainserver.common.ui.pagination;
/**
* PaginationRenderer의 구현체를 빈설정 파일을 참조하여 반환한다.
* 이는 이미지, 텍스트등 여러 포맷으로 보여줄 필요성이 있을 경우, 각 type의 구현클래스를 사용자가 지정하고
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public interface PaginationManager {
public PaginationRenderer getRendererType(String type);
}

View File

@@ -0,0 +1,24 @@
package com.wb.domainserver.common.ui.pagination;
/**
* PaginationRenderer의 interface
*
* @author 박철민
* @since 2023-11-22
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2023-11-22 박철민 최초 생성
*
* </pre>
*/
public interface PaginationRenderer {
public String renderPagination(PaginationInfo paginationInfo, String jsFunction);
}

View File

@@ -0,0 +1,60 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 아이디 정합성을 체크한다.
*
* @author 최범식
* @since 2024-01-13
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-13 최범식 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = BoardId.BoardIdValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface BoardId {
String message() default "영문/숫자/언더스코어(_)/하이픈(-)만 사용하여 6~30자로 입력해 주세요.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class BoardIdValidator implements ConstraintValidator<BoardId, String> {
private final String REGEX_ID = "^[A-Za-z[0-9]-_$]{4,30}$";
public Pattern boardId = Pattern.compile(REGEX_ID);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return !boardId.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,60 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 영문만 입력되었는지 정합성을 체크한다.
*
* @author 박철민
* @since 2024-01-04
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-04 박철민 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = English.EnglishValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface English {
String message() default "영문을 입력하셔야 합니다.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class EnglishValidator implements ConstraintValidator<English, String> {
private final String REGEX_ENGLISH = "^[a-zA-Z\\s]*$";
public Pattern english = Pattern.compile(REGEX_ENGLISH);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return english.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,61 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 아이디 정합성을 체크한다.
*
* @author 최범식
* @since 2024-01-13
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-13 최범식 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = Id.IdValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface Id {
String message() default "영문/숫자 조합 6~20자로 입력해 주세요.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class IdValidator implements ConstraintValidator<Id, String> {
private final String REGEX_ID = "^[A-Za-z[0-9]$]{6,20}$";
public Pattern id = Pattern.compile(REGEX_ID);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return id.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,62 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 한글만 입력되었는지 정합성을 체크한다.
*
* @author 박철민
* @since 2024-01-04
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-04 박철민 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = Korean.KoreanValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface Korean {
String message() default "한글을 입력하셔야 합니다.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class KoreanValidator implements ConstraintValidator<Korean, String> {
private final String REGEX_KOREAN = "^[가-힣\\s]*$";
public Pattern korean = Pattern.compile(REGEX_KOREAN);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return korean.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,60 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 비밀번호 정합성을 체크한다.
*
* @author 최범식
* @since 2024-01-12
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-12 최범식 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = MngrPassword.MngrPasswordValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface MngrPassword {
String message() default "영문/숫자/특수문자 조합 10~20로 입력해 주세요.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class MngrPasswordValidator implements ConstraintValidator<MngrPassword, String> {
private final String REGEX_PASSWORD = "^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[$@$!%*#?&{}()~_*\\\\^+-:><=\\[\\]])[A-Za-z[0-9]@$!%*#?&{}()~_*\\^+-:><=\\[\\]]{10,20}$";
public Pattern mngrPassword = Pattern.compile(REGEX_PASSWORD);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return mngrPassword.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,60 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 숫자(정수)만 입력되었는지 정합성을 체크한다.
*
* @author 박철민
* @since 2024-01-04
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-04 박철민 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = NumberOnly.NumberOnlyValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface NumberOnly {
String message() default " 숫자(정수)를 입력하셔야 합니다.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class NumberOnlyValidator implements ConstraintValidator<NumberOnly, String> {
private final String REGEX_NUMBER_ONLY = "^[0-9]*$";
public Pattern numberonly = Pattern.compile(REGEX_NUMBER_ONLY);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return numberonly.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,60 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 숫자와하이픈만 입력되었는지 정합성을 체크한다.
*
* @author 박철민
* @since 2024-01-04
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-04 박철민 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = NumberWithHyphen.NumberWithHyphenValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface NumberWithHyphen {
String message() default "숫자와 하이픈(-)만 입력하셔야 합니다.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class NumberWithHyphenValidator implements ConstraintValidator<NumberWithHyphen, String> {
private final String REGEX_NUMBER_WIT_HYPEN = "^[0-9-]*$";
public Pattern NumberWithHyphen = Pattern.compile(REGEX_NUMBER_WIT_HYPEN);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return NumberWithHyphen.matcher(value).matches();
}
}
}
}

View File

@@ -0,0 +1,61 @@
package com.wb.domainserver.common.validate;
import com.wb.domainserver.util.string.StringUtil;
import jakarta.validation.Constraint;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;
import jakarta.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.regex.Pattern;
import static java.lang.annotation.ElementType.FIELD;
/**
* 입력값에 패스워드 정합성을 체크한다.
*
* @author 최범식
* @since 2024-01-13
* @version 1.0
* @see
*
* <pre>
* == (Modification Information) == 개정이력
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2024-01-13 최범식 최초 생성
*
* </pre>
*/
@Constraint(validatedBy = Password.PasswordValidator.class)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(FIELD)
public @interface Password {
String message() default "영문/숫자 조합 6~20자로 입력해 주세요.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default{};
class PasswordValidator implements ConstraintValidator<Password, String> {
private final String REGEX_PASSWORD = "^[A-Za-z[0-9]$]{6,20}$";
public Pattern password = Pattern.compile(REGEX_PASSWORD);
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtil.isEmpty(value)) {
return false;
} else {
return password.matcher(value).matches();
}
}
}
}