feat(itms): iams.nlib → legacy/nlib subtree 이식 (히스토리 보존)

git-subtree-dir: legacy/nlib
git-subtree-mainline: c057b0feb5
git-subtree-split: 6ee2c7265e
This commit is contained in:
itms-merge-dev 2026-07-17 17:01:27 +09:00
commit 32dd03f775
600 changed files with 122502 additions and 0 deletions

40
legacy/nlib/.classpath Normal file
View File

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk1.8.0_202">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jst.server.core.container/org.eclipse.jst.server.tomcat.runtimeTarget/Apache Tomcat v8.5"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

120
legacy/nlib/.gitignore vendored Normal file
View File

@ -0,0 +1,120 @@
# Created by https://www.toptal.com/developers/gitignore/api/java,windows,eclipse
# Edit at https://www.toptal.com/developers/gitignore?templates=java,windows,eclipse
### Eclipse ###
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
.settings/
.settings/*
.loadpath
.recommenders
target/
build/
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# PyDev specific (Python IDE for Eclipse)
*.pydevproject
# CDT-specific (C/C++ Development Tooling)
.cproject
# CDT- autotools
.autotools
# Java annotation processor (APT)
.factorypath
# PDT-specific (PHP Development Tools)
.buildpath
# sbteclipse plugin
.target
# Tern plugin
.tern-project
# TeXlipse plugin
.texlipse
# STS (Spring Tool Suite)
.springBeans
# Code Recommenders
.recommenders/
# Annotation Processing
.apt_generated/
.apt_generated_test/
# Scala IDE specific (Scala & Java development for Eclipse)
.cache-main
.scala_dependencies
.worksheet
# Uncomment this line if you wish to ignore the project description file.
# Typically, this file would be tracked if it contains build/dependency configurations:
#.project
### Eclipse Patch ###
# Spring Boot Tooling
.sts4-cache/
### Java ###
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/java,windows,eclipse
### nLib ###
!RESTfulAPI.server/**/*
!RESTfulAPI.server/bin/*
!src/main/webapp/WEB-INF/lib/*.*

49
legacy/nlib/.project Normal file
View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>nlib</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.core.springbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.springframework.ide.eclipse.boot.validation.springbootbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.springframework.ide.eclipse.core.springnature</nature>
<nature>egovframework.dev.imp.ide.natures.egovnature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

1
legacy/nlib/data/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/fileupload/

View File

@ -0,0 +1 @@
/*

636
legacy/nlib/pom.xml Normal file
View File

@ -0,0 +1,636 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nlib</groupId>
<artifactId>nlib</artifactId>
<packaging>war</packaging>
<version>1.0.0</version>
<name>nlib</name>
<url>http://www.egovframe.go.kr</url>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<properties>
<spring.maven.artifact.version>4.3.16.RELEASE</spring.maven.artifact.version>
<egovframework.rte.version>3.8.0</egovframework.rte.version>
<spring-security.version>4.2.5.RELEASE</spring-security.version>
<slf4j.version>1.7.2</slf4j.version>
<log4j.version>2.15.0</log4j.version>
</properties>
<repositories>
<repository>
<id>mvn2</id>
<url>http://repo1.maven.org/maven2/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>egovframe</id>
<url>http://www.egovframe.go.kr/maven/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>egovframe2</id>
<url>http://maven.egovframe.kr:8080/maven/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<dependencies>
<!-- 표준프레임워크 실행환경 -->
<dependency>
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.ptl.mvc</artifactId>
<version>${egovframework.rte.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.psl.dataaccess</artifactId>
<version>${egovframework.rte.version}</version>
</dependency>
<dependency>
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.fdl.idgnr</artifactId>
<version>${egovframework.rte.version}</version>
</dependency>
<dependency>
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.fdl.property</artifactId>
<version>${egovframework.rte.version}</version>
</dependency>
<dependency>
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.fdl.security</artifactId>
<version>${egovframework.rte.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>egovframework.rte</groupId>
<artifactId>egovframework.rte.fdl.crypto</artifactId>
<version>${egovframework.rte.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>5.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<!-- logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
<!-- <exclusions>
<exclusion>
<artifactId>commons-io</artifactId>
<groupId>commons-io</groupId>
</exclusion>
</exclusions> -->
</dependency>
<!-- Spring Security -->
<!-- <dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-webflow</artifactId>
<version>2.5.0.RELEASE</version>
</dependency> -->
<dependency>
<groupId>org.springframework.webflow</groupId>
<artifactId>spring-faces</artifactId>
<version>2.4.1.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-core</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${spring-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
<version>${spring-security.version}</version>
</dependency>
<!-- 요소기술 달력을 위한 라이브러리 -->
<dependency>
<groupId>com.ibm.icu</groupId>
<artifactId>icu4j</artifactId>
<version>53.1</version>
</dependency>
<!-- NAVER LOGIN (DIGITALSHIP JSYOO 2021.08.12) -->
<!--
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>2.8.1</version>
</dependency>
-->
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt-spring3</artifactId>
<version>1.9.2</version>
</dependency>
<!-- 제이슨 파싱 (DIGITALSHIP JSYOO 2021.08.12)-->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<!-- GOOGLE LOGIN (DIGITALSHIP JSYOO 2021.08.12) -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<!-- 바코드 ZXing (DIGITALSHIP KNKIM 2021.06.25)-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
<!-- Tiles (DIGITALSHIP KNKIM 2021.07.06)-->
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-extras</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-servlet</artifactId>
<version>3.0.8</version>
</dependency>
<dependency>
<groupId>org.apache.tiles</groupId>
<artifactId>tiles-jsp</artifactId>
<version>3.0.8</version>
</dependency>
<!-- AJAX JSON (DIGITALSHIP KNKIM 2021.07.15)-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.1</version>
</dependency>
<!-- XML/자바객체 변환 (DIGITALSHIP KNKIM 2021.06.21)-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.12.1</version>
</dependency>
<!-- DB : Maria (DIGITALSHIP KNKIM 2021.08.04)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.maven.artifact.version}</version>
</dependency>
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>2.2.5</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.lazyluke</groupId>
<artifactId>log4jdbc-remix</artifactId>
<version>0.2.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
<!-- 검색엔진 연동 (DIGITALSHIP KNKIM 2021.08.09) -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.7</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20201115</version>
</dependency>
<!-- OAuth22 Login (DIGITALSHIP KNKIM 2021.08.17) -->
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-apis</artifactId>
<!-- <version>5.6.0</version> -->
<version>8.3.1</version>
</dependency>
<dependency>
<groupId>com.github.scribejava</groupId>
<artifactId>scribejava-core</artifactId>
<version>8.3.1</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-core</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.social</groupId>
<artifactId>spring-social-web</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency>
<!-- OWASP HTML Sanitizer -->
<dependency>
<groupId>com.googlecode.owasp-java-html-sanitizer</groupId>
<artifactId>owasp-java-html-sanitizer</artifactId>
<version>20211018.2</version>
</dependency>
</dependencies>
<build>
<defaultGoal>install</defaultGoal>
<directory>${basedir}/target</directory>
<finalName>${artifactId}-${version}</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>80</port>
<path>/</path>
<systemProperties>
<JAVA_OPTS>-Xms256m -Xmx768m -XX:MaxPermSize=256m</JAVA_OPTS>
</systemProperties>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>hibernate3-maven-plugin</artifactId>
<version>2.1</version>
<configuration>
<components>
<component>
<name>hbm2ddl</name>
<implementation>annotationconfiguration</implementation>
</component>
</components>
</configuration>
<dependencies>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
</plugin>
<!-- EMMA -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>emma-maven-plugin</artifactId>
<version>1.0-alpha-3</version>
</plugin>
<!-- PMD manven plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.1</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<!-- EMMA -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
<forkMode>once</forkMode>
<reportFormat>xml</reportFormat>
<excludes>
<exclude>**/Abstract*.java</exclude>
<exclude>**/*Suite.java</exclude>
</excludes>
<includes>
<include>**/*Test.java</include>
</includes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>emma-maven-plugin</artifactId>
<inherited>true</inherited>
</plugin>
<!-- JavaDoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
</plugin>
</plugins>
</build>
<reporting>
<outputDirectory>${basedir}/target/site</outputDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
<reportSets>
<reportSet>
<id>sunlink</id>
<reports>
<report>javadoc</report>
</reports>
<inherited>true</inherited>
<configuration>
<links>
<link>http://docs.oracle.com/javase/6/docs/api/</link>
</links>
</configuration>
</reportSet>
</reportSets>
</plugin>
<!-- JUnit Test Results & EMMA Coverage Reporting -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>emma-maven-plugin</artifactId>
<inherited>true</inherited>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>surefire-report-maven-plugin</artifactId>
<inherited>true</inherited>
<reportSets>
<reportSet>
<reports>
<report>report-only</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<!-- Generating JavaDoc Report -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<minmemory>128m</minmemory>
<maxmemory>512m</maxmemory>
<encoding>${encoding}</encoding>
<docencoding>${encoding}</docencoding>
<charset>${encoding}</charset>
</configuration>
</plugin>
<!-- Generating Java Source in HTML -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<configuration>
<inputEncoding>${encoding}</inputEncoding>
<outputEncoding>${encoding}</outputEncoding>
<linkJavadoc>true</linkJavadoc>
<javadocDir>apidocs</javadocDir>
</configuration>
</plugin>
</plugins>
</reporting>
<profiles>
<!-- 운영서버 환경 빌드 설정 -->
<profile>
<id>opr</id> <!-- mvn clean install -Popr -->
<properties>
<env>opr</env>
<profile.final.name>nlibhome</profile.final.name>
</properties>
<build>
<finalName>${profile.final.name}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<!-- packaging 수행 시 lib 폴더 하위 jar 파일 제외하고 싶을 경우 사용
<packagingExcludes>WEB-INF/lib/*.jar</packagingExcludes>
-->
<!-- was 서버 deploy 위한 war 생성시 제외할 파일들 -->
<packagingExcludes>
css/, favicon/, fonts/, images/, js/, index.html
</packagingExcludes>
</configuration>
</plugin>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<!-- globals.xml 파일 -->
<delete file="${project.build.outputDirectory}/egovframework/egovProps/globals.properties"/>
<rename src="${project.build.outputDirectory}/egovframework/egovProps/globals.properties.opr" dest="${project.build.outputDirectory}/egovframework/egovProps/globals.properties"/>
<!-- context-properties.xml 파일 -->
<delete file="${project.build.outputDirectory}/nlib/nlib.properties"/>
<rename src="${project.build.outputDirectory}/nlib/nlib.properties.opr" dest="${project.build.outputDirectory}/nlib/nlib.properties"/>
<!-- context-oauth.xml 파일 -->
<delete file="${project.build.outputDirectory}/egovframework/spring/context-oauth.xml"/>
<rename src="${project.build.outputDirectory}/egovframework/spring/context-oauth.xml.opr" dest="${project.build.outputDirectory}/egovframework/spring/context-oauth.xml"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptors>
<!-- static-contents zip file -->
<descriptor>src/main/assembly/static-contents.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<!-- 운영서버 빌드 설정 end -->
</profiles>
</project>

View File

@ -0,0 +1,24 @@
<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>static</id>
<baseDirectory>/</baseDirectory>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.basedir}/target/${profile.final.name}/</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>css/**</include>
<include>favicon/**</include>
<include>fonts/**</include>
<include>images/**</include>
<include>js/**</include>
<include>index.html</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>

View File

@ -0,0 +1,185 @@
package egovframework.com.cmm;
import java.io.Serializable;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* 클래스
* @author 공통서비스개발팀 이삼섭
* @since 2009.06.01
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.3.11 이삼섭 최초 생성
*
* </pre>
*/
@SuppressWarnings("serial")
public class ComDefaultCodeVO implements Serializable {
/** 코드 ID */
private String codeId = "";
/** 상세코드 */
private String code = "";
/** 코드명 */
private String codeNm = "";
/** 코드설명 */
private String codeDc = "";
/** 특정테이블명 */
private String tableNm = ""; //특정테이블에서 코드정보를추출시 사용
/** 상세 조건 여부 */
private String haveDetailCondition = "N";
/** 상세 조건 */
private String detailCondition = "";
/**
* codeId attribute를 리턴한다.
*
* @return the codeId
*/
public String getCodeId() {
return codeId;
}
/**
* codeId attribute 값을 설정한다.
*
* @param codeId
* the codeId to set
*/
public void setCodeId(String codeId) {
this.codeId = codeId;
}
/**
* code attribute를 리턴한다.
*
* @return the code
*/
public String getCode() {
return code;
}
/**
* code attribute 값을 설정한다.
*
* @param code
* the code to set
*/
public void setCode(String code) {
this.code = code;
}
/**
* codeNm attribute를 리턴한다.
*
* @return the codeNm
*/
public String getCodeNm() {
return codeNm;
}
/**
* codeNm attribute 값을 설정한다.
*
* @param codeNm
* the codeNm to set
*/
public void setCodeNm(String codeNm) {
this.codeNm = codeNm;
}
/**
* codeDc attribute를 리턴한다.
*
* @return the codeDc
*/
public String getCodeDc() {
return codeDc;
}
/**
* codeDc attribute 값을 설정한다.
*
* @param codeDc
* the codeDc to set
*/
public void setCodeDc(String codeDc) {
this.codeDc = codeDc;
}
/**
* tableNm attribute를 리턴한다.
*
* @return the tableNm
*/
public String getTableNm() {
return tableNm;
}
/**
* tableNm attribute 값을 설정한다.
*
* @param tableNm
* the tableNm to set
*/
public void setTableNm(String tableNm) {
this.tableNm = tableNm;
}
/**
* haveDetailCondition attribute를 리턴한다.
*
* @return the haveDetailCondition
*/
public String getHaveDetailCondition() {
return haveDetailCondition;
}
/**
* haveDetailCondition attribute 값을 설정한다.
*
* @param haveDetailCondition
* the haveDetailCondition to set
*/
public void setHaveDetailCondition(String haveDetailCondition) {
this.haveDetailCondition = haveDetailCondition;
}
/**
* detailCondition attribute를 리턴한다.
*
* @return the detailCondition
*/
public String getDetailCondition() {
return detailCondition;
}
/**
* detailCondition attribute 값을 설정한다.
*
* @param detailCondition
* the detailCondition to set
*/
public void setDetailCondition(String detailCondition) {
this.detailCondition = detailCondition;
}
/**
* toString 메소드를 대치한다.
*/
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package egovframework.com.cmm;
import egovframework.rte.fdl.cmmn.exception.handler.ExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Class Name : EgovSampleExcepHndlr.java
* @Description : EgovSampleExcepHndlr Class
* @Modification Information
* @
* @ 수정일 수정자 수정내용
* @ --------- --------- -------------------------------
* @ 2009.03.16 최초생성
*
* @author 개발프레임웍크 실행환경 개발팀
* @since 2009. 03.16
* @version 1.0
* @see
*
* Copyright (C) by MOPAS All right reserved.
*/
public class EgovComExcepHndlr implements ExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(EgovComExcepHndlr.class);
/**
* @param ex
* @param packageName
* @see 개발프레임웍크 실행환경 개발팀
*/
@Override
public void occur(Exception ex, String packageName) {
LOGGER.debug(" EgovServiceExceptionHandler run...............");
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package egovframework.com.cmm;
import egovframework.rte.fdl.cmmn.exception.handler.ExceptionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Class Name : EgovSampleOthersExcepHndlr.java
* @Description : EgovSampleOthersExcepHndlr Class
* @Modification Information
* @
* @ 수정일 수정자 수정내용
* @ --------- --------- -------------------------------
* @ 2009.03.16 최초생성
*
* @author 개발프레임웍크 실행환경 개발팀
* @since 2009. 03.16
* @version 1.0
* @see
*
* Copyright (C) by MOPAS All right reserved.
*/
public class EgovComOthersExcepHndlr implements ExceptionHandler {
private static final Logger LOGGER = LoggerFactory.getLogger(EgovComOthersExcepHndlr.class);
/**
* @param exception
* @param packageName
* @see 개발프레임웍크 실행환경 개발팀
*/
@Override
public void occur(Exception exception, String packageName) {
LOGGER.debug(" EgovServiceExceptionHandler run...............");
}
}

View File

@ -0,0 +1,87 @@
package egovframework.com.cmm;
import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
/**
* 메시지 리소스 사용을 위한 MessageSource 인터페이스 ReloadableResourceBundleMessageSource 클래스의 구현체
* @author 공통서비스 개발팀 이문준
* @since 2009.06.01
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.03.11 이문준 최초 생성
* 2017.07.21 장동한 args, locale 설정
*
* </pre>
*/
public class EgovMessageSource 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 locale - 로케일
* @return String
*/
public String getMessage(String code, Locale locale) {
return getReloadableResourceBundleMessageSource().getMessage(code, null, locale);
}
/**
* 정의된 메세지 조회
* @param code - 메세지 코드
* @param args - 매개변수
* @return String
*/
public String getMessageArgs(String code, Object[] args) {
return getReloadableResourceBundleMessageSource().getMessage(code, args, Locale.getDefault());
}
/**
* 정의된 메세지 조회
* @param code - 메세지 코드
* @param args - 매개변수
* @param locale - 로케일
* @return String
*/
public String getMessageArgsLocale(String code, Object[] args, Locale locale) {
return getReloadableResourceBundleMessageSource().getMessage(code, args, locale);
}
}

View File

@ -0,0 +1,125 @@
package egovframework.com.cmm;
import java.util.regex.Pattern;
/**
* 교차접속 스크립트 공격 취약성 방지(파라미터 문자열 교체)
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ----------- -------- ---------------------------
* 2011.10.10 한성곤 최초 생성
* 2017-02-07 이정은 시큐어코딩(ES) - 시큐어코딩 경로 조작 자원 삽입[CWE-22, CWE-23, CWE-95, CWE-99]
* 2018.08.17 신용호 filePathBlackList 수정
* 2018.10.10 신용호 . => \\.으로 수정
* </pre>
*/
public class EgovWebUtil {
public static String clearXSSMinimum(String value) {
if (value == null || value.trim().equals("")) {
return "";
}
String returnValue = value;
returnValue = returnValue.replaceAll("&", "&amp;");
returnValue = returnValue.replaceAll("<", "&lt;");
returnValue = returnValue.replaceAll(">", "&gt;");
returnValue = returnValue.replaceAll("\"", "&#34;");
returnValue = returnValue.replaceAll("\'", "&#39;");
returnValue = returnValue.replaceAll("\\.", "&#46;");
returnValue = returnValue.replaceAll("%2E", "&#46;");
returnValue = returnValue.replaceAll("%2F", "&#47;");
return returnValue;
}
public static String clearXSSMaximum(String value) {
String returnValue = value;
returnValue = clearXSSMinimum(returnValue);
returnValue = returnValue.replaceAll("%00", null);
returnValue = returnValue.replaceAll("%", "&#37;");
// \\. => .
returnValue = returnValue.replaceAll("\\.\\./", ""); // ../
returnValue = returnValue.replaceAll("\\.\\.\\\\", ""); // ..\
returnValue = returnValue.replaceAll("\\./", ""); // ./
returnValue = returnValue.replaceAll("%2F", "");
return returnValue;
}
public static String filePathBlackList(String value) {
String returnValue = value;
if (returnValue == null || returnValue.trim().equals("")) {
return "";
}
returnValue = returnValue.replaceAll("\\.\\.", "");
return returnValue;
}
/**
* 행안부 보안취약점 점검 조치 방안.
*
* @param value
* @return
*/
public static String filePathReplaceAll(String value) {
String returnValue = value;
if (returnValue == null || returnValue.trim().equals("")) {
return "";
}
returnValue = returnValue.replaceAll("/", "");
returnValue = returnValue.replaceAll("\\", "");
returnValue = returnValue.replaceAll("\\.\\.", ""); // ..
returnValue = returnValue.replaceAll("&", "");
return returnValue;
}
public static String fileInjectPathReplaceAll(String value) {
String returnValue = value;
if (returnValue == null || returnValue.trim().equals("")) {
return "";
}
returnValue = returnValue.replaceAll("/", "");
returnValue = returnValue.replaceAll("\\..", ""); // ..
returnValue = returnValue.replaceAll("\\\\", "");// \
returnValue = returnValue.replaceAll("&", "");
return returnValue;
}
public static String filePathWhiteList(String value) {
return value;
}
public static boolean isIPAddress(String str) {
Pattern ipPattern = Pattern.compile("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}");
return ipPattern.matcher(str).matches();
}
public static String removeCRLF(String parameter) {
return parameter.replaceAll("\r", "").replaceAll("\n", "");
}
public static String removeSQLInjectionRisk(String parameter) {
return parameter.replaceAll("\\p{Space}", "").replaceAll("\\*", "").replaceAll("%", "").replaceAll(";", "").replaceAll("-", "").replaceAll("\\+", "").replaceAll(",", "");
}
public static String removeOSCmdRisk(String parameter) {
return parameter.replaceAll("\\p{Space}", "").replaceAll("\\*", "").replaceAll("|", "").replaceAll(";", "");
}
}

View File

@ -0,0 +1,57 @@
package egovframework.com.cmm;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import nlib.user.web.LoginController;
public class NlibLoginSuccessHandler implements AuthenticationSuccessHandler {
private static final Logger log = LoggerFactory.getLogger(LoginController.class);
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException, ServletException {
log.warn("login Test...");
// 권한을 넣을 리스트를 만듭니다
List<String> authList = new ArrayList<>();
// 디버깅 테스트
log.debug("getCredential : " + authentication.getCredentials());
log.debug("principal : " + authentication.getPrincipal());
log.debug("들어오는 사용자 : " + authentication.getName());
log.debug("가진 권한 : " + authentication.getAuthorities());
// 들어온 사용자의 권한을 authList에 추가 (여러개일 있으므로 하나씩 담음.)
authentication.getAuthorities().forEach(auth -> {
authList.add(auth.getAuthority());
});
// 관리자 경우
if (authList.contains("ROLE_ADMIN")) {
log.debug("관리자 입니다.");
response.sendRedirect("/login/admin.do");
return;
}
// 회원가입한 사용자일 경우.
if (authList.contains("ROLE_MEMBER")) {
log.warn("회원가입된 사용자 입니다.");
response.sendRedirect("/login/member.do");
return;
}
// 실패했을 경우 그대로 loginPage.jsp로 돌아갑니다.
response.sendRedirect("/");
}
}

View File

@ -0,0 +1,217 @@
package egovframework.com.cmm.service;
import java.io.Serializable;
/**
* 공통상세코드 모델 클래스
* @author 공통서비스 개발팀 이중호
* @since 2009.04.01
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.04.01 이중호 최초 생성
* 2017.09.07 이정은 표준프레임워크 v3.7 개선(clCode 추가)
*
* </pre>
*/
public class CmmnDetailCode implements Serializable {
private static final long serialVersionUID = 1L;
/*
* 분류코드
*/
private String clCode = "";
/*
* 코드ID
*/
private String codeId = "";
/*
* 코드ID명
*/
private String codeIdNm = "";
/*
* 상세코드
*/
private String code = "";
/*
* 상세코드명
*/
private String codeNm = "";
/*
* 상세코드설명
*/
private String codeDc = "";
/*
* 사용여부
*/
private String useAt = "";
/*
* 최초등록자ID
*/
private String frstRegisterId = "";
/*
* 최종수정자ID
*/
private String lastUpdusrId = "";
/**
* clCode attribute 리턴한다.
* @return String
*/
public String getClCode() {
return clCode;
}
/**
* clCode attribute 값을 설정한다.
* @param clCode String
*/
public void setClCode(String clCode) {
this.clCode = clCode;
}
/**
* codeId attribute 리턴한다.
* @return String
*/
public String getCodeId() {
return codeId;
}
/**
* codeId attribute 값을 설정한다.
* @param codeId String
*/
public void setCodeId(String codeId) {
this.codeId = codeId;
}
/**
* codeIdNm attribute 리턴한다.
* @return String
*/
public String getCodeIdNm() {
return codeIdNm;
}
/**
* codeIdNm attribute 값을 설정한다.
* @param codeIdNm String
*/
public void setCodeIdNm(String codeIdNm) {
this.codeIdNm = codeIdNm;
}
/**
* code attribute 리턴한다.
* @return String
*/
public String getCode() {
return code;
}
/**
* code attribute 값을 설정한다.
* @param code String
*/
public void setCode(String code) {
this.code = code;
}
/**
* codeNm attribute 리턴한다.
* @return String
*/
public String getCodeNm() {
return codeNm;
}
/**
* codeNm attribute 값을 설정한다.
* @param codeNm String
*/
public void setCodeNm(String codeNm) {
this.codeNm = codeNm;
}
/**
* codeDc attribute 리턴한다.
* @return String
*/
public String getCodeDc() {
return codeDc;
}
/**
* codeDc attribute 값을 설정한다.
* @param codeDc String
*/
public void setCodeDc(String codeDc) {
this.codeDc = codeDc;
}
/**
* useAt attribute 리턴한다.
* @return String
*/
public String getUseAt() {
return useAt;
}
/**
* useAt attribute 값을 설정한다.
* @param useAt String
*/
public void setUseAt(String useAt) {
this.useAt = useAt;
}
/**
* frstRegisterId attribute 리턴한다.
* @return String
*/
public String getFrstRegisterId() {
return frstRegisterId;
}
/**
* frstRegisterId attribute 값을 설정한다.
* @param frstRegisterId String
*/
public void setFrstRegisterId(String frstRegisterId) {
this.frstRegisterId = frstRegisterId;
}
/**
* lastUpdusrId attribute 리턴한다.
* @return String
*/
public String getLastUpdusrId() {
return lastUpdusrId;
}
/**
* lastUpdusrId attribute 값을 설정한다.
* @param lastUpdusrId String
*/
public void setLastUpdusrId(String lastUpdusrId) {
this.lastUpdusrId = lastUpdusrId;
}
}

View File

@ -0,0 +1,64 @@
package egovframework.com.cmm.service;
import java.util.List;
import java.util.Map;
import egovframework.com.cmm.ComDefaultCodeVO;
/**
*
* 공통코드등 전체 업무에서 공용해서 사용해야 하는 서비스를 정의하기 위한 서비스 인터페이스
* @author 공통서비스 개발팀 이삼섭
* @since 2009.04.01
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.03.11 이삼섭 최초 생성
*
* </pre>
*/
public interface EgovCmmUseService {
/**
* 공통코드를 조회한다.
*
* @param vo
* @return List(코드)
* @throws Exception
*/
public List<CmmnDetailCode> selectCmmCodeDetail(ComDefaultCodeVO vo) throws Exception;
/**
* ComDefaultCodeVO의 리스트를 받아서 여러개의 코드 리스트를 맵에 담아서 리턴한다.
*
* @param voList
* @return Map(코드)
* @throws Exception
*/
public Map<String, List<CmmnDetailCode>> selectCmmCodeDetails(List<?> voList) throws Exception;
/**
* 조직정보를 코드형태로 리턴한다.
*
* @param 조회조건정보 vo
* @return 조직정보 List
* @throws Exception
*/
public List<CmmnDetailCode> selectOgrnztIdDetail(ComDefaultCodeVO vo) throws Exception;
/**
* 그룹정보를 코드형태로 리턴한다.
*
* @param 조회조건정보 vo
* @return 그룹정보 List
* @throws Exception
*/
public List<CmmnDetailCode> selectGroupIdDetail(ComDefaultCodeVO vo) throws Exception;
}

View File

@ -0,0 +1,222 @@
package egovframework.com.cmm.service;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import egovframework.com.cmm.EgovWebUtil;
import egovframework.com.cmm.util.EgovResourceCloseHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Class Name : EgovProperties.java
* Description : properties값들을 파일로부터 읽어와 Globals클래스의 정적변수로 로드시켜주는 클래스로
* 문자열 정보 기준으로 사용할 전역변수를 시스템 재시작으로 반영할 있도록 한다.
* Modification Information
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2009.01.19 박지욱 최초 생성
* 2011.07.20 서준식 Globals파일의 상대경로를 읽은 메서드 추가
* 2014.10.13 이기하 Globals.properties 값이 null일 경우 오류처리
* 2019.04.26 신용호 RELATIVE_PATH_PREFIX Path 적용 방식 개선
* @author 공통 서비스 개발팀 박지욱
* @since 2009. 01. 19
* @version 1.0
* @see
*
*/
public class EgovProperties {
private static final Logger LOGGER = LoggerFactory.getLogger(EgovProperties.class);
//파일구분자
final static String FILE_SEPARATOR = System.getProperty("file.separator");
//프로퍼티 파일의 물리적 위치
//public static final String GLOBALS_PROPERTIES_FILE = System.getProperty("user.home") + FILE_SEPARATOR + "egovProps" +FILE_SEPARATOR + "globals.properties";
public static final String RELATIVE_PATH_PREFIX = EgovProperties.class.getResource("").getPath().substring(0, EgovProperties.class.getResource("").getPath().lastIndexOf("com"));
//public static final String RELATIVE_PATH_PREFIX = EgovProperties.class.getProtectionDomain().getCodeSource().getLocation().getPath().substring(0,EgovProperties.class.getProtectionDomain().getCodeSource().getLocation().getPath().indexOf("WEB-INF/classes/")+"WEB-INF/classes/".length())+"egovframework/";
public static final String GLOBALS_PROPERTIES_FILE = RELATIVE_PATH_PREFIX + "egovProps" + FILE_SEPARATOR + "globals.properties";
/**
* 인자로 주어진 문자열을 Key값으로 하는 상대경로 프로퍼티 값을 절대경로로 반환한다(Globals.java 전용)
* @param keyName String
* @return String
*/
public static String getPathProperty(String keyName) {
String value = "";
LOGGER.debug("getPathProperty : {} = {}", GLOBALS_PROPERTIES_FILE, keyName);
FileInputStream fis = null;
try {
Properties props = new Properties();
fis = new FileInputStream(EgovWebUtil.filePathBlackList(GLOBALS_PROPERTIES_FILE));
props.load(new BufferedInputStream(fis));
value = props.getProperty(keyName);
value = (value == null) ? "" : value.trim();//KISA 보안약점 조치 (2018-10-29, 윤창원)
value = RELATIVE_PATH_PREFIX + "egovProps" + System.getProperty("file.separator") + value;
} catch (FileNotFoundException fne) {
LOGGER.debug("Property file not found.", fne);
throw new RuntimeException("Property file not found", fne);
} catch (IOException ioe) {
LOGGER.debug("Property file IO exception", ioe);
throw new RuntimeException("Property file IO exception", ioe);
} finally {
EgovResourceCloseHelper.close(fis);
}
return value;
}
/**
* 인자로 주어진 문자열을 Key값으로 하는 프로퍼티 값을 반환한다(Globals.java 전용)
* @param keyName String
* @return String
*/
public static String getProperty(String keyName) {
String value = "";
LOGGER.debug("===>>> getProperty"+EgovProperties.class.getProtectionDomain().getCodeSource().getLocation().getPath());
LOGGER.debug("getProperty : {} = {}", GLOBALS_PROPERTIES_FILE, keyName);
FileInputStream fis = null;
try {
Properties props = new Properties();
fis = new FileInputStream(EgovWebUtil.filePathBlackList(GLOBALS_PROPERTIES_FILE));
props.load(new BufferedInputStream(fis));
if (props.getProperty(keyName) == null) {
return "";
}
value = props.getProperty(keyName).trim();
} catch (FileNotFoundException fne) {
LOGGER.debug("Property file not found.", fne);
throw new RuntimeException("Property file not found", fne);
} catch (IOException ioe) {
LOGGER.debug("Property file IO exception", ioe);
throw new RuntimeException("Property file IO exception", ioe);
} finally {
EgovResourceCloseHelper.close(fis);
}
return value;
}
/**
* 주어진 파일에서 인자로 주어진 문자열을 Key값으로 하는 프로퍼티 상대 경로값을 절대 경로값으로 반환한다
* @param fileName String
* @param key String
* @return String
*/
public static String getPathProperty(String fileName, String key) {
FileInputStream fis = null;
try {
Properties props = new Properties();
fis = new FileInputStream(EgovWebUtil.filePathBlackList(fileName));
props.load(new BufferedInputStream(fis));
fis.close();
String value = props.getProperty(key);
value = RELATIVE_PATH_PREFIX + "egovProps" + System.getProperty("file.separator") + value;
return value;
} catch (FileNotFoundException fne) {
LOGGER.debug("Property file not found.", fne);
throw new RuntimeException("Property file not found", fne);
} catch (IOException ioe) {
LOGGER.debug("Property file IO exception", ioe);
throw new RuntimeException("Property file IO exception", ioe);
} finally {
EgovResourceCloseHelper.close(fis);
}
}
/**
* 주어진 파일에서 인자로 주어진 문자열을 Key값으로 하는 프로퍼티 값을 반환한다
* @param fileName String
* @param key String
* @return String
*/
public static String getProperty(String fileName, String key) {
FileInputStream fis = null;
try {
Properties props = new Properties();
fis = new FileInputStream(EgovWebUtil.filePathBlackList(fileName));
props.load(new BufferedInputStream(fis));
fis.close();
String value = props.getProperty(key);
return value;
} catch (FileNotFoundException fne) {
LOGGER.debug("Property file not found.", fne);
throw new RuntimeException("Property file not found", fne);
} catch (IOException ioe) {
LOGGER.debug("Property file IO exception", ioe);
throw new RuntimeException("Property file IO exception", ioe);
} finally {
EgovResourceCloseHelper.close(fis);
}
}
/**
* 주어진 프로파일의 내용을 파싱하여 (key-value) 형태의 구조체 배열을 반환한다.
* @param property String
* @return ArrayList
*/
public static ArrayList<Map<String, String>> loadPropertyFile(String property) {
// key - value 형태로 배열 결과
ArrayList<Map<String, String>> keyList = new ArrayList<Map<String, String>>();
String src = property.replace('\\', File.separatorChar).replace('/', File.separatorChar);
FileInputStream fis = null;
try {
File srcFile = new File(EgovWebUtil.filePathBlackList(src));
if (srcFile.exists()) {
Properties props = new Properties();
fis = new FileInputStream(src);
props.load(new BufferedInputStream(fis));
fis.close();
Enumeration<?> plist = props.propertyNames();
if (plist != null) {
while (plist.hasMoreElements()) {
Map<String, String> map = new HashMap<String, String>();
String key = (String) plist.nextElement();
map.put(key, props.getProperty(key));
keyList.add(map);
}
}
}
} catch (IOException ex) {
LOGGER.debug("IO Exception", ex);
throw new RuntimeException(ex);
} finally {
EgovResourceCloseHelper.close(fis);
}
return keyList;
}
}

View File

@ -0,0 +1,26 @@
package egovframework.com.cmm.service;
import java.util.List;
public interface EgovUserDetailsService {
/**
* 인증된 사용자객체를 VO형식으로 가져온다.
* @return Object - 사용자 ValueObject
*/
public Object getAuthenticatedUser();
/**
* 인증된 사용자의 권한 정보를 가져온다.
* ) [ROLE_ADMIN, ROLE_USER, ROLE_A, ROLE_B, ROLE_RESTRICTED, IS_AUTHENTICATED_FULLY, IS_AUTHENTICATED_REMEMBERED, IS_AUTHENTICATED_ANONYMOUSLY]
* @return List - 사용자 권한정보 목록
*/
public List<String> getAuthorities();
/**
* 인증된 사용자 여부를 체크한다.
* @return Boolean - 인증된 사용자 여부(TRUE / FALSE)
*/
public Boolean isAuthenticated();
}

View File

@ -0,0 +1,240 @@
package egovframework.com.cmm.service;
import java.io.Serializable;
import org.apache.commons.lang3.builder.ToStringBuilder;
/**
* @Class Name : FileVO.java
* @Description : 파일정보 처리를 위한 VO 클래스
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- ------- -------------------
* 2009. 3. 25. 이삼섭
*
* @author 공통 서비스 개발팀 이삼섭
* @since 2009. 3. 25.
* @version
* @see
*
*/
@SuppressWarnings("serial")
public class FileVO implements Serializable {
/**
* 첨부파일 아이디
*/
public String atchFileId = "";
/**
* 생성일자
*/
public String creatDt = "";
/**
* 파일내용
*/
public String fileCn = "";
/**
* 파일확장자
*/
public String fileExtsn = "";
/**
* 파일크기
*/
public String fileMg = "";
/**
* 파일연번
*/
public String fileSn = "";
/**
* 파일저장경로
*/
public String fileStreCours = "";
/**
* 원파일명
*/
public String orignlFileNm = "";
/**
* 저장파일명
*/
public String streFileNm = "";
/**
* atchFileId attribute를 리턴한다.
*
* @return the atchFileId
*/
public String getAtchFileId() {
return atchFileId;
}
/**
* atchFileId attribute 값을 설정한다.
*
* @param atchFileId
* the atchFileId to set
*/
public void setAtchFileId(String atchFileId) {
this.atchFileId = atchFileId;
}
/**
* creatDt attribute를 리턴한다.
*
* @return the creatDt
*/
public String getCreatDt() {
return creatDt;
}
/**
* creatDt attribute 값을 설정한다.
*
* @param creatDt
* the creatDt to set
*/
public void setCreatDt(String creatDt) {
this.creatDt = creatDt;
}
/**
* fileCn attribute를 리턴한다.
*
* @return the fileCn
*/
public String getFileCn() {
return fileCn;
}
/**
* fileCn attribute 값을 설정한다.
*
* @param fileCn
* the fileCn to set
*/
public void setFileCn(String fileCn) {
this.fileCn = fileCn;
}
/**
* fileExtsn attribute를 리턴한다.
*
* @return the fileExtsn
*/
public String getFileExtsn() {
return fileExtsn;
}
/**
* fileExtsn attribute 값을 설정한다.
*
* @param fileExtsn
* the fileExtsn to set
*/
public void setFileExtsn(String fileExtsn) {
this.fileExtsn = fileExtsn;
}
/**
* fileMg attribute를 리턴한다.
*
* @return the fileMg
*/
public String getFileMg() {
return fileMg;
}
/**
* fileMg attribute 값을 설정한다.
*
* @param fileMg
* the fileMg to set
*/
public void setFileMg(String fileMg) {
this.fileMg = fileMg;
}
/**
* fileSn attribute를 리턴한다.
*
* @return the fileSn
*/
public String getFileSn() {
return fileSn;
}
/**
* fileSn attribute 값을 설정한다.
*
* @param fileSn
* the fileSn to set
*/
public void setFileSn(String fileSn) {
this.fileSn = fileSn;
}
/**
* fileStreCours attribute를 리턴한다.
*
* @return the fileStreCours
*/
public String getFileStreCours() {
return fileStreCours;
}
/**
* fileStreCours attribute 값을 설정한다.
*
* @param fileStreCours
* the fileStreCours to set
*/
public void setFileStreCours(String fileStreCours) {
this.fileStreCours = fileStreCours;
}
/**
* orignlFileNm attribute를 리턴한다.
*
* @return the orignlFileNm
*/
public String getOrignlFileNm() {
return orignlFileNm;
}
/**
* orignlFileNm attribute 값을 설정한다.
*
* @param orignlFileNm
* the orignlFileNm to set
*/
public void setOrignlFileNm(String orignlFileNm) {
this.orignlFileNm = orignlFileNm;
}
/**
* streFileNm attribute를 리턴한다.
*
* @return the streFileNm
*/
public String getStreFileNm() {
return streFileNm;
}
/**
* streFileNm attribute 값을 설정한다.
*
* @param streFileNm
* the streFileNm to set
*/
public void setStreFileNm(String streFileNm) {
this.streFileNm = streFileNm;
}
/**
* toString 메소드를 대치한다.
*/
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}

View File

@ -0,0 +1,58 @@
package egovframework.com.cmm.service;
/**
* Class Name : Globals.java
* Description : 시스템 구동 프로퍼티를 통해 사용될 전역변수를 정의한다.
* Modification Information
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.01.19 박지욱 최초 생성
*
* @author 공통 서비스 개발팀 박지욱
* @since 2009. 01. 19
* @version 1.0
* @see
*
*/
public class Globals {
//OS 유형
public static final String OS_TYPE = EgovProperties.getProperty("Globals.OsType");
//DB 유형
public static final String DB_TYPE = EgovProperties.getProperty("Globals.DbType");
//메인 페이지
public static final String MAIN_PAGE = EgovProperties.getProperty("Globals.MainPage");
//ShellFile 경로
public static final String SHELL_FILE_PATH = EgovProperties.getPathProperty("Globals.ShellFilePath");
//퍼로퍼티 파일 위치
public static final String CONF_PATH = EgovProperties.getPathProperty("Globals.ConfPath");
//Server정보 프로퍼티 위치
public static final String SERVER_CONF_PATH = EgovProperties.getPathProperty("Globals.ServerConfPath");
//Client정보 프로퍼티 위치
public static final String CLIENT_CONF_PATH = EgovProperties.getPathProperty("Globals.ClientConfPath");
//파일포맷 정보 프로퍼티 위치
public static final String FILE_FORMAT_PATH = EgovProperties.getPathProperty("Globals.FileFormatPath");
//파일 업로드 파일명
public static final String ORIGIN_FILE_NM = "originalFileName";
//파일 확장자
public static final String FILE_EXT = "fileExtension";
//파일크기
public static final String FILE_SIZE = "fileSize";
//업로드된 파일명
public static final String UPLOAD_FILE_NM = "uploadFileName";
//파일경로
public static final String FILE_PATH = "filePath";
//메일발송요청 XML파일경로
public static final String MAIL_REQUEST_PATH = EgovProperties.getPathProperty("Globals.MailRequestPath");
//메일발송응답 XML파일경로
public static final String MAIL_RESPONSE_PATH = EgovProperties.getPathProperty("Globals.MailRResponsePath");
// G4C 연결용 IP (localhost)
public static final String LOCAL_IP = EgovProperties.getProperty("Globals.LocalIp");
}

View File

@ -0,0 +1,62 @@
package egovframework.com.cmm.service.impl;
import java.util.List;
import egovframework.com.cmm.ComDefaultCodeVO;
import egovframework.com.cmm.service.CmmnDetailCode;
import org.springframework.stereotype.Repository;
/**
* @Class Name : CmmUseDAO.java
* @Description : 공통코드등 전체 업무에서 공용해서 사용해야 하는 서비스를 정의하기위한 데이터 접근 클래스
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- ------- -------------------
* 2009. 3. 11. 이삼섭
*
* @author 공통 서비스 개발팀 이삼섭
* @since 2009. 3. 11.
* @version
* @see
*
*/
@Repository("cmmUseDAO")
public class CmmUseDAO extends EgovComAbstractDAO {
/**
* 주어진 조건에 따른 공통코드를 불러온다.
*
* @param vo
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public List<CmmnDetailCode> selectCmmCodeDetail(ComDefaultCodeVO vo) throws Exception {
return (List<CmmnDetailCode>) list("CmmUseDAO.selectCmmCodeDetail", vo);
}
/**
* 공통코드로 사용할 조직정보를 불러온다.
*
* @param vo
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public List<CmmnDetailCode> selectOgrnztIdDetail(ComDefaultCodeVO vo) throws Exception {
return (List<CmmnDetailCode>) list("CmmUseDAO.selectOgrnztIdDetail", vo);
}
/**
* 공통코드로 사용할그룹정보를 불러온다.
* @param vo
* @return
* @throws Exception
*/
@SuppressWarnings("unchecked")
public List<CmmnDetailCode> selectGroupIdDetail(ComDefaultCodeVO vo) throws Exception {
return (List<CmmnDetailCode>) list("CmmUseDAO.selectGroupIdDetail", vo);
}
}

View File

@ -0,0 +1,91 @@
package egovframework.com.cmm.service.impl;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import egovframework.com.cmm.ComDefaultCodeVO;
import egovframework.com.cmm.service.CmmnDetailCode;
import egovframework.com.cmm.service.EgovCmmUseService;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
/**
* @Class Name : EgovCmmUseServiceImpl.java
* @Description : 공통코드등 전체 업무에서 공용해서 사용해야 하는 서비스를 정의하기위한 서비스 구현 클래스
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- ------- -------------------
* 2009. 3. 11. 이삼섭
*
* @author 공통 서비스 개발팀 이삼섭
* @since 2009. 3. 11.
* @version
* @see
*
*/
@Service("EgovCmmUseService")
public class EgovCmmUseServiceImpl extends EgovAbstractServiceImpl implements EgovCmmUseService {
@Resource(name = "cmmUseDAO")
private CmmUseDAO cmmUseDAO;
/**
* 공통코드를 조회한다.
*
* @param vo
* @return
* @throws Exception
*/
public List<CmmnDetailCode> selectCmmCodeDetail(ComDefaultCodeVO vo) throws Exception {
return cmmUseDAO.selectCmmCodeDetail(vo);
}
/**
* ComDefaultCodeVO의 리스트를 받아서 여러개의 코드 리스트를 맵에 담아서 리턴한다.
*
* @param voList
* @return
* @throws Exception
*/
public Map<String, List<CmmnDetailCode>> selectCmmCodeDetails(List<?> voList) throws Exception {
ComDefaultCodeVO vo;
Map<String, List<CmmnDetailCode>> map = new HashMap<String, List<CmmnDetailCode>>();
Iterator<?> iter = voList.iterator();
while (iter.hasNext()) {
vo = (ComDefaultCodeVO)iter.next();
map.put(vo.getCodeId(), cmmUseDAO.selectCmmCodeDetail(vo));
}
return map;
}
/**
* 조직정보를 코드형태로 리턴한다.
*
* @param 조회조건정보 vo
* @return 조직정보 List
* @throws Exception
*/
public List<CmmnDetailCode> selectOgrnztIdDetail(ComDefaultCodeVO vo) throws Exception {
return cmmUseDAO.selectOgrnztIdDetail(vo);
}
/**
* 그룹정보를 코드형태로 리턴한다.
*
* @param 조회조건정보 vo
* @return 그룹정보 List
* @throws Exception
*/
public List<CmmnDetailCode> selectGroupIdDetail(ComDefaultCodeVO vo) throws Exception {
return cmmUseDAO.selectGroupIdDetail(vo);
}
}

View File

@ -0,0 +1,306 @@
/**
*
*/
package egovframework.com.cmm.service.impl;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import egovframework.rte.psl.dataaccess.EgovAbstractMapper;
/**
* EgovComAbstractDAO.java 클래스
*
* @author 서준식
* @since 2011. 9. 23.
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- ------------- ----------------------
* 2011. 9. 23. 서준식 최초 생성
* 2016. 5. 11. 장동한 myBatis 방식 적용
* </pre>
*/
public abstract class EgovComAbstractDAO extends EgovAbstractMapper{
private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
@Resource(name="egov.sqlSession")
public void setSqlSessionFactory(SqlSessionFactory sqlSession) {
super.setSqlSessionFactory(sqlSession);
}
/**
* 입력 처리 SQL mapping 실행한다.
*
* @param queryId - 입력 처리 SQL mapping 쿼리 ID
*
* @return DBMS가 지원하는 경우 insert 적용 결과 count
*/
@Override
public int insert(String queryId) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().insert(queryId);
}
/**
* 입력 처리 SQL mapping 실행한다.
*
* @param queryId - 입력 처리 SQL mapping 쿼리 ID
* @param parameterObject - 입력 처리 SQL mapping 입력 데이터를 세팅한 파라메터 객체(보통 VO 또는 Map)
*
* @return DBMS가 지원하는 경우 insert 적용 결과 count
*/
@Override
public int insert(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().insert(queryId, parameterObject);
}
/**
* 수정 처리 SQL mapping 실행한다.
*
* @param queryId - 수정 처리 SQL mapping 쿼리 ID
*
* @return DBMS가 지원하는 경우 update 적용 결과 count
*/
@Override
public int update(String queryId) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().update(queryId);
}
/**
* 수정 처리 SQL mapping 실행한다.
*
* @param queryId - 수정 처리 SQL mapping 쿼리 ID
* @param parameterObject - 수정 처리 SQL mapping 입력 데이터(key 조건 변경 데이터) 세팅한 파라메터 객체(보통 VO 또는 Map)
*
* @return DBMS가 지원하는 경우 update 적용 결과 count
*/
@Override
public int update(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().update(queryId, parameterObject);
}
/**
* 삭제 처리 SQL mapping 실행한다.
*
* @param queryId - 삭제 처리 SQL mapping 쿼리 ID
*
* @return DBMS가 지원하는 경우 delete 적용 결과 count
*/
@Override
public int delete(String queryId) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().delete(queryId);
}
/**
* 삭제 처리 SQL mapping 실행한다.
*
* @param queryId - 삭제 처리 SQL mapping 쿼리 ID
* @param parameterObject - 삭제 처리 SQL mapping 입력 데이터(일반적으로 key 조건) 세팅한 파라메터 객체(보통 VO 또는 Map)
*
* @return DBMS가 지원하는 경우 delete 적용 결과 count
*/
@Override
public int delete(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().delete(queryId, parameterObject);
}
//CHECKSTYLE:OFF
/**
* 명명규칙에 맞춰 selectOne() 변경한다.
* @deprecated select() 메소드로 대체
*
* @see EgovAbstractMapper.selectOne()
*/
//CHECKSTYLE:ON
@Deprecated
public Object selectByPk(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectOne(queryId, parameterObject);
}
/**
* 단건조회 처리 SQL mapping 실행한다.
*
* @param queryId - 단건 조회 처리 SQL mapping 쿼리 ID
*
* @return 결과 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 단일 결과 객체(보통 VO 또는 Map)
*/
@Override
public <T> T selectOne(String queryId) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectOne(queryId);
}
/**
* 단건조회 처리 SQL mapping 실행한다.
*
* @param queryId - 단건 조회 처리 SQL mapping 쿼리 ID
* @param parameterObject - 단건 조회 처리 SQL mapping 입력 데이터(key) 세팅한 파라메터 객체(보통 VO 또는 Map)
*
* @return 결과 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 단일 결과 객체(보통 VO 또는 Map)
*/
@Override
public <T> T selectOne(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectOne(queryId, parameterObject);
}
/**
* 결과 목록을 Map 변환한다.
* 모든 구문이 파라미터를 필요로 하지는 않기 때문에, 파라미터 객체를 요구하지 않는 형태로 오버로드되었다.
*
* @param queryId - 단건 조회 처리 SQL mapping 쿼리 ID
* @param mapKey - 결과 객체의 프로퍼티 하나를 키로 사용
*
* @return 결과 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 단일 결과 객체(보통 VO 또는 Map) Map
*/
@Override
public <K, V> Map<K, V> selectMap(String queryId, String mapKey) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectMap(queryId, mapKey);
}
/**
* 결과 목록을 Map 변환한다.
* 모든 구문이 파라미터를 필요로 하지는 않기 때문에, 파라미터 객체를 요구하지 않는 형태로 오버로드되었다.
*
* @param queryId - 단건 조회 처리 SQL mapping 쿼리 ID
* @param parameterObject - 조회 처리 SQL mapping 입력 데이터(조회 조건) 세팅한 파라메터 객체(보통 VO 또는 Map)
* @param mapKey - 결과 객체의 프로퍼티 하나를 키로 사용
*
* @return 결과 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 단일 결과 객체(보통 VO 또는 Map) Map
*/
@Override
public <K, V> Map<K, V> selectMap(String queryId, Object parameterObject, String mapKey) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectMap(queryId, parameterObject, mapKey);
}
/**
* 결과 목록을 Map 변환한다.
* 모든 구문이 파라미터를 필요로 하지는 않기 때문에, 파라미터 객체를 요구하지 않는 형태로 오버로드되었다.
*
* @param queryId - 단건 조회 처리 SQL mapping 쿼리 ID
* @param parameterObject - 조회 처리 SQL mapping 입력 데이터(조회 조건) 세팅한 파라메터 객체(보통 VO 또는 Map)
* @param mapKey - 결과 객체의 프로퍼티 하나를 키로 사용
* @param rowBounds - 특정 개수 만큼의 레코드를 건너띄게
*
* @return 결과 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 단일 결과 객체(보통 VO 또는 Map) Map
*/
@Override
public <K, V> Map<K, V> selectMap(String queryId, Object parameterObject, String mapKey, RowBounds rowBounds) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectMap(queryId, parameterObject, mapKey, rowBounds);
}
//CHECKSTYLE:OFF
/**
* 명명규칙에 맞춰 selectList() 변경한다.
*
* @see EgovAbstractMapper.selectList()
* @deprecated List<?> 메소드로 대체
*/
//CHECKSTYLE:ON
@Deprecated
public List<?> list(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectList(queryId, parameterObject);
}
/**
* 리스트 조회 처리 SQL mapping 실행한다.
*
* @param queryId - 리스트 조회 처리 SQL mapping 쿼리 ID
*
* @return 결과 List 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 결과 객체(보통 VO 또는 Map) List
*/
@Override
public <E> List<E> selectList(String queryId) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectList(queryId);
}
/**
* 리스트 조회 처리 SQL mapping 실행한다.
*
* @param queryId - 리스트 조회 처리 SQL mapping 쿼리 ID
* @param parameterObject - 리스트 조회 처리 SQL mapping 입력 데이터(조회 조건) 세팅한 파라메터 객체(보통 VO 또는 Map)
*
* @return 결과 List 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 결과 객체(보통 VO 또는 Map) List
*/
@Override
public <E> List<E> selectList(String queryId, Object parameterObject) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectList(queryId, parameterObject);
}
/**
* 리스트 조회 처리 SQL mapping 실행한다.
*
* @param queryId - 리스트 조회 처리 SQL mapping 쿼리 ID
* @param parameterObject - 리스트 조회 처리 SQL mapping 입력 데이터(조회 조건) 세팅한 파라메터 객체(보통 VO 또는 Map)
* @param rowBounds - 특정 개수 만큼의 레코드를 건너띄게
*
* @return 결과 List 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 결과 객체(보통 VO 또는 Map) List
*/
@Override
public <E> List<E> selectList(String queryId, Object parameterObject, RowBounds rowBounds) {
LOGGER.debug("queryId = "+queryId);
return getSqlSession().selectList(queryId, parameterObject, rowBounds);
}
/**
* 부분 범위 리스트 조회 처리 SQL mapping 실행한다.
* (부분 범위 - pageIndex pageSize 기반으로 현재 부분 범위 조회를 위한 skipResults, maxResults 계산하여 ibatis 호출)
*
* @param queryId - 리스트 조회 처리 SQL mapping 쿼리 ID
* @param parameterObject - 리스트 조회 처리 SQL mapping 입력 데이터(조회 조건) 세팅한 파라메터 객체(보통 VO 또는 Map)
* @param pageIndex - 현재 페이지 번호
* @param pageSize - 페이지 조회 (pageSize)
*
* @return 부분 범위 결과 List 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 부분 범위 결과 객체(보통 VO 또는 Map) List
*/
@Override
public List<?> listWithPaging(String queryId, Object parameterObject, int pageIndex, int pageSize) {
LOGGER.debug("queryId = "+queryId);
int skipResults = pageIndex * pageSize;
//int maxResults = (pageIndex * pageSize) + pageSize;
RowBounds rowBounds = new RowBounds(skipResults, pageSize);
return getSqlSession().selectList(queryId, parameterObject, rowBounds);
}
/**
* SQL 조회 결과를 ResultHandler를 이용해서 출력한다.
* ResultHandler를 상속해 구현한 커스텀 핸들러의 handleResult() 메서드에 따라 실행된다.
*
* @param queryId - 리스트 조회 처리 SQL mapping 쿼리 ID
* @param handler - 조회 결과를 제어하기 위해 구현한 ResultHandler
* @return
*
* @return 결과 List 객체 - SQL mapping 파일에서 지정한 resultType/resultMap 의한 결과 객체(보통 VO 또는 Map) List
*/
@Override
public void listToOutUsingResultHandler(String queryId, ResultHandler handler) {
LOGGER.debug("queryId = "+queryId);
getSqlSession().select(queryId, handler);
}
}

View File

@ -0,0 +1,83 @@
package egovframework.com.cmm.util;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Utility class to support to logging information
* @author Vincent Han
* @since 2014.09.18
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2014.09.18 표준프레임워크센터 최초 생성
*
* </pre>
*/
public class EgovBasicLogger {
private static final Level IGNORE_INFO_LEVEL = Level.OFF;
private static final Level DEBUG_INFO_LEVEL = Level.FINEST;
private static final Level INFO_INFO_LEVEL = Level.INFO;
private static final Logger ignoreLogger = Logger.getLogger("ignore");
private static final Logger debugLogger = Logger.getLogger("debug");
private static final Logger infoLogger = Logger.getLogger("info");
/**
* 기록이나 처리가 불필요한 경우 사용.
* @param message
* @param exception
*/
public static void ignore(String message, Exception exception) {
if (exception == null) {
ignoreLogger.log(IGNORE_INFO_LEVEL, message);
} else {
ignoreLogger.log(IGNORE_INFO_LEVEL, message, exception);
}
}
/**
* 기록이나 처리가 불필요한 경우 사용.
* @param message
* @param exception
*/
public static void ignore(String message) {
ignore(message, null);
}
/**
* 디버그 정보를 기록하는 경우 사용.
* @param message
* @param exception
*/
public static void debug(String message, Exception exception) {
if (exception == null) {
debugLogger.log(DEBUG_INFO_LEVEL, message);
} else {
debugLogger.log(DEBUG_INFO_LEVEL, message, exception);
}
}
/**
* 디버그 정보를 기록하는 경우 사용.
* @param message
* @param exception
*/
public static void debug(String message) {
debug(message, null);
}
/**
* 일반적이 정보를 기록하는 경우 사용.
* @param message
* @param exception
*/
public static void info(String message) {
infoLogger.log(INFO_INFO_LEVEL, message);
}
}

View File

@ -0,0 +1,146 @@
package egovframework.com.cmm.util;
import java.io.Closeable;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Wrapper;
/**
* Utility class to support to close resources
* @author Vincent Han
* @since 2014.09.18
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2014.09.18 표준프레임워크센터 최초 생성
*
* </pre>
*/
public class EgovResourceCloseHelper {
/**
* Resource close 처리.
* @param resources
*/
public static void close(Closeable ... resources) {
for (Closeable resource : resources) {
if (resource != null) {
try {
resource.close();
} catch (IOException ignore) {//KISA 보안약점 조치 (2018-10-29, 윤창원)
EgovBasicLogger.ignore("Occurred IOException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ingored!!");
}
}
}
}
/**
* JDBC 관련 resource 객체 close 처리
* @param objects
*/
public static void closeDBObjects(Wrapper ... objects) {
for (Object object : objects) {
if (object != null) {
if (object instanceof ResultSet) {
try {
((ResultSet)object).close();
} catch (SQLException ignore) {//KISA 보안약점 조치 (2018-10-29, 윤창원)
EgovBasicLogger.ignore("Occurred SQLException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ingored!!");
}
} else if (object instanceof Statement) {
try {
((Statement)object).close();
} catch (SQLException ignore) {//KISA 보안약점 조치 (2018-10-29, 윤창원)
EgovBasicLogger.ignore("Occurred SQLException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ingored!!");
}
} else if (object instanceof Connection) {
try {
((Connection)object).close();
} catch (SQLException ignore) {
EgovBasicLogger.ignore("Occurred SQLException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ingored!!");
}
} else {
throw new IllegalArgumentException("Wrapper type is not found : " + object.toString());
}
}
}
}
/**
* Socket 관련 resource 객체 close 처리
* @param objects
*/
public static void closeSocketObjects(Socket socket, ServerSocket server) {
if (socket != null) {
try {
socket.shutdownOutput();
} catch (IOException ignore) {
EgovBasicLogger.ignore("Occurred IOException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to shutdown ouput is ignored!!");
}
try {
socket.close();
} catch (IOException ignore) {
EgovBasicLogger.ignore("Occurred IOException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ignored!!");
}
}
if (server != null) {
try {
server.close();
} catch (IOException ignore) {
EgovBasicLogger.ignore("Occurred IOException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ignored!!");
}
}
}
/**
* Socket 관련 resource 객체 close 처리
*
* @param sockets
*/
public static void closeSockets(Socket ... sockets) {
for (Socket socket : sockets) {
if (socket != null) {
try {
socket.shutdownOutput();
} catch (IOException ignore) {
EgovBasicLogger.ignore("Occurred IOException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to shutdown ouput is ignored!!");
}
try {
socket.close();
} catch (IOException ignore) {
EgovBasicLogger.ignore("Occurred IOException to close resource is ingored!!");
} catch (Exception ignore) {
EgovBasicLogger.ignore("Occurred Exception to close resource is ignored!!");
}
}
}
}
}

View File

@ -0,0 +1,61 @@
package egovframework.com.cmm.util;
import java.util.List;
import egovframework.com.cmm.service.EgovUserDetailsService;
/**
* EgovUserDetails Helper 클래스
*
* @author sjyoon
* @since 2009.06.01
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- ------------- ----------------------
* 2009.03.10 sjyoon 최초 생성
* 2011.07.01 서준식 interface 생성후 상세 로직의 분리
* </pre>
*/
public class EgovUserDetailsHelper {
static EgovUserDetailsService egovUserDetailsService;
public EgovUserDetailsService getEgovUserDetailsService() {
return egovUserDetailsService;
}
public void setEgovUserDetailsService(EgovUserDetailsService egovUserDetailsService) {
EgovUserDetailsHelper.egovUserDetailsService = egovUserDetailsService;
}
/**
* 인증된 사용자객체를 VO형식으로 가져온다.
* @return Object - 사용자 ValueObject
*/
public static Object getAuthenticatedUser() {
return egovUserDetailsService.getAuthenticatedUser();
}
/**
* 인증된 사용자의 권한 정보를 가져온다.
*
* @return List - 사용자 권한정보 목록
*/
public static List<String> getAuthorities() {
return egovUserDetailsService.getAuthorities();
}
/**
* 인증된 사용자 여부를 체크한다.
* @return Boolean - 인증된 사용자 여부(TRUE / FALSE)
*/
public static Boolean isAuthenticated() {
return egovUserDetailsService.isAuthenticated();
}
}

View File

@ -0,0 +1,60 @@
/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package egovframework.com.cmm.web;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.context.request.WebRequest;
/**
* @Class Name : EgovBindingInitializer.java
* @Description : EgovBindingInitializer Class
* @Modification Information
* @
* @ 수정일 수정자 수정내용
* @ --------- --------- -------------------------------
* @ 2009.03.16 최초생성
*
* @author 개발프레임웍크 실행환경 개발팀
* @since 2009. 03.16
* @version 1.0
* @see
*
* Copyright (C) by MOPAS All right reserved.
*/
public class EgovBindingInitializer implements WebBindingInitializer {
/**
* initBinder
* @param binder
* @param request
* @see 개발프레임웍크 실행환경 개발팀
*/
@Override
public void initBinder(WebDataBinder binder, WebRequest request) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
binder.registerCustomEditor(String.class, new StringTrimmerEditor(false));
}
}

View File

@ -0,0 +1,93 @@
package egovframework.com.cmm.web;
import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import egovframework.com.cmm.EgovWebUtil;
import egovframework.rte.fdl.property.EgovPropertyService;
/**
* @Class Name : EgovComUtlController.java
* @Description : 공통유틸리티성 작업을 위한 Controller
* @Modification Information
* @
* @ 수정일 수정자 수정내용
* @ ---------- -------- ---------------------------
* 2009.03.02 조재영 최초 생성
* 2011.10.07 이기하 .action -> .do로 변경하면서 동일 매핑이 되어 삭제처리
* 2015.11.12 김연호 한국인터넷진흥원 취약점 개선
* 2019.04.25 신용호 moveToPage() 화이트리스트 처리
*
* @author 공통서비스 개발팀 조재영
* @since 2009.03.02
* @version 1.0
* @see
*
*/
@Controller
public class EgovComUtlController {
//@Resource(name = "egovUserManageService")
//private EgovUserManageService egovUserManageService;
private static final Logger LOGGER = LoggerFactory.getLogger(EgovComUtlController.class);
@Resource(name = "egovPageLinkWhitelist")
protected List<String> egovWhitelist;
/** EgovPropertyService */
@Resource(name = "propertiesService")
protected EgovPropertyService propertiesService;
/**
* JSP 호출작업만 처리하는 공통 함수
*/
@RequestMapping(value="/EgovPageLink.do")
public String moveToPage(@RequestParam("link") String linkPage){
String link = linkPage;
link = link.replace(";", "");
link = link.replace(".", "");
// service 사용하여 리턴할 결과값 처리하는 부분은 생략하고 단순 페이지 링크만 처리함
if (linkPage==null || linkPage.equals("")){
link="egovframework/com/cmm/egovError";
}
// 화이트 리스트 처리
// whitelist목록에 있는 경우 결과가 true, 결과가 false인경우 FAIL처리
if (egovWhitelist.contains(linkPage) == false) {
LOGGER.debug("Page Link WhiteList Error! Please check whitelist!");
link="egovframework/com/cmm/egovError";
}
// 안전한 경로 문자열로 조치
link = EgovWebUtil.filePathBlackList(link);
return link;
}
/**
* 모달조회
* @return String
* @exception Exception
*/
@RequestMapping(value="/EgovModal.do")
public String selectUtlJsonInquire() throws Exception {
return "egovframework/com/cmm/EgovModal";
}
/**
* validato rule dynamic Javascript
*/
@RequestMapping("/validator.do")
public String validate(){
return "egovframework/com/cmm/validator";
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2008-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package egovframework.com.cmm.web;
import egovframework.rte.ptl.mvc.tags.ui.pagination.AbstractPaginationRenderer;
import javax.servlet.ServletContext;
import org.springframework.web.context.ServletContextAware;
/**
* @Class Name : ImagePaginationRenderer.java
* @Description : ImagePaginationRenderer Class
* @Modification Information
* @
* @ 수정일 수정자 수정내용
* @ --------- --------- -------------------------------
* @ 2009.03.16 최초생성
*
* @author 개발프레임웍크 실행환경 개발팀
* @since 2009. 03.16
* @version 1.0
* @see
*
* Copyright (C) by MOPAS All right reserved.
*/
public class EgovImgPaginationRenderer extends AbstractPaginationRenderer implements ServletContextAware{
private ServletContext servletContext;
public EgovImgPaginationRenderer() {
// no-op
}
/**
* PaginationRenderer
*
* @see 개발프레임웍크 실행환경 개발팀
*/
public void initVariables() {
firstPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">" + "<image src='" + servletContext.getContextPath() + "/images/egovframework/cmmn/btn_page_pre10.gif' border=0/></a>&#160;";
previousPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">" + "<image src='" + servletContext.getContextPath() + "/images/egovframework/cmmn/btn_page_pre1.gif' border=0/></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;\">" + "<image src='" + servletContext.getContextPath() + "/images/egovframework/cmmn/btn_page_next1.gif' border=0/></a>&#160;";
lastPageLabel = "<a href=\"#\" onclick=\"{0}({1}); return false;\">" + "<image src='" + servletContext.getContextPath() + "/images/egovframework/cmmn/btn_page_next10.gif' border=0/></a>&#160;";
}
@Override
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
initVariables();
}
}

View File

@ -0,0 +1,52 @@
/*
* eGovFrame OAuth
* Copyright The eGovFrame Open Community (http://open.egovframe.go.kr)).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @author 이기하(슈퍼개발자K3)
*/
package egovframework.com.ext.oauth.service;
import org.springframework.social.connect.UserProfile;
import org.springframework.web.context.request.WebRequest;
/**
* 소셜 계정으로 일반회원 가입을 처리하는 비즈니스 인터페이스 클래스
* @author 이기하
* @since 2014.10.08
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ----------- -------- ---------------------------
* 2014.10.08 이기하 최초 생성
* </pre>
*/
public interface EgovSignupService {
/**
* 소셜 계정으로 일반회원 가입을 처리한다
* @param UserProfile profile
* @param WebRequest request
* @param String key
* @return String
* @exception Exception
*/
public String signup(UserProfile profile, WebRequest request, String key) throws Exception;
}

View File

@ -0,0 +1,54 @@
package egovframework.com.ext.oauth.service;
import java.util.Map;
import com.github.scribejava.core.builder.api.DefaultApi20;
import com.github.scribejava.core.model.OAuthConstants;
import com.github.scribejava.core.model.ParameterList;
public class KakaoAPI20 extends DefaultApi20 implements OAuthConfig {
private String apiKey = "";
private KakaoAPI20() {
}
private static class InstanceHolder {
private static final KakaoAPI20 INSTANCE = new KakaoAPI20();
}
public static KakaoAPI20 instance() {
return InstanceHolder.INSTANCE;
}
@Override
public String getAccessTokenEndpoint() {
return KAKAO_ACCESS_TOKEN+apiKey;
}
@Override
protected String getAuthorizationBaseUrl() {
return KAKAO_AUTH;
}
public String getAuthorizationUrl(String responseType, String apiKey, String callback, String scope, String state,
Map<String, String> additionalParams) {
this.apiKey = apiKey;
final ParameterList parameters = new ParameterList(additionalParams);
parameters.add(OAuthConstants.RESPONSE_TYPE, responseType);
parameters.add(OAuthConstants.CLIENT_ID, apiKey);
if (callback != null) {
parameters.add(OAuthConstants.REDIRECT_URI, callback);
}
if (scope != null) {
parameters.add(OAuthConstants.SCOPE, scope);
}
if (state != null) {
parameters.add(OAuthConstants.STATE, state);
}
return parameters.appendTo(getAuthorizationBaseUrl());
}
}

View File

@ -0,0 +1,50 @@
package egovframework.com.ext.oauth.service;
import java.util.Map;
import com.github.scribejava.core.builder.api.DefaultApi20;
import com.github.scribejava.core.model.OAuthConstants;
import com.github.scribejava.core.model.ParameterList;
public class NaverAPI20 extends DefaultApi20 implements OAuthConfig {
private NaverAPI20() {
}
private static class InstanceHolder {
private static final NaverAPI20 INSTANCE = new NaverAPI20();
}
public static NaverAPI20 instance() {
return InstanceHolder.INSTANCE;
}
@Override
public String getAccessTokenEndpoint() {
return NAVER_ACCESS_TOKEN;
}
@Override
protected String getAuthorizationBaseUrl() {
return NAVER_AUTH;
}
public String getAuthorizationUrl(String responseType, String apiKey, String callback, String scope, String state,
Map<String, String> additionalParams) {
final ParameterList parameters = new ParameterList(additionalParams);
parameters.add(OAuthConstants.RESPONSE_TYPE, responseType);
parameters.add(OAuthConstants.CLIENT_ID, apiKey);
if (callback != null) {
parameters.add(OAuthConstants.REDIRECT_URI, callback);
}
if (scope != null) {
parameters.add(OAuthConstants.SCOPE, scope);
}
if (state != null) {
parameters.add(OAuthConstants.STATE, state);
}
return parameters.appendTo(getAuthorizationBaseUrl());
}
}

View File

@ -0,0 +1,21 @@
package egovframework.com.ext.oauth.service;
import nlib.cmm.service.NlibProperty;
public interface OAuthConfig {
static final String GOOGLE_SERVICE_NAME = NlibProperty.getString("oauth2.client.provider.google.name");
static final String GOOGLE_PROFILE_URL = NlibProperty.getString("oauth2.client.provider.google.user-info-uri"); // "https://www.googleapis.com/plus/v1/people/me";
static final String NAVER_SERVICE_NAME = NlibProperty.getString("oauth2.client.provider.naver.name");
static final String NAVER_PROFILE_URL = NlibProperty.getString("oauth2.client.provider.naver.user-info-uri"); // "https://openapi.naver.com/v1/nid/me";
static final String NAVER_ACCESS_TOKEN = NlibProperty.getString("oauth2.client.provider.naver.token-uri"); // "https://nid.naver.com/oauth2.0/token?grant_type=authorization_code";
static final String NAVER_AUTH = NlibProperty.getString("oauth2.client.provider.naver.authorization-uri"); // "https://nid.naver.com/oauth2.0/authorize";
static final String KAKAO_SERVICE_NAME = NlibProperty.getString("oauth2.client.provider.kakao.name");
static final String KAKAO_PROFILE_URL = NlibProperty.getString("oauth2.client.provider.kakao.user-info-uri"); // "https://kapi.kakao.com/v2/user/me";
static final String KAKAO_ACCESS_TOKEN = NlibProperty.getString("oauth2.client.provider.kakao.token-uri"); // "https://kauth.kakao.com/oauth/token?client_id=";
static final String KAKAO_AUTH = NlibProperty.getString("oauth2.client.provider.kakao.authorization-uri"); // "https://kauth.kakao.com/oauth/authorize";
}

View File

@ -0,0 +1,223 @@
package egovframework.com.ext.oauth.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.scribejava.core.builder.ScopeBuilder;
import com.github.scribejava.core.builder.ServiceBuilder;
import com.github.scribejava.core.model.OAuth2AccessToken;
import com.github.scribejava.core.model.OAuthRequest;
import com.github.scribejava.core.model.Response;
import com.github.scribejava.core.model.Verb;
import com.github.scribejava.core.oauth.OAuth20Service;
import nlib.user.web.LoginController;
import nlib.util.StringUtil;
public class OAuthLogin {
/** SNS 호출 시, URL callType 대체 문자열 */
public static final String CALL_TYPE_LOGIN = "login";
public static final String CALL_TYPE_MEMBER = "member";
private static final Logger log = LoggerFactory.getLogger(OAuthLogin.class);
private OAuth20Service oauthService;
private OAuthVO oauthVO;
public OAuthLogin(OAuthVO oauthVO, String callType) {
this(oauthVO, callType, null);
}
public OAuthLogin(OAuthVO oauthVO, String callType, String councilJsessionId) {
if(oauthVO.getService().equals("google"))
{
ScopeBuilder scope = new ScopeBuilder();
scope.withScope("profile");
scope.withScope("openid");
scope.withScope("email");
//scope.withScope("https://www.googleapis.com/auth/user.phonenumbers.read");
//scope.withScope("https://www.googleapis.com/auth/user.birthday.read");
this.oauthService = new ServiceBuilder(oauthVO.getClientId())
.apiSecret(oauthVO.getClientSecret())
.callback(oauthVO.getRedirectUrl(callType, councilJsessionId))
.defaultScope(scope)
//.scope("profile")
.build(oauthVO.getApi20Instance());
} else if(oauthVO.getService().equals("kakao") || oauthVO.getService().equals("naver")) {
this.oauthService = new ServiceBuilder(oauthVO.getClientId())
.apiSecret(oauthVO.getClientSecret())
.callback(oauthVO.getRedirectUrl(callType, councilJsessionId))
//.scope("profile")
.build(oauthVO.getApi20Instance());
}
this.oauthVO = oauthVO;
}
public String getOAuthURL(String state) {
return this.oauthService.getAuthorizationUrl(state);
}
public OAuthUniversalUser getUserProfile(String code) throws Exception {
log.debug("getUserProfile > getAccessToken");
OAuth2AccessToken accessToken = oauthService.getAccessToken(code);
log.debug("getUserProfile > getAccessToken2");
OAuthRequest request = new OAuthRequest(Verb.GET, this.oauthVO.getProfileUrl());
oauthService.signRequest(accessToken, request);
Response response = oauthService.execute(request);
return parseJson(response.getBody());
}
private OAuthUniversalUser parseJson(String body) throws Exception {
OAuthUniversalUser user = new OAuthUniversalUser();
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = mapper.readTree(body);
if (this.oauthVO.isNaver()) {
//------------------------------------
// 네이버
//------------------------------------
user.setSnsType(OAuthConfig.NAVER_SERVICE_NAME);
JsonNode resNode = rootNode.get("response");
// 사용자 내부 고유 ID (: kh3lhfSg2v7TnJLmdhH7a0HyL-1zExIS4cF1mD4Hi4Y)
user.setSnsId(resNode.get("id").asText());
// 사용자로그인ID (메일형식) : 네이버 계정 제공하지 않으므로 연락처 이메일을 기본 메일 계정으로 설정
if (resNode.has("email")) {
user.setSnsUserId(StringUtil.getString(resNode.get("email").asText(), ""));
// 메일주소
user.setSnsEmail(StringUtil.getString(resNode.get("email").asText(), ""));
}
// 사용자명 (: 홍길동)
if (resNode.has("name")) {
user.setSnsName(StringUtil.getString(resNode.get("name").asText(), ""));
}
// 생년월일
String birthday ="0000";
String birthyear = "0000";
if (resNode.has("birthday")) {
birthday = StringUtil.getString(resNode.get("birthday").asText(), "0000");
}
if (resNode.has("birthyear")) {
birthyear = StringUtil.getString(resNode.get("birthyear").asText(), "0000");
}
birthday = birthday.replaceAll("-", "");
if(birthday.length() != 4) birthday = "0000";
if(birthyear.length() != 4) birthyear = "0000";
user.setSnsBirthday(birthyear + birthday);
// 성별
if (resNode.has("gender")) {
user.setSnsGender(StringUtil.getString(resNode.get("gender").asText(), ""));
}
//휴대폰번호
if (resNode.has("mobile")) {
String mobile = StringUtil.getString(resNode.get("mobile").asText(), "");
if(mobile != "")
{
mobile = mobile.replaceAll("-", "");
user.setSnsMobileNo(mobile);
}
}
// 로그인 성공
user.setValidLogin(true);
} else if (this.oauthVO.isGoogle()) {
//------------------------------------
// 구글
//------------------------------------
user.setSnsType(OAuthConfig.GOOGLE_SERVICE_NAME);
if (rootNode.has("sub"))
user.setSnsId(StringUtil.getString(rootNode.get("sub").asText(), ""));
if (rootNode.has("email"))
user.setSnsUserId(StringUtil.getString(rootNode.get("email").asText(), ""));
if (rootNode.has("name"))
user.setSnsName(StringUtil.getString(rootNode.get("name").asText(), ""));
} else if (this.oauthVO.isKakao()) {
//------------------------------------
// 카카오
//------------------------------------
user.setSnsType(OAuthConfig.KAKAO_SERVICE_NAME);
JsonNode resNode = rootNode.get("kakao_account");
if(rootNode.has("id")) {
user.setSnsId((rootNode.get("id").asText() == null) ? "" : rootNode.get("id").asText());
}
if (resNode.has("email")) {
user.setSnsUserId(StringUtil.getString(resNode.get("email").asText(), ""));
user.setSnsEmail(StringUtil.getString(resNode.get("email").asText(), ""));
}
if (resNode.has("gender"))
{
user.setSnsGender(StringUtil.getString(resNode.get("gender").asText(), ""));
if(user.getSnsGender().equals("male"))
{
user.setSnsGender("M");
}else if(user.getSnsGender().equals("female"))
{
user.setSnsGender("F");
}
}
// 생년월일
String birthday ="0000";
String birthyear = "0000";
if (resNode.has("birthday")) {
birthday = StringUtil.getString(resNode.get("birthday").asText(), "0000");
}
if (resNode.has("birthyear")) {
birthyear = StringUtil.getString(resNode.get("birthyear").asText(), "0000");
}
birthday = birthday.replaceAll("-", "");
if(birthday.length() != 4) birthday = "0000";
if(birthyear.length() != 4) birthyear = "0000";
user.setSnsBirthday(birthyear + birthday);
if (resNode.has("phone_number"))
user.setSnsMobileNo(StringUtil.getString(resNode.get("phone_number").asText(), ""));
}
return user;
}
/**
* URL에 매개변수를 GET 방식으로 추가하여 리턴한다.
*
* @param url
* @param paramName
* @param paramValue
* @return
*/
public String appendUrlParam(String url, String paramName, String paramValue) {
if(StringUtil.isEmpty(url)) return "";
if(StringUtil.isEmpty(paramName)) return url;
if(StringUtil.isEmpty(paramValue)) paramValue = "";
if(url.contains("?")) url += "&";
else url += "?";
url += paramName + "=" + paramValue;
return url;
}
}

View File

@ -0,0 +1,202 @@
package egovframework.com.ext.oauth.service;
import java.util.Date;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
public class OAuthUniversalUser {
private String mbSnsId;
private String mbInfoId;
private String snsId;
private String snsEmail;
private String snsUserId;
private String snsName;
private String snsNickName;
private String snsBirthday;
private String snsGender;
private String snsType;
private String snsMobileNo;
private String loginIp;
private Date lastLogin;
private String regDd;
private NlibLoginVO nlibVO;
private String councilJsessionId; /* 로그인 접속 문화원 코드 */
private String councilHomeUrl; /* 로그인 접속 문화원 홈 URL */
private boolean isValidLogin = false;
public boolean isValid() {
return StringUtil.isNotEmpty(snsId);
}
public String getMbInfoId() {
return mbInfoId;
}
public void setMbInfoId(String mbInfoId) {
this.mbInfoId = mbInfoId;
}
public String getSnsId() {
return snsId;
}
public void setSnsId(String snsId) {
this.snsId = snsId;
}
public String getSnsEmail() {
return snsEmail;
}
public void setSnsEmail(String email) {
this.snsEmail = email;
}
public String getSnsUserId() {
return snsUserId;
}
public void setSnsUserId(String snsUserId) {
this.snsUserId = snsUserId;
}
public String getSnsName() {
return snsName;
}
public void setSnsName(String snsName) {
this.snsName = snsName;
}
public String getSnsNickName() {
return snsNickName;
}
public void setSnsNickName(String snsNickName) {
this.snsNickName = snsNickName;
}
public String getSnsType() {
return snsType;
}
public void setSnsType(String snsType) {
this.snsType = snsType;
}
public String getLoginip() {
return loginIp;
}
public void setLoginip(String loginIp) {
this.loginIp = loginIp;
}
public Date getLastlogin() {
return lastLogin;
}
public void setLastlogin(Date lastLogin) {
this.lastLogin = lastLogin;
}
public String getSnsBirthday() {
return snsBirthday;
}
public void setSnsBirthday(String snsBirthday) {
this.snsBirthday = snsBirthday;
}
public String getLoginIp() {
return loginIp;
}
public void setLoginIp(String loginIp) {
this.loginIp = loginIp;
}
public Date getLastLogin() {
return lastLogin;
}
public void setLastLogin(Date lastLogin) {
this.lastLogin = lastLogin;
}
public String getSnsGender() {
return snsGender;
}
public void setSnsGender(String snsGender) {
this.snsGender = snsGender;
}
public boolean isValidLogin() {
return isValidLogin;
}
public void setValidLogin(boolean isValidLogin) {
this.isValidLogin = isValidLogin;
}
public String getSnsMobileNo() {
return snsMobileNo;
}
public void setSnsMobileNo(String snsMobileNo) {
this.snsMobileNo = snsMobileNo;
}
public NlibLoginVO getNlibVO() {
return nlibVO;
}
public void setNlibVO(NlibLoginVO nlibVO) {
this.nlibVO = nlibVO;
}
public String getMbSnsId() {
return mbSnsId;
}
public void setMbSnsId(String mbSnsId) {
this.mbSnsId = mbSnsId;
}
public String getRegDd() {
return regDd;
}
public void setRegDd(String regDd) {
this.regDd = regDd;
}
public String getCouncilJsessionId() {
return councilJsessionId;
}
public void setCouncilJsessionId(String councilJsessionId) {
this.councilJsessionId = councilJsessionId;
}
public String getCouncilHomeUrl() {
return councilHomeUrl;
}
public void setCouncilHomeUrl(String councilHomeUrl) {
this.councilHomeUrl = councilHomeUrl;
}
}

View File

@ -0,0 +1,130 @@
package egovframework.com.ext.oauth.service;
import com.github.scribejava.apis.GoogleApi20;
import com.github.scribejava.core.builder.api.DefaultApi20;
import nlib.cmm.crypto.AriaCrypto;
import nlib.util.StringUtil;
public class OAuthVO implements OAuthConfig {
private String serviceName;
private String clientId;
private String clientSecret;
private String redirectUrl;
private String state;
private DefaultApi20 api20Instance;
private String profileUrl;
private boolean isNaver;
private boolean isGoogle;
private boolean isKakao;
public OAuthVO(String serviceName, String clientId, String clientSecret, String redirectUrl) {
this.serviceName = serviceName;
this.clientId = clientId;
this.clientSecret = clientSecret;
this.redirectUrl = redirectUrl;
this.state = state;
this.isGoogle = StringUtil.equalsIgnoreCase(GOOGLE_SERVICE_NAME, serviceName);
this.isNaver = StringUtil.equalsIgnoreCase(NAVER_SERVICE_NAME, serviceName);
this.isKakao = StringUtil.equalsIgnoreCase(KAKAO_SERVICE_NAME, serviceName);
if (isGoogle) {
this.api20Instance = GoogleApi20.instance();
this.profileUrl = GOOGLE_PROFILE_URL;
} else if (isNaver) {
this.api20Instance = NaverAPI20.instance();
this.profileUrl = NAVER_PROFILE_URL;
} else if (isKakao) {
this.api20Instance = KakaoAPI20.instance();
this.profileUrl = KAKAO_PROFILE_URL;
}
}
// GET / SET
public String getService() {
return serviceName;
}
public void setService(String service) {
this.serviceName = service;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getRedirectUrl(String callType, String councilJsessionId) {
String retUrl = redirectUrl.replaceAll("\\{callType\\}", callType);
retUrl = retUrl.replaceAll("\\{oauthServiceName\\}", getService());
String encCouncilJsessionId = AriaCrypto.encode(councilJsessionId);
retUrl = retUrl.replaceAll("\\{councilJsessionId\\}", (councilJsessionId == null ? "" : encCouncilJsessionId));
return retUrl;
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
}
public DefaultApi20 getApi20Instance() {
return api20Instance;
}
public void setApi20Instance(DefaultApi20 api20Instance) {
this.api20Instance = api20Instance;
}
public String getProfileUrl() {
return profileUrl;
}
public void setProfileUrl(String profileUrl) {
this.profileUrl = profileUrl;
}
public boolean isGoogle() {
return isGoogle;
}
public boolean isNaver() {
return isNaver;
}
public boolean isKakao() {
return isKakao;
}
public void setGoogle(boolean isGoogle) {
this.isGoogle = isGoogle;
}
public void setNaver(boolean isNaver) {
this.isNaver = isNaver;
}
public void setKakao(boolean isKakao) {
this.isKakao = isKakao;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}

View File

@ -0,0 +1,146 @@
package egovframework.com.utl.fcc.service;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
/**
* 날짜 시간에 대한 변환을 수행하는 클래스
*/
public class EgovDateFormat {
/**
* 기본 Locale에 해당하는 형식으로 날짜를 변환한다.
*
* @param date 날짜
* @return 날짜 문자열
*/
public static String formatDate(Date date) {
return DateFormat.getDateInstance().format(date);
}
/**
* Locale에 해당하는 형식으로 날짜를 변환한다.
*
* @param locale 로케일
* @param date 날짜
* @return 날짜 문자열
*/
public static String formatDate(Locale locale, Date date) {
return DateFormat.getDateInstance(DateFormat.DEFAULT, locale).format(date);
}
/**
* 주어진 스타일에 따라, 기본 Locale에 해당하는 형식으로 날짜를 변환한다.
*
* @param style 날짜 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param date 날짜
* @return 날짜 문자열
*/
public static String formatDate(int style, Date date) {
return DateFormat.getDateInstance(style).format(date);
}
/**
* 주어진 스타일에 따라, Locale에 해당하는 형식으로 날짜를 변환한다.
*
* @param style 날짜 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param locale 로케일
* @param date 날짜
* @return 날짜 문자열
*/
public static String formatDate(int style, Locale locale, Date date) {
return DateFormat.getDateInstance(style, locale).format(date);
}
/**
* 기본 Locale에 해당하는 형식으로 날짜 시간을 변환한다.
*
* @param date 날짜 시간
* @return 날짜 시간 문자열
*/
public static String formatDateTime(Date date) {
return DateFormat.getDateTimeInstance().format(date);
}
/**
* Locale에 해당하는 형식으로 날짜 시간을 변환한다.
*
* @param locale 로케일
* @param date 날짜 시간
* @return 날짜 시간 문자열
*/
public static String formatDateTime(Locale locale, Date date) {
return DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale).format(date);
}
/**
* 주어진 스타일에 따라, 기본 Locale에 해당하는 형식으로 날짜 시간을 변환한다.
*
* @param dateStyle 날짜 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param timeStyle 시간 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param date 날짜 시간
* @return 날짜 시간 문자열
*/
public static String formatDateTime(int dateStyle, int timeStyle, Date date) {
return DateFormat.getDateTimeInstance(dateStyle, timeStyle).format(date);
}
/**
* 주어진 스타일에 따라, Locale에 해당하는 형식으로 날짜 시간을 변환한다.
*
* @param dateStyle 날짜 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param timeStyle 시간 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param locale 로케일
* @param date 날짜 시간
* @return 날짜 시간 문자열
*/
public static String formatDateTime(int dateStyle, int timeStyle, Locale locale, Date date) {
return DateFormat.getDateTimeInstance(dateStyle, timeStyle, locale).format(date);
}
/**
* 기본 Locale에 해당하는 형식으로 시간을 변환한다.
*
* @param date 시간
* @return 시간 문자열
*/
public static String formatTime(Date date) {
return DateFormat.getTimeInstance().format(date);
}
/**
* Locale에 해당하는 형식으로 시간을 변환한다.
*
* @param locale 로케일
* @param date 시간
* @return 시간 문자열
*/
public static String formatTime(Locale locale, Date date) {
return DateFormat.getTimeInstance(DateFormat.DEFAULT, locale).format(date);
}
/**
* 주어진 스타일에 따라, 기본 Locale에 해당하는 형식으로 시간을 변환한다.
*
* @param style 시간 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param date 시간
* @return 시간 문자열
*/
public static String formatTime(int style, Date date) {
return DateFormat.getTimeInstance(style).format(date);
}
/**
* 주어진 스타일에 따라, Locale에 해당하는 형식으로 시간을 변환한다.
*
* @param style 시간 스타일 (사용 가능한 : {@link DateFormat#FULL}, {@link DateFormat#LONG}, {@link DateFormat#MEDIUM}, {@link DateFormat#SHORT}, {@link DateFormat#DEFAULT})
* @param locale 로케일
* @param date 시간
* @return 시간 문자열
*/
public static String formatTime(int style, Locale locale, Date date) {
return DateFormat.getTimeInstance(style, locale).format(date);
}
}

View File

@ -0,0 +1,865 @@
package egovframework.com.utl.fcc.service;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.TimeZone;
import com.ibm.icu.util.ChineseCalendar;
/**
*
* Date 대한 Util 클래스
* @author 공통서비스 개발팀 이중호
* @since 2009.02.01
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.02.01 이중호 최초 생성
*
* </pre>
*/
public class EgovDateUtil {
/**
* <p>yyyyMMdd 혹은 yyyy-MM-dd 형식의 날짜 문자열을 입력 받아 , , 일을
* 증감한다. , , 일은 가감할 수를 의미하며, 음수를 입력할 경우 감한다.</p>
*
* <pre>
* DateUtil.addYearMonthDay("19810828", 0, 0, 19) = "19810916"
* DateUtil.addYearMonthDay("20060228", 0, 0, -10) = "20060218"
* DateUtil.addYearMonthDay("20060228", 0, 0, 10) = "20060310"
* DateUtil.addYearMonthDay("20060228", 0, 0, 32) = "20060401"
* DateUtil.addYearMonthDay("20050331", 0, -1, 0) = "20050228"
* DateUtil.addYearMonthDay("20050301", 0, 2, 30) = "20050531"
* DateUtil.addYearMonthDay("20050301", 1, 2, 30) = "20060531"
* DateUtil.addYearMonthDay("20040301", 2, 0, 0) = "20060301"
* DateUtil.addYearMonthDay("20040229", 2, 0, 0) = "20060228"
* DateUtil.addYearMonthDay("20040229", 2, 0, 1) = "20060301"
* </pre>
*
* @param dateStr 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @param year 가감할 . 0이 입력될 경우 가감이 없다
* @param month 가감할 . 0이 입력될 경우 가감이 없다
* @param day 가감할 . 0이 입력될 경우 가감이 없다
* @return yyyyMMdd 형식의 날짜 문자열
* @throws IllegalArgumentException 날짜 포맷이 정해진 바와 다를 경우.
* 입력 값이 <code>null</code> 경우.
*/
public static String addYearMonthDay(String sDate, int year, int month, int day) {
String dateStr = validChkDate(sDate);
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
try {
cal.setTime(sdf.parse(dateStr));
} catch (ParseException e) {
throw new IllegalArgumentException("Invalid date format: " + dateStr);
}
if (year != 0) {
cal.add(Calendar.YEAR, year);
}
if (month != 0) {
cal.add(Calendar.MONTH, month);
}
if (day != 0) {
cal.add(Calendar.DATE, day);
}
return sdf.format(cal.getTime());
}
/**
* <p>yyyyMMdd 혹은 yyyy-MM-dd 형식의 날짜 문자열을 입력 받아 년을
* 증감한다. <code>year</code> 가감할 수를 의미하며, 음수를 입력할 경우 감한다.</p>
*
* <pre>
* DateUtil.addYear("20000201", 62) = "20620201"
* DateUtil.addYear("20620201", -62) = "20000201"
* DateUtil.addYear("20040229", 2) = "20060228"
* DateUtil.addYear("20060228", -2) = "20040228"
* DateUtil.addYear("19000101", 200) = "21000101"
* </pre>
*
* @param dateStr 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @param year 가감할 . 0이 입력될 경우 가감이 없다
* @return yyyyMMdd 형식의 날짜 문자열
* @throws IllegalArgumentException 날짜 포맷이 정해진 바와 다를 경우.
* 입력 값이 <code>null</code> 경우.
*/
public static String addYear(String dateStr, int year) {
return addYearMonthDay(dateStr, year, 0, 0);
}
/**
* <p>yyyyMMdd 혹은 yyyy-MM-dd 형식의 날짜 문자열을 입력 받아 월을
* 증감한다. <code>month</code> 가감할 수를 의미하며, 음수를 입력할 경우 감한다.</p>
*
* <pre>
* DateUtil.addMonth("20010201", 12) = "20020201"
* DateUtil.addMonth("19800229", 12) = "19810228"
* DateUtil.addMonth("20040229", 12) = "20050228"
* DateUtil.addMonth("20050228", -12) = "20040228"
* DateUtil.addMonth("20060131", 1) = "20060228"
* DateUtil.addMonth("20060228", -1) = "20060128"
* </pre>
*
* @param dateStr 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @param month 가감할 . 0이 입력될 경우 가감이 없다
* @return yyyyMMdd 형식의 날짜 문자열
* @throws IllegalArgumentException 날짜 포맷이 정해진 바와 다를 경우.
* 입력 값이 <code>null</code> 경우.
*/
public static String addMonth(String dateStr, int month) {
return addYearMonthDay(dateStr, 0, month, 0);
}
/**
* <p>yyyyMMdd 혹은 yyyy-MM-dd 형식의 날짜 문자열을 입력 받아 (day)
* 증감한다. <code>day</code> 가감할 수를 의미하며, 음수를 입력할 경우 감한다.
* <br/><br/>
* 위에 정의된 addDays 메서드는 사용자가 ParseException을 반드시 처리해야 하는 불편함이
* 있기 때문에 추가된 메서드이다.</p>
*
* <pre>
* DateUtil.addDay("19991201", 62) = "20000201"
* DateUtil.addDay("20000201", -62) = "19991201"
* DateUtil.addDay("20050831", 3) = "20050903"
* DateUtil.addDay("20050831", 3) = "20050903"
* // 2006년 6월 31일은 실제로 존재하지 않는 날짜이다 -> 20060701로 간주된다
* DateUtil.addDay("20060631", 1) = "20060702"
* </pre>
*
* @param dateStr 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @param day 가감할 . 0이 입력될 경우 가감이 없다
* @return yyyyMMdd 형식의 날짜 문자열
* @throws IllegalArgumentException 날짜 포맷이 정해진 바와 다를 경우.
* 입력 값이 <code>null</code> 경우.
*/
public static String addDay(String dateStr, int day) {
return addYearMonthDay(dateStr, 0, 0, day);
}
/**
* <p>yyyyMMdd 혹은 yyyy-MM-dd 형식의 날짜 문자열 <code>dateStr1</code> <code>
* dateStr2</code> 사이의 수를 구한다.<br>
* <code>dateStr2</code> <code>dateStr1</code> 보다 과거 날짜일 경우에는
* 음수를 반환한다. 동일한 경우에는 0을 반환한다.</p>
*
* <pre>
* DateUtil.getDaysDiff("20060228","20060310") = 10
* DateUtil.getDaysDiff("20060101","20070101") = 365
* DateUtil.getDaysDiff("19990228","19990131") = -28
* DateUtil.getDaysDiff("20060801","20060802") = 1
* DateUtil.getDaysDiff("20060801","20060801") = 0
* </pre>
*
* @param dateStr1 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @param dateStr2 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @return 차이.
* @throws IllegalArgumentException 날짜 포맷이 정해진 바와 다를 경우.
* 입력 값이 <code>null</code> 경우.
*/
public static int getDaysDiff(String sDate1, String sDate2) {
String dateStr1 = validChkDate(sDate1);
String dateStr2 = validChkDate(sDate2);
if (!checkDate(sDate1) || !checkDate(sDate2)) {
throw new IllegalArgumentException("Invalid date format: args[0]=" + sDate1 + " args[1]=" + sDate2);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
Date date1 = null;
Date date2 = null;
try {
date1 = sdf.parse(dateStr1);
date2 = sdf.parse(dateStr2);
} catch (ParseException e) {
throw new IllegalArgumentException("Invalid date format: args[0]=" + dateStr1 + " args[1]=" + dateStr2);
}
if (date1 != null && date2 != null) {
int days1 = (int) ((date1.getTime() / 3600000) / 24);
int days2 = (int) ((date2.getTime() / 3600000) / 24);
return days2 - days1;
} else {
return 0;
}
}
/**
* <p>yyyyMMdd 혹은 yyyy-MM-dd 형식의 날짜 문자열을 입력 받아 유효한 날짜인지 검사.</p>
*
* <pre>
* DateUtil.checkDate("1999-02-35") = false
* DateUtil.checkDate("2000-13-31") = false
* DateUtil.checkDate("2006-11-31") = false
* DateUtil.checkDate("2006-2-28") = false
* DateUtil.checkDate("2006-2-8") = false
* DateUtil.checkDate("20060228") = true
* DateUtil.checkDate("2006-02-28") = true
* </pre>
*
* @param dateStr 날짜 문자열(yyyyMMdd, yyyy-MM-dd의 형식)
* @return 유효한 날짜인지 여부
*/
public static boolean checkDate(String sDate) {
String dateStr = validChkDate(sDate);
String year = dateStr.substring(0, 4);
String month = dateStr.substring(4, 6);
String day = dateStr.substring(6);
return checkDate(year, month, day);
}
/**
* <p>입력한 , , 일이 유효한지 검사.</p>
*
* @param year 연도
* @param month
* @param day
* @return 유효한 날짜인지 여부
*/
public static boolean checkDate(String year, String month, String day) {
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy.MM.dd", Locale.getDefault());
Date result = formatter.parse(year + "." + month + "." + day);
String resultStr = formatter.format(result);
if (resultStr.equalsIgnoreCase(year + "." + month + "." + day))
return true;
else
return false;
} catch (ParseException e) {
return false;
}
}
/**
* 날짜형태의 String의 날짜 포맷 TimeZone을 변경해 주는 메서드
*
* @param strSource 바꿀 날짜 String
* @param fromDateFormat 기존의 날짜 형태
* @param toDateFormat 원하는 날짜 형태
* @param strTimeZone 변경할 TimeZone(""이면 변경 안함)
* @return 소스 String의 날짜 포맷을 변경한 String
*/
public static String convertDate(String strSource, String fromDateFormat, String toDateFormat, String strTimeZone) {
SimpleDateFormat simpledateformat = null;
Date date = null;
String fromFormat = "";
String toFormat = "";
if (EgovStringUtil.isNullToString(strSource).trim().equals("")) {
return "";
}
if (EgovStringUtil.isNullToString(fromDateFormat).trim().equals(""))
fromFormat = "yyyyMMddHHmmss"; // default값
if (EgovStringUtil.isNullToString(toDateFormat).trim().equals(""))
toFormat = "yyyy-MM-dd HH:mm:ss"; // default값
try {
simpledateformat = new SimpleDateFormat(fromFormat, Locale.getDefault());
date = simpledateformat.parse(strSource);
if (!EgovStringUtil.isNullToString(strTimeZone).trim().equals("")) {
simpledateformat.setTimeZone(TimeZone.getTimeZone(strTimeZone));
}
simpledateformat = new SimpleDateFormat(toFormat, Locale.getDefault());
} catch (ParseException exception) {
throw new RuntimeException(exception);
}
return simpledateformat.format(date);
}
/**
* yyyyMMdd 형식의 날짜문자열을 원하는 캐릭터(ch) 쪼개 돌려준다<br/>
* <pre>
* ex) 20030405, ch(.) -> 2003.04.05
* ex) 200304, ch(.) -> 2003.04
* ex) 20040101,ch(/) --> 2004/01/01 리턴
* </pre>
*
* @param date yyyyMMdd 형식의 날짜문자열
* @param ch 구분자
* @return 변환된 문자열
*/
public static String formatDate(String sDate, String ch) {
String dateStr = validChkDate(sDate);
String str = dateStr.trim();
String yyyy = "";
String mm = "";
String dd = "";
if (str.length() == 8) {
yyyy = str.substring(0, 4);
if (yyyy.equals("0000")) {
return "";
}
mm = str.substring(4, 6);
if (mm.equals("00")) {
return yyyy;
}
dd = str.substring(6, 8);
if (dd.equals("00")) {
return yyyy + ch + mm;
}
return yyyy + ch + mm + ch + dd;
} else if (str.length() == 6) {
yyyy = str.substring(0, 4);
if (yyyy.equals("0000")) {
return "";
}
mm = str.substring(4, 6);
if (mm.equals("00")) {
return yyyy;
}
return yyyy + ch + mm;
} else if (str.length() == 4) {
yyyy = str.substring(0, 4);
if (yyyy.equals("0000")) {
return "";
} else {
return yyyy;
}
} else {
return "";
}
}
/**
* HH24MISS 형식의 시간문자열을 원하는 캐릭터(ch) 쪼개 돌려준다 <br>
* <pre>
* ex) 151241, ch(/) -> 15/12/31
* </pre>
*
* @param str HH24MISS 형식의 시간문자열
* @param ch 구분자
* @return 변환된 문자열
*/
public static String formatTime(String sTime, String ch) {
String timeStr = validChkTime(sTime);
return timeStr.substring(0, 2) + ch + timeStr.substring(2, 4) + ch + timeStr.substring(4, 6);
}
/**
* 연도를 입력 받아 해당 연도 2월의 말일(일수) 문자열로 반환한다.
*
* @param year
* @return 해당 연도 2월의 말일(일수)
*/
public String leapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return "29";
}
return "28";
}
/**
* <p>입력받은 연도가 윤년인지 아닌지 검사한다.</p>
*
* <pre>
* DateUtil.isLeapYear(2004) = false
* DateUtil.isLeapYear(2005) = true
* DateUtil.isLeapYear(2006) = true
* </pre>
*
* @param year 연도
* @return 윤년 여부
*/
public static boolean isLeapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return false;
}
return true;
}
/**
* 현재(한국기준) 날짜정보를 얻는다. <BR>
* 표기법은 yyyy-mm-dd <BR>
* @return String yyyymmdd형태의 현재 한국시간. <BR>
*/
public static String getToday() {
return getCurrentDate("");
}
/**
* 현재(한국기준) 날짜정보를 얻는다. <BR>
* 표기법은 yyyy-mm-dd <BR>
* @return String yyyymmdd형태의 현재 한국시간. <BR>
*/
public static String getCurrentDate(String dateType) {
Calendar aCalendar = Calendar.getInstance();
int year = aCalendar.get(Calendar.YEAR);
int month = aCalendar.get(Calendar.MONTH) + 1;
int date = aCalendar.get(Calendar.DATE);
String strDate = Integer.toString(year)
+ ((month < 10) ? "0" + Integer.toString(month) : Integer.toString(month))
+ ((date < 10) ? "0" + Integer.toString(date) : Integer.toString(date));
if (!"".equals(dateType)) {
strDate = convertDate(strDate, "yyyyMMdd", dateType);
}
return strDate;
}
/**
* 날짜형태의 String의 날짜 포맷만을 변경해 주는 메서드
* @param sDate 날짜
* @param sTime 시간
* @param sFormatStr 포멧 스트링 문자열
* @return 지정한 날짜/시간을 지정한 포맷으로 출력
* @See Letter Date or Time Component Presentation Examples
G Era designator Text AD
y Year Year 1996; 96
M Month in year Month July; Jul; 07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day in week Text Tuesday; Tue
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard Time; PST; GMT-08:00
Z Time zone RFC 822 time zone -0800
Date and Time Pattern Result
"yyyy.MM.dd G 'at' HH:mm:ss z" 2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy" Wed, Jul 4, '01
"h:mm a" 12:08 PM
"hh 'o''clock' a, zzzz" 12 o'clock PM, Pacific Daylight Time
"K:mm a, z" 0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa" 02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z" Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ" 010704120856-0700
*/
public static String convertDate(String sDate, String sTime, String sFormatStr) {
String dateStr = validChkDate(sDate);
String timeStr = validChkTime(sTime);
Calendar cal = null;
cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(dateStr.substring(0, 4)));
cal.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(4, 6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeStr.substring(0, 2)));
cal.set(Calendar.MINUTE, Integer.parseInt(timeStr.substring(2, 4)));
SimpleDateFormat sdf = new SimpleDateFormat(sFormatStr, Locale.ENGLISH);
return sdf.format(cal.getTime());
}
/**
* 입력받은 일자 사이의 임의의 일자를 반환
* @param sDate1 시작일자
* @param sDate2 종료일자
* @return 임의일자
*/
public static String getRandomDate(String sDate1, String sDate2) {
String dateStr1 = validChkDate(sDate1);
String dateStr2 = validChkDate(sDate2);
String randomDate = null;
int sYear, sMonth, sDay;
int eYear, eMonth, eDay;
sYear = Integer.parseInt(dateStr1.substring(0, 4));
sMonth = Integer.parseInt(dateStr1.substring(4, 6));
sDay = Integer.parseInt(dateStr1.substring(6, 8));
eYear = Integer.parseInt(dateStr2.substring(0, 4));
eMonth = Integer.parseInt(dateStr2.substring(4, 6));
eDay = Integer.parseInt(dateStr2.substring(6, 8));
GregorianCalendar beginDate = new GregorianCalendar(sYear, sMonth - 1, sDay, 0, 0);
GregorianCalendar endDate = new GregorianCalendar(eYear, eMonth - 1, eDay, 23, 59);
if (endDate.getTimeInMillis() < beginDate.getTimeInMillis()) {
throw new IllegalArgumentException("Invalid input date : " + sDate1 + "~" + sDate2);
}
SecureRandom r = new SecureRandom();
r.setSeed(new Date().getTime());
long rand = ((r.nextLong() >>> 1) % (endDate.getTimeInMillis() - beginDate.getTimeInMillis() + 1)) + beginDate.getTimeInMillis();
GregorianCalendar cal = new GregorianCalendar();
//SimpleDateFormat calformat = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat calformat = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
cal.setTimeInMillis(rand);
randomDate = calformat.format(cal.getTime());
// 랜덤문자열를 리턴
return randomDate;
}
/**
* 입력받은 양력일자를 변환하여 음력일자로 반환
* @param sDate 양력일자
* @return 음력일자
*/
public static Map<String, String> toLunar(String sDate) {
String dateStr = validChkDate(sDate);
Map<String, String> hm = new HashMap<String, String>();
hm.put("day", "");
hm.put("leap", "0");
if (dateStr.length() != 8) {
return hm;
}
Calendar cal;
ChineseCalendar lcal;
cal = Calendar.getInstance();
lcal = new ChineseCalendar();
cal.set(Calendar.YEAR, Integer.parseInt(dateStr.substring(0, 4)));
cal.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(4, 6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
lcal.setTimeInMillis(cal.getTimeInMillis());
String year = String.valueOf(lcal.get(ChineseCalendar.EXTENDED_YEAR) - 2637);
String month = String.valueOf(lcal.get(ChineseCalendar.MONTH) + 1);
String day = String.valueOf(lcal.get(ChineseCalendar.DAY_OF_MONTH));
String leap = String.valueOf(lcal.get(ChineseCalendar.IS_LEAP_MONTH));
String pad4Str = "0000";
String pad2Str = "00";
String retYear = (pad4Str + year).substring(year.length());
String retMonth = (pad2Str + month).substring(month.length());
String retDay = (pad2Str + day).substring(day.length());
String SDay = retYear + retMonth + retDay;
hm.put("day", SDay);
hm.put("leap", leap);
return hm;
}
/**
* 입력받은 음력일자를 변환하여 양력일자로 반환
* @param sDate 음력일자
* @param iLeapMonth 음력윤달여부(IS_LEAP_MONTH)
* @return 양력일자
*/
public static String toSolar(String sDate, int iLeapMonth) {
String dateStr = validChkDate(sDate);
Calendar cal;
ChineseCalendar lcal;
cal = Calendar.getInstance();
lcal = new ChineseCalendar();
lcal.set(ChineseCalendar.EXTENDED_YEAR, Integer.parseInt(dateStr.substring(0, 4)) + 2637);
lcal.set(ChineseCalendar.MONTH, Integer.parseInt(dateStr.substring(4, 6)) - 1);
lcal.set(ChineseCalendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
lcal.set(ChineseCalendar.IS_LEAP_MONTH, iLeapMonth);
cal.setTimeInMillis(lcal.getTimeInMillis());
String year = String.valueOf(cal.get(Calendar.YEAR));
String month = String.valueOf(cal.get(Calendar.MONTH) + 1);
String day = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
String pad4Str = "0000";
String pad2Str = "00";
String retYear = (pad4Str + year).substring(year.length());
String retMonth = (pad2Str + month).substring(month.length());
String retDay = (pad2Str + day).substring(day.length());
return retYear + retMonth + retDay;
}
/**
* 입력받은 요일의 영문명을 국문명의 요일로 반환
* @param sWeek 영문 요일명
* @return 국문 요일명
*/
public static String convertWeek(String sWeek) {
String retStr = null;
if (sWeek.equals("SUN")) {
retStr = "일요일";
} else if (sWeek.equals("MON")) {
retStr = "월요일";
} else if (sWeek.equals("TUE")) {
retStr = "화요일";
} else if (sWeek.equals("WED")) {
retStr = "수요일";
} else if (sWeek.equals("THR")) {
retStr = "목요일";
} else if (sWeek.equals("FRI")) {
retStr = "금요일";
} else if (sWeek.equals("SAT")) {
retStr = "토요일";
}
return retStr;
}
/**
* 입력일자의 유효 여부를 확인
* @param sDate 일자
* @return 유효 여부
*/
public static boolean validDate(String sDate) {
String dateStr = validChkDate(sDate);
Calendar cal;
boolean ret = false;
cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(dateStr.substring(0, 4)));
cal.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(4, 6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
String year = String.valueOf(cal.get(Calendar.YEAR));
String month = String.valueOf(cal.get(Calendar.MONTH) + 1);
String day = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
String pad4Str = "0000";
String pad2Str = "00";
String retYear = (pad4Str + year).substring(year.length());
String retMonth = (pad2Str + month).substring(month.length());
String retDay = (pad2Str + day).substring(day.length());
String retYMD = retYear + retMonth + retDay;
if (sDate.equals(retYMD)) {
ret = true;
}
return ret;
}
/**
* 입력일자, 요일의 유효 여부를 확인
* @param sDate 일자
* @param sWeek 요일 (DAY_OF_WEEK)
* @return 유효 여부
*/
public static boolean validDate(String sDate, int sWeek) {
String dateStr = validChkDate(sDate);
Calendar cal;
boolean ret = false;
cal = Calendar.getInstance();
cal.set(Calendar.YEAR, Integer.parseInt(dateStr.substring(0, 4)));
cal.set(Calendar.MONTH, Integer.parseInt(dateStr.substring(4, 6)) - 1);
cal.set(Calendar.DAY_OF_MONTH, Integer.parseInt(dateStr.substring(6, 8)));
int Week = cal.get(Calendar.DAY_OF_WEEK);
if (validDate(sDate)) {
if (sWeek == Week) {
ret = true;
}
}
return ret;
}
/**
* 입력시간의 유효 여부를 확인
* @param sTime 입력시간
* @return 유효 여부
*/
public static boolean validTime(String sTime) {
String timeStr = validChkTime(sTime);
Calendar cal;
boolean ret = false;
cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeStr.substring(0, 2)));
cal.set(Calendar.MINUTE, Integer.parseInt(timeStr.substring(2, 4)));
String HH = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
String MM = String.valueOf(cal.get(Calendar.MINUTE));
String pad2Str = "00";
String retHH = (pad2Str + HH).substring(HH.length());
String retMM = (pad2Str + MM).substring(MM.length());
String retTime = retHH + retMM;
if (sTime.equals(retTime)) {
ret = true;
}
return ret;
}
/**
* 입력된 일자에 , , 일을 가감한 날짜의 요일을 반환
* @param sDate 날짜
* @param year
* @param month
* @param day
* @return 계산된 일자의 요일(DAY_OF_WEEK)
*/
public static String addYMDtoWeek(String sDate, int year, int month, int day) {
String dateStr = validChkDate(sDate);
dateStr = addYearMonthDay(dateStr, year, month, day);
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd", Locale.ENGLISH);
try {
cal.setTime(sdf.parse(dateStr));
} catch (ParseException e) {
throw new IllegalArgumentException("Invalid date format: " + dateStr);
}
SimpleDateFormat rsdf = new SimpleDateFormat("E", Locale.ENGLISH);
return rsdf.format(cal.getTime());
}
/**
* 입력된 일자에 , , , 시간, 분을 가감한 날짜, 시간을 포멧스트링 형식으로 반환
* @param sDate 날짜
* @param sTime 시간
* @param year
* @param month
* @param day
* @param hour 시간
* @param minute
* @param formatStr 포멧스트링
* @return
*/
public static String addYMDtoDayTime(String sDate, String sTime, int year, int month, int day, int hour, int minute, String formatStr) {
String dateStr = validChkDate(sDate);
String timeStr = validChkTime(sTime);
dateStr = addYearMonthDay(dateStr, year, month, day);
dateStr = convertDate(dateStr, timeStr, "yyyyMMddHHmm");
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmm", Locale.ENGLISH);
try {
cal.setTime(sdf.parse(dateStr));
} catch (ParseException e) {
throw new IllegalArgumentException("Invalid date format: " + dateStr);
}
if (hour != 0) {
cal.add(Calendar.HOUR, hour);
}
if (minute != 0) {
cal.add(Calendar.MINUTE, minute);
}
SimpleDateFormat rsdf = new SimpleDateFormat(formatStr, Locale.ENGLISH);
return rsdf.format(cal.getTime());
}
/**
* 입력된 일자를 int 형으로 반환
* @param sDate 일자
* @return int(일자)
*/
public static int datetoInt(String sDate) {
return Integer.parseInt(convertDate(sDate, "0000", "yyyyMMdd"));
}
/**
* 입력된 시간을 int 형으로 반환
* @param sTime 시간
* @return int(시간)
*/
public static int timetoInt(String sTime) {
return Integer.parseInt(convertDate("00000101", sTime, "HHmm"));
}
/**
* 입력된 일자 문자열을 확인하고 8자리로 리턴
* @param sDate
* @return
*/
public static String validChkDate(String dateStr) {
if (dateStr == null || !(dateStr.trim().length() == 8 || dateStr.trim().length() == 10)) {
throw new IllegalArgumentException("Invalid date format: " + dateStr);
}
if (dateStr.length() == 10) {
return EgovStringUtil.removeMinusChar(dateStr);
}
return dateStr;
}
/**
* 입력된 일자 문자열을 확인하고 8자리로 리턴
* @param sDate
* @return
*/
public static String validChkTime(String timeStr) {
if (timeStr == null || !(timeStr.trim().length() == 4)) {
throw new IllegalArgumentException("Invalid time format: " + timeStr);
}
if (timeStr.length() == 5) {
timeStr = EgovStringUtil.remove(timeStr, ':');
}
return timeStr;
}
}

View File

@ -0,0 +1,159 @@
package egovframework.com.utl.fcc.service;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import egovframework.com.cmm.EgovWebUtil;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
/**
* @Class Name : EgovFileUploadUtil.java
* @Description : Spring 기반 File Upload 유틸리티
* @Modification Information
*
* 수정일 수정자 수정내용
* ---------- -------- ---------------------------
* 2009.08.26 한성곤 최초 생성
* 2018.08.17 신용호 uploadFilesExt(확장자 기록) 추가
*
* @author 공통컴포넌트 개발팀 한성곤
* @since 2009.08.26
* @version 1.0
* @see
*/
public class EgovFileUploadUtil extends EgovFormBasedFileUtil {
/**
* 파일을 Upload 처리한다.
*
* @param request
* @param where
* @param maxFileSize
* @return
* @throws Exception
*/
public static List<EgovFormBasedFileVo> uploadFiles(HttpServletRequest request, String where, long maxFileSize) throws Exception {
List<EgovFormBasedFileVo> list = new ArrayList<EgovFormBasedFileVo>();
MultipartHttpServletRequest mptRequest = (MultipartHttpServletRequest) request;
Iterator<?> fileIter = mptRequest.getFileNames();
while (fileIter.hasNext()) {
MultipartFile mFile = mptRequest.getFile((String) fileIter.next());
EgovFormBasedFileVo vo = new EgovFormBasedFileVo();
String tmp = mFile.getOriginalFilename();
if (tmp.lastIndexOf("\\") >= 0) {
tmp = tmp.substring(tmp.lastIndexOf("\\") + 1);
}
vo.setFileName(tmp);
vo.setContentType(mFile.getContentType());
vo.setServerSubPath(getTodayString());
vo.setPhysicalName(getPhysicalFileName());
vo.setSize(mFile.getSize());
if (tmp.lastIndexOf(".") >= 0) {
vo.setPhysicalName(vo.getPhysicalName()); // 2012.11 KISA 보안조치
}
if (mFile.getSize() > 0) {
InputStream is = null;
try {
is = mFile.getInputStream();
saveFile(is, new File(EgovWebUtil.filePathBlackList(where + SEPERATOR + vo.getServerSubPath() + SEPERATOR + vo.getPhysicalName())));
} finally {
if (is != null) {
is.close();
}
}
list.add(vo);
}
}
return list;
}
/**
* 파일을 Upload(확장명 저장 확장자 제한) 처리한다.
*
* @param request
* @param where
* @param maxFileSize
* @return
* @throws Exception
*/
public static List<EgovFormBasedFileVo> uploadFilesExt(HttpServletRequest request, String where, long maxFileSize, String extensionWhiteList) throws Exception {
List<EgovFormBasedFileVo> list = new ArrayList<EgovFormBasedFileVo>();
MultipartHttpServletRequest mptRequest = (MultipartHttpServletRequest) request;
Iterator<?> fileIter = mptRequest.getFileNames();
while (fileIter.hasNext()) {
MultipartFile mFile = mptRequest.getFile((String) fileIter.next());
EgovFormBasedFileVo vo = new EgovFormBasedFileVo();
String tmp = mFile.getOriginalFilename();
if (tmp.lastIndexOf("\\") >= 0) {
tmp = tmp.substring(tmp.lastIndexOf("\\") + 1);
}
String ext = "";
if ( tmp.lastIndexOf(".") > 0 )
ext = getFileExtension(tmp).toLowerCase();
else
throw new SecurityException("Unacceptable file extension."); // 허용되지 않는 확장자 처리
if ( extensionWhiteList.indexOf(ext) < 0 )
throw new SecurityException("Unacceptable file extension."); // 허용되지 않는 확장자 처리
vo.setFileName(tmp);
vo.setContentType(mFile.getContentType());
vo.setServerSubPath(getTodayString());
vo.setPhysicalName(getPhysicalFileName()+"."+ext);
vo.setSize(mFile.getSize());
if (tmp.lastIndexOf(".") >= 0) {
vo.setPhysicalName(vo.getPhysicalName()); // 2012.11 KISA 보안조치
}
if (mFile.getSize() > 0) {
InputStream is = null;
try {
is = mFile.getInputStream();
saveFile(is, new File(EgovWebUtil.filePathBlackList(where + SEPERATOR + vo.getServerSubPath() + SEPERATOR + vo.getPhysicalName())));
} finally {
if (is != null) {
is.close();
}
}
list.add(vo);
}
}
return list;
}
/**
* 파일 확장자를 추출한다.
*
* @param fileNamePath
* @return
*/
public static String getFileExtension(String fileNamePath) {
String ext = fileNamePath.substring(fileNamePath.lastIndexOf(".") + 1,fileNamePath.length());
return (ext == null) ? "" : ext;
}
}

View File

@ -0,0 +1,295 @@
package egovframework.com.utl.fcc.service;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import egovframework.com.cmm.EgovWebUtil;
import egovframework.com.cmm.util.EgovResourceCloseHelper;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @Class Name : EgovFormBasedFileUtil.java
* @Description : Form-based File Upload 유틸리티
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.08.26 한성곤 최초 생성
* 2017.03.03 조성원 시큐어코딩(ES)-부적절한 예외 처리[CWE-253, CWE-440, CWE-754]
*
* @author 공통컴포넌트 개발팀 한성곤
* @since 2009.08.26
* @version 1.0
* @see
*/
public class EgovFormBasedFileUtil {
/** Buffer size */
public static final int BUFFER_SIZE = 8192;
public static final String SEPERATOR = File.separator;
private static final Logger LOGGER = LoggerFactory.getLogger(EgovFormBasedFileUtil.class);
/**
* 오늘 날짜 문자열 취득.
* ex) 20090101
* @return
*/
public static String getTodayString() {
SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd", Locale.getDefault());
return format.format(new Date());
}
/**
* 물리적 파일명 생성.
* @return
*/
public static String getPhysicalFileName() {
return EgovFormBasedUUID.randomUUID().toString().replaceAll("-", "").toUpperCase();
}
/**
* 파일명 변환.
* @param filename String
* @return
* @throws Exception
*/
protected static String convert(String filename) throws Exception {
//return java.net.URLEncoder.encode(filename, "utf-8");
return filename;
}
/**
* Stream으로부터 파일을 저장함.
* @param is InputStream
* @param file File
* @throws IOException
*/
public static long saveFile(InputStream is, File file) throws IOException {
//KISA 보안약점 조치 (2018-10-29, 윤창원)
if (file.getParentFile() == null) {
LOGGER.debug("file.getParentFile() is null");
throw new RuntimeException("file.getParentFile() is null");
}
// 디렉토리 생성
if (!file.getParentFile().exists()) {
//2017.03.03 조성원 시큐어코딩(ES)-부적절한 예외 처리[CWE-253, CWE-440, CWE-754]
if(file.getParentFile().mkdirs()){
LOGGER.debug("[file.mkdirs] file : Directory Creation Success");
}else{
LOGGER.error("[file.mkdirs] file : Directory Creation Fail");
}
}
OutputStream os = null;
long size = 0L;
try {
os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = is.read(buffer, 0, BUFFER_SIZE)) != -1) {
size += bytesRead;
os.write(buffer, 0, bytesRead);
}
} finally {
EgovResourceCloseHelper.close(os);
}
return size;
}
/**
* 파일을 Upload 처리한다.
*
* @param request
* @param where
* @param maxFileSize
* @return
* @throws Exception
*/
public static List<EgovFormBasedFileVo> uploadFiles(HttpServletRequest request, String where, long maxFileSize) throws Exception {
List<EgovFormBasedFileVo> list = new ArrayList<EgovFormBasedFileVo>();
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
upload.setFileSizeMax(maxFileSize); // SizeLimitExceededException
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (item.isFormField()) {
LOGGER.info("Form field '{}' with value '{}' detected.", name, Streams.asString(stream));
} else {
LOGGER.info("File field '{}' with file name '{}' detected.", name, item.getName());
if ("".equals(item.getName())) {
continue;
}
// Process the input stream
EgovFormBasedFileVo vo = new EgovFormBasedFileVo();
String tmp = item.getName();
if (tmp.lastIndexOf("\\") >= 0) {
tmp = tmp.substring(tmp.lastIndexOf("\\") + 1);
}
vo.setFileName(tmp);
vo.setContentType(item.getContentType());
vo.setServerSubPath(getTodayString());
vo.setPhysicalName(getPhysicalFileName());
if (tmp.lastIndexOf(".") >= 0) {
vo.setPhysicalName(vo.getPhysicalName() + tmp.substring(tmp.lastIndexOf(".")));
}
long size = saveFile(stream, new File(EgovWebUtil.filePathBlackList(where) + SEPERATOR + vo.getServerSubPath() + SEPERATOR + vo.getPhysicalName()));
vo.setSize(size);
list.add(vo);
}
}
} else {
throw new IOException("form's 'enctype' attribute have to be 'multipart/form-data'");
}
return list;
}
/**
* 파일을 Download 처리한다.
*
* @param response
* @param where
* @param serverSubPath
* @param physicalName
* @param original
* @throws Exception
*/
public static void downloadFile(HttpServletResponse response, String where, String serverSubPath, String physicalName, String original) throws Exception {
String downFileName = where + SEPERATOR + serverSubPath + SEPERATOR + physicalName;
File file = new File(EgovWebUtil.filePathBlackList(downFileName));
if (!file.exists()) {
throw new FileNotFoundException(downFileName);
}
if (!file.isFile()) {
throw new FileNotFoundException(downFileName);
}
byte[] b = new byte[BUFFER_SIZE];
original = original.replaceAll("\r", "").replaceAll("\n", "");
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment; filename=\"" + convert(original) + "\";");
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Pragma", "no-cache");
response.setHeader("Expires", "0");
BufferedInputStream fin = null;
BufferedOutputStream outs = null;
try {
fin = new BufferedInputStream(new FileInputStream(file));
outs = new BufferedOutputStream(response.getOutputStream());
int read = 0;
while ((read = fin.read(b)) != -1) {
outs.write(b, 0, read);
}
} finally {
EgovResourceCloseHelper.close(outs, fin);
}
}
/**
* 이미지에 대한 미리보기 기능을 제공한다.
*
* mimeType의 경우는 JSP 상에서 다음과 같이 얻을 있다.
* getServletConfig().getServletContext().getMimeType(name);
*
* @param response
* @param where
* @param serverSubPath
* @param physicalName
* @param mimeType
* @throws Exception
*/
public static void viewFile(HttpServletResponse response, String where, String serverSubPath, String physicalName, String mimeTypeParam) throws Exception {
String mimeType = mimeTypeParam;
String downFileName = where + SEPERATOR + serverSubPath + SEPERATOR + physicalName;
File file = new File(EgovWebUtil.filePathBlackList(downFileName));
if (!file.exists()) {
throw new FileNotFoundException(downFileName);
}
if (!file.isFile()) {
throw new FileNotFoundException(downFileName);
}
byte[] b = new byte[BUFFER_SIZE];
if (mimeType == null) {
mimeType = "application/octet-stream;";
}
response.setContentType(EgovWebUtil.removeCRLF(mimeType));
response.setHeader("Content-Disposition", "filename=image;");
BufferedInputStream fin = null;
BufferedOutputStream outs = null;
try {
fin = new BufferedInputStream(new FileInputStream(file));
outs = new BufferedOutputStream(response.getOutputStream());
int read = 0;
while ((read = fin.read(b)) != -1) {
outs.write(b, 0, read);
}
} finally {
EgovResourceCloseHelper.close(outs, fin);
}
}
}

View File

@ -0,0 +1,104 @@
package egovframework.com.utl.fcc.service;
import java.io.Serializable;
/**
* @Class Name : EgovFormBasedFileVo.java
* @Description : Form-based File Upload VO
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.08.26 한성곤 최초 생성
*
* @author 공통컴포넌트 개발팀 한성곤
* @since 2009.08.26
* @version 1.0
* @see
*
* Copyright (C) 2008 by MOPAS All right reserved.
*/
@SuppressWarnings("serial")
public class EgovFormBasedFileVo implements Serializable {
/** 파일명 */
private String fileName = "";
/** ContextType */
private String contentType = "";
/** 하위 디렉토리 지정 */
private String serverSubPath = "";
/** 물리적 파일명 */
private String physicalName = "";
/** 파일 사이즈 */
private long size = 0L;
/**
* fileName attribute를 리턴한다.
* @return the fileName
*/
public String getFileName() {
return fileName;
}
/**
* fileName attribute 값을 설정한다.
* @param fileName the fileName to set
*/
public void setFileName(String fileName) {
this.fileName = fileName;
}
/**
* contentType attribute를 리턴한다.
* @return the contentType
*/
public String getContentType() {
return contentType;
}
/**
* contentType attribute 값을 설정한다.
* @param contentType the contentType to set
*/
public void setContentType(String contentType) {
this.contentType = contentType;
}
/**
* serverSubPath attribute를 리턴한다.
* @return the serverSubPath
*/
public String getServerSubPath() {
return serverSubPath;
}
/**
* serverSubPath attribute 값을 설정한다.
* @param serverSubPath the serverSubPath to set
*/
public void setServerSubPath(String serverSubPath) {
this.serverSubPath = serverSubPath;
}
/**
* physicalName attribute를 리턴한다.
* @return the physicalName
*/
public String getPhysicalName() {
return physicalName;
}
/**
* physicalName attribute 값을 설정한다.
* @param physicalName the physicalName to set
*/
public void setPhysicalName(String physicalName) {
this.physicalName = physicalName;
}
/**
* size attribute를 리턴한다.
* @return the size
*/
public long getSize() {
return size;
}
/**
* size attribute 값을 설정한다.
* @param size the size to set
*/
public void setSize(long size) {
this.size = size;
}
}

View File

@ -0,0 +1,521 @@
package egovframework.com.utl.fcc.service;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
*
* A class that represents an immutable universally unique identifier (UUID). A
* UUID represents a 128-bit value.
*
* <p>
* There exist different variants of these global identifiers. The methods of
* this class are for manipulating the Leach-Salz variant, although the
* constructors allow the creation of any variant of UUID (described below).
*
* <p>
* The layout of a variant 2 (Leach-Salz) UUID is as follows:
*
* The most significant long consists of the following unsigned fields:
*
* <pre>
* 0xFFFFFFFF00000000 time_low
* 0x00000000FFFF0000 time_mid
* 0x000000000000F000 version
* 0x0000000000000FFF time_hi
* </pre>
*
* The least significant long consists of the following unsigned fields:
*
* <pre>
* 0xC000000000000000 variant
* 0x3FFF000000000000 clock_seq
* 0x0000FFFFFFFFFFFF node
* </pre>
*
* <p>
* The variant field contains a value which identifies the layout of the
* <tt>UUID</tt>. The bit layout described above is valid only for a
* <tt>UUID</tt> with a variant value of 2, which indicates the Leach-Salz
* variant.
*
* <p>
* The version field holds a value that describes the type of this <tt>UUID</tt>.
* There are four different basic types of UUIDs: time-based, DCE security,
* name-based, and randomly generated UUIDs. These types have a version value of
* 1, 2, 3 and 4, respectively.
*
* <p>
* For more information including algorithms used to create <tt>UUID</tt>s,
* see the Internet-Draft <a
* href="http://www.ietf.org/internet-drafts/draft-mealling-uuid-urn-03.txt">UUIDs
* and GUIDs</a> or the standards body definition at <a
* href="http://www.iso.ch/cate/d2229.html">ISO/IEC 11578:1996</a>.
*
* @version 1.14, 07/12/04
* @since 1.5
*/
@SuppressWarnings("serial")
public class EgovFormBasedUUID implements Serializable {
/*
* The most significant 64 bits of this UUID.
*
* @serial
*/
private final long mostSigBits;
/*
* The least significant 64 bits of this UUID.
*
* @serial
*/
private final long leastSigBits;
/*
* The version number associated with this UUID. Computed on demand.
*/
private transient int version = -1;
/*
* The variant number associated with this UUID. Computed on demand.
*/
private transient int variant = -1;
/*
* The timestamp associated with this UUID. Computed on demand.
*/
private transient volatile long timestamp = -1;
/*
* The clock sequence associated with this UUID. Computed on demand.
*/
private transient int sequence = -1;
/*
* The node number associated with this UUID. Computed on demand.
*/
private transient long node = -1;
/*
* The hashcode of this UUID. Computed on demand.
*/
private transient int hashCode = -1;
/*
* The random number generator used by this class to create random based
* UUIDs.
*/
private static volatile SecureRandom numberGenerator = null;
// Constructors and Factories
/*
* Private constructor which uses a byte array to construct the new UUID.
*/
private EgovFormBasedUUID(byte[] data) {
long msb = 0;
long lsb = 0;
for (int i = 0; i < 8; i++)
msb = (msb << 8) | (data[i] & 0xff);
for (int i = 8; i < 16; i++)
lsb = (lsb << 8) | (data[i] & 0xff);
this.mostSigBits = msb;
this.leastSigBits = lsb;
}
/**
* Constructs a new <tt>UUID</tt> using the specified data.
* <tt>mostSigBits</tt> is used for the most significant 64 bits of the
* <tt>UUID</tt> and <tt>leastSigBits</tt> becomes the least significant
* 64 bits of the <tt>UUID</tt>.
*
* @param mostSigBits
* @param leastSigBits
*/
public EgovFormBasedUUID(long mostSigBits, long leastSigBits) {
this.mostSigBits = mostSigBits;
this.leastSigBits = leastSigBits;
}
/**
* Static factory to retrieve a type 4 (pseudo randomly generated) UUID.
*
* The <code>UUID</code> is generated using a cryptographically strong
* pseudo random number generator.
*
* @return a randomly generated <tt>UUID</tt>.
*/
public static EgovFormBasedUUID randomUUID() {
SecureRandom ng = numberGenerator;
if (ng == null) {
numberGenerator = ng = new SecureRandom();
}
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
randomBytes[6] &= 0x0f; /* clear version */
randomBytes[6] |= 0x40; /* set to version 4 */
randomBytes[8] &= 0x3f; /* clear variant */
randomBytes[8] |= 0x80; /* set to IETF variant */
return new EgovFormBasedUUID(randomBytes);
}
/**
* Static factory to retrieve a type 3 (name based) <tt>UUID</tt> based on
* the specified byte array.
*
* @param name
* a byte array to be used to construct a <tt>UUID</tt>.
* @return a <tt>UUID</tt> generated from the specified array.
*/
public static EgovFormBasedUUID nameUUIDFromBytes(byte[] name) {
MessageDigest md;
try {
// 2011.10.10 보안점검 후속조치 암호화 알고리즘 변경(MD5 -> SHA-256)
//md = MessageDigest.getInstance("MD5");
md = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException nsae) {
//throw new InternalError("MD5 not supported");
throw new InternalError("SHA-256 not supported");
}
// 2011.10.10 보안점검 후속조치
if (md == null) {
throw new RuntimeException("MessageDigest is null!!");
}
// 2014.09.20 보안점검 후속 조치
// Random 방식의 salt 추가
SecureRandom ng = new SecureRandom();
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
md.reset();
md.update(randomBytes);
byte[] sha = md.digest(name);
byte[] md5Bytes = new byte[8];
System.arraycopy(sha, 0, md5Bytes, 0, 8);
//2011.10.10 보안점검 후속조치
md5Bytes[6] &= 0x0f; /* clear version */
md5Bytes[6] |= 0x30; /* set to version 3 */
md5Bytes[8] &= 0x3f; /* clear variant */
md5Bytes[8] |= 0x80; /* set to IETF variant */
return new EgovFormBasedUUID(md5Bytes);
}
/**
* Creates a <tt>UUID</tt> from the string standard representation as
* described in the {@link #toString} method.
*
* @param name
* a string that specifies a <tt>UUID</tt>.
* @return a <tt>UUID</tt> with the specified value.
* @throws IllegalArgumentException
* if name does not conform to the string representation as
* described in {@link #toString}.
*/
public static EgovFormBasedUUID fromString(String name) {
String[] components = name.split("-");
if (components.length != 5)
throw new IllegalArgumentException("Invalid UUID string: " + name);
for (int i = 0; i < 5; i++)
components[i] = "0x" + components[i];
long mostSigBits = Long.decode(components[0]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[1]).longValue();
mostSigBits <<= 16;
mostSigBits |= Long.decode(components[2]).longValue();
long leastSigBits = Long.decode(components[3]).longValue();
leastSigBits <<= 48;
leastSigBits |= Long.decode(components[4]).longValue();
return new EgovFormBasedUUID(mostSigBits, leastSigBits);
}
// Field Accessor Methods
/**
* Returns the least significant 64 bits of this UUID's 128 bit value.
*
* @return the least significant 64 bits of this UUID's 128 bit value.
*/
public long getLeastSignificantBits() {
return leastSigBits;
}
/**
* Returns the most significant 64 bits of this UUID's 128 bit value.
*
* @return the most significant 64 bits of this UUID's 128 bit value.
*/
public long getMostSignificantBits() {
return mostSigBits;
}
/**
* The version number associated with this <tt>UUID</tt>. The version
* number describes how this <tt>UUID</tt> was generated.
*
* The version number has the following meaning:
* <p>
* <ul>
* <li>1 Time-based UUID
* <li>2 DCE security UUID
* <li>3 Name-based UUID
* <li>4 Randomly generated UUID
* </ul>
*
* @return the version number of this <tt>UUID</tt>.
*/
public int version() {
if (version < 0) {
// Version is bits masked by 0x000000000000F000 in MS long
version = (int) ((mostSigBits >> 12) & 0x0f);
}
return version;
}
/**
* The variant number associated with this <tt>UUID</tt>. The variant
* number describes the layout of the <tt>UUID</tt>.
*
* The variant number has the following meaning:
* <p>
* <ul>
* <li>0 Reserved for NCS backward compatibility
* <li>2 The Leach-Salz variant (used by this class)
* <li>6 Reserved, Microsoft Corporation backward compatibility
* <li>7 Reserved for future definition
* </ul>
*
* @return the variant number of this <tt>UUID</tt>.
*/
public int variant() {
if (variant < 0) {
// This field is composed of a varying number of bits
if ((leastSigBits >>> 63) == 0) {
variant = 0;
} else if ((leastSigBits >>> 62) == 2) {
variant = 2;
} else {
variant = (int) (leastSigBits >>> 61);
}
}
return variant;
}
/**
* The timestamp value associated with this UUID.
*
* <p>
* The 60 bit timestamp value is constructed from the time_low, time_mid,
* and time_hi fields of this <tt>UUID</tt>. The resulting timestamp is
* measured in 100-nanosecond units since midnight, October 15, 1582 UTC.
* <p>
*
* The timestamp value is only meaningful in a time-based UUID, which has
* version type 1. If this <tt>UUID</tt> is not a time-based UUID then
* this method throws UnsupportedOperationException.
*
* @throws UnsupportedOperationException
* if this UUID is not a version 1 UUID.
*/
public long timestamp() {
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
long result = timestamp;
if (result < 0) {
result = (mostSigBits & 0x0000000000000FFFL) << 48;
result |= ((mostSigBits >> 16) & 0xFFFFL) << 32;
result |= mostSigBits >>> 32;
timestamp = result;
}
return result;
}
/**
* The clock sequence value associated with this UUID.
*
* <p>
* The 14 bit clock sequence value is constructed from the clock sequence
* field of this UUID. The clock sequence field is used to guarantee
* temporal uniqueness in a time-based UUID.
* <p>
*
* The clockSequence value is only meaningful in a time-based UUID, which
* has version type 1. If this UUID is not a time-based UUID then this
* method throws UnsupportedOperationException.
*
* @return the clock sequence of this <tt>UUID</tt>.
* @throws UnsupportedOperationException
* if this UUID is not a version 1 UUID.
*/
public int clockSequence() {
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
if (sequence < 0) {
sequence = (int) ((leastSigBits & 0x3FFF000000000000L) >>> 48);
}
return sequence;
}
/**
* The node value associated with this UUID.
*
* <p>
* The 48 bit node value is constructed from the node field of this UUID.
* This field is intended to hold the IEEE 802 address of the machine that
* generated this UUID to guarantee spatial uniqueness.
* <p>
*
* The node value is only meaningful in a time-based UUID, which has version
* type 1. If this UUID is not a time-based UUID then this method throws
* UnsupportedOperationException.
*
* @return the node value of this <tt>UUID</tt>.
* @throws UnsupportedOperationException
* if this UUID is not a version 1 UUID.
*/
public long node() {
if (version() != 1) {
throw new UnsupportedOperationException("Not a time-based UUID");
}
if (node < 0) {
node = leastSigBits & 0x0000FFFFFFFFFFFFL;
}
return node;
}
// Object Inherited Methods
/**
* Returns a <code>String</code> object representing this
* <code>UUID</code>.
*
* <p>
* The UUID string representation is as described by this BNF :
*
* <pre>
* UUID = &lt;time_low&gt; &quot;-&quot; &lt;time_mid&gt; &quot;-&quot;
* &lt;time_high_and_version&gt; &quot;-&quot;
* &lt;variant_and_sequence&gt; &quot;-&quot;
* &lt;node&gt;
* time_low = 4*&lt;hexOctet&gt;
* time_mid = 2*&lt;hexOctet&gt;
* time_high_and_version = 2*&lt;hexOctet&gt;
* variant_and_sequence = 2*&lt;hexOctet&gt;
* node = 6*&lt;hexOctet&gt;
* hexOctet = &lt;hexDigit&gt;&lt;hexDigit&gt;
* hexDigit =
* &quot;0&quot; | &quot;1&quot; | &quot;2&quot; | &quot;3&quot; | &quot;4&quot; | &quot;5&quot; | &quot;6&quot; | &quot;7&quot; | &quot;8&quot; | &quot;9&quot;
* | &quot;a&quot; | &quot;b&quot; | &quot;c&quot; | &quot;d&quot; | &quot;e&quot; | &quot;f&quot;
* | &quot;A&quot; | &quot;B&quot; | &quot;C&quot; | &quot;D&quot; | &quot;E&quot; | &quot;F&quot;
* </pre>
*
* @return a string representation of this <tt>UUID</tt>.
*/
@Override
public String toString() {
return (digits(mostSigBits >> 32, 8) + "-"
+ digits(mostSigBits >> 16, 4) + "-" + digits(mostSigBits, 4)
+ "-" + digits(leastSigBits >> 48, 4) + "-" + digits(
leastSigBits, 12));
}
/** Returns val represented by the specified number of hex digits. */
private static String digits(long val, int digits) {
long hi = 1L << (digits * 4);
return Long.toHexString(hi | (val & (hi - 1))).substring(1);
}
/**
* Returns a hash code for this <code>UUID</code>.
*
* @return a hash code value for this <tt>UUID</tt>.
*/
@Override
public int hashCode() {
if (hashCode == -1) {
hashCode = (int) ((mostSigBits >> 32) ^ mostSigBits
^ (leastSigBits >> 32) ^ leastSigBits);
}
return hashCode;
}
/**
* Compares this object to the specified object. The result is <tt>true</tt>
* if and only if the argument is not <tt>null</tt>, is a <tt>UUID</tt>
* object, has the same variant, and contains the same value, bit for bit,
* as this <tt>UUID</tt>.
*
* @param obj
* the object to compare with.
* @return <code>true</code> if the objects are the same;
* <code>false</code> otherwise.
*/
@Override
public boolean equals(Object obj) {
// 보안 취약점 점검 지적사항 반영 시작
if (obj == null)
return false;
// 보안 취약점 점검 지적사항 반영 시작
if (!(obj instanceof EgovFormBasedUUID))
return false;
if (((EgovFormBasedUUID) obj).variant() != this.variant())
return false;
EgovFormBasedUUID id = (EgovFormBasedUUID) obj;
return (mostSigBits == id.mostSigBits && leastSigBits == id.leastSigBits);
}
// Comparison Operations
/**
* Compares this UUID with the specified UUID.
*
* <p>
* The first of two UUIDs follows the second if the most significant field
* in which the UUIDs differ is greater for the first UUID.
*
* @param val
* <tt>UUID</tt> to which this <tt>UUID</tt> is to be
* compared.
* @return -1, 0 or 1 as this <tt>UUID</tt> is less than, equal to, or
* greater than <tt>val</tt>.
*/
public int compareTo(EgovFormBasedUUID val) {
// The ordering is intentionally set up so that the UUIDs
// can simply be numerically compared as two numbers
return (this.mostSigBits < val.mostSigBits ? -1
: (this.mostSigBits > val.mostSigBits ? 1
: (this.leastSigBits < val.leastSigBits ? -1
: (this.leastSigBits > val.leastSigBits ? 1 : 0))));
}
/**
* Reconstitute the <tt>UUID</tt> instance from a stream (that is,
* deserialize it). This is necessary to set the transient fields to their
* correct uninitialized value so they will be recomputed on demand.
*/
private void readObject(java.io.ObjectInputStream in)
throws java.io.IOException, ClassNotFoundException {
in.defaultReadObject();
// Set "cached computation" fields to their initial values
version = -1;
variant = -1;
timestamp = -1;
sequence = -1;
node = -1;
hashCode = -1;
}
}

View File

@ -0,0 +1,207 @@
package egovframework.com.utl.fcc.service;
/**
*
* 포맷유효성체크 대한 Util 클래스
* @author 공통컴포넌트 개발팀 윤성록
* @since 2009.06.23
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.06.23 윤성록 최초 생성
*
* </pre>
*/
public class EgovFormatCheckUtil {
/**
* <pxxx - xxx- xxxx 형식의 전화번호 , 중간, 문자열 3개 입력 받아 유요한 전화번호형식인지 검사.</p>
*
*
* @param 전화번호 문자열( 3개 )
* @return 유효한 전화번호 형식인지 여부 (True/False)
*/
public static boolean checkFormatTell(String tell1, String tell2, String tell3) {
String[] check = {"02", "031", "032", "033", "041", "042", "043", "051", "052", "053", "054", "055", "061",
"062", "063", "070", "080", "0505"}; //존재하는 국번 데이터
String temp = tell1 + tell2 + tell3;
for(int i=0; i < temp.length(); i++){
if (temp.charAt(i) < '0' || temp.charAt(i) > '9')
return false;
} //숫자가 아닌 값이 들어왔는지를 확인
for(int i = 0; i < check.length; i++){
if(tell1.equals(check[i])) break;
if(i == check.length - 1) return false;
} //국번입력이 제대로 되었는지를 확인
if(tell2.charAt(0) == '0') return false;
if(tell1.equals("02")){
if(tell2.length() != 3 && tell2.length() !=4) return false;
if(tell3.length() != 4) return false; //서울지역(02)국번 입력때의 전화 번호 형식유효성 체크
}else{
if(tell2.length() != 3) return false;
if(tell3.length() != 4) return false;
} //서울을 제외한 지역(국번 입력때의 전화 번호 형식유효성 체크
return true;
}
/**
* <p>xxx - xxx- xxxx 형식의 전화번호 하나를 입력 받아 유요한 전화번호형식인지 검사.</p>
*
*
* @param 전화번호 문자열 (1개)
* @return 유효한 전화번호 형식인지 여부 (True/False)
*/
public static boolean checkFormatTell(String tellNumber) {
String temp1;
String temp2;
String temp3;
String tell = tellNumber;
tell = tell.replace("-", "");
if(tell.length() < 9 || tell.length() > 11 || tell.charAt(0) != '0') return false; //전화번호 길이에 대한 체크
if(tell.charAt(1) =='2'){ //서울지역 (02)국번의 경우일때
temp1 = tell.substring(0,2);
if(tell.length() == 9){
temp2 = tell.substring(2,5);
temp3 = tell.substring(5,9);
}else if(tell.length() == 10){
temp2 = tell.substring(2,6);
temp3 = tell.substring(6,10);
}else
return false;
} else if(tell.substring(0,4).equals("0505")){ //평생번호(0505)국번의 경우일때
if(tell.length() != 11) return false;
temp1 = tell.substring(0,4);
temp2 = tell.substring(4,7);
temp3 = tell.substring(7,11);
} else { // 서울지역 "0505" 제외한 일반적인 경우일때
if(tell.length() != 10) return false;
temp1 = tell.substring(0,3);
temp2 = tell.substring(3,6);
temp3 = tell.substring(6,10);
}
return checkFormatTell(temp1, temp2, temp3);
}
/**
* <p>xxx - xxx- xxxx 형식의 휴대폰번호 , 중간, 문자열 3개 입력 받아 유요한 휴대폰번호형식인지 검사.</p>
*
*
* @param 휴대폰번호 문자열,(3개)
* @return 유효한 휴대폰번호 형식인지 여부 (True/False)
*/
public static boolean checkFormatCell(String cell1, String cell2, String cell3) {
String[] check = {"010", "011", "016", "017", "018", "019"}; //유효한 휴대폰 첫자리 번호 데이터
String temp = cell1 + cell2 + cell3;
for(int i=0; i < temp.length(); i++){
if (temp.charAt(i) < '0' || temp.charAt(i) > '9')
return false;
} //숫자가 아닌 값이 들어왔는지를 확인
for(int i = 0; i < check.length; i++){
if(cell1.equals(check[i])) break;
if(i == check.length - 1) return false;
} // 휴대폰 첫자리 번호입력의 유효성 체크
if(cell2.charAt(0) == '0') return false;
if(cell2.length() != 3 && cell2.length() !=4) return false;
if(cell3.length() != 4) return false;
return true;
}
/**
* <p>XXXXXXXXXX 형식의 휴대폰번호 문자열 3개 입력 받아 유요한 휴대폰번호형식인지 검사.</p>
*
*
* @param 휴대폰번호 문자열(1개)
* @return 유효한 휴대폰번호 형식인지 여부 (True/False)
*/
public static boolean checkFormatCell(String cellNumber) {
String temp1;
String temp2;
String temp3;
String cell = cellNumber;
cell = cell.replace("-", "");
if(cell.length() < 10 || cell.length() > 11 || cell.charAt(0) != '0') return false;
if(cell.length() == 10){ //전체 10자리 휴대폰 번호일 경우
temp1 = cell.substring(0,3);
temp2 = cell.substring(3,6);
temp3 = cell.substring(6,10);
}else{ //전체 11자리 휴대폰 번호일 경우
temp1 = cell.substring(0,3);
temp2 = cell.substring(3,7);
temp3 = cell.substring(7,11);
}
return checkFormatCell(temp1, temp2, temp3);
}
/**
* <p> 이메일의 , 문자열 2개 입력 받아 유요한 이메일형식인지 검사.</p>
*
*
* @param 이메일 문자열 (2개)
* @return 유효한 이메일 형식인지 여부 (True/False)
*/
public static boolean checkFormatMail(String mail1, String mail2) {
int count = 0;
for(int i = 0; i < mail1.length(); i++){
if(mail1.charAt(i) <= 'z' && mail1.charAt(i) >= 'a') continue;
else if(mail1.charAt(i) <= 'Z' && mail1.charAt(i) >= 'A') continue;
else if(mail1.charAt(i) <= '9' && mail1.charAt(i) >= '0') continue;
else if(mail1.charAt(i) == '-' && mail1.charAt(i) == '_') continue;
else return false;
} // 유효한 문자, 숫자인지 체크
for(int i = 0; i < mail2.length(); i++){
if(mail2.charAt(i) <= 'z' && mail2.charAt(i) >= 'a') continue;
else if(mail2.charAt(i) == '.'){ count++; continue;}
else return false;
} // 메일 주소의 형식 체크(xxx.xxx 형태)
if(count == 1) return true;
else return false;
}
/**
* <p> 이메일의 전체문자열 1개 입력 받아 유요한 이메일형식인지 검사.</p>
*
*
* @param 이메일 문자열 (1개)
* @return 유효한 이메일 형식인지 여부 (True/False)
*/
public static boolean checkFormatMail(String mail) {
String[] temp = mail.split("@"); // '@' 기점으로 , 문자열 구분
if(temp.length == 2) return checkFormatMail(temp[0], temp[1]);
else return false;
}
}

View File

@ -0,0 +1,246 @@
package egovframework.com.utl.fcc.service;
/**
*
* 번호유효성체크 대한 Util 클래스
* @author 공통컴포넌트 개발팀 윤성록
* @since 2009.06.10
* @version 1.0
* @see
*
* <pre>
* << 개정이력(Modification Information) >>
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.06.10 윤성록 최초 생성
* 2012.02.27 이기하 법인번호 체크로직 수정
*
* </pre>
*/
public class EgovNumberCheckUtil {
/**
* <p>XXXXXX - XXXXXXX 형식의 주민번호 , 문자열 2개 입력 받아 유효한 주민번호인지 검사.</p>
*
*
* @param 6자리 주민앞번호 문자열 , 7자리 주민뒷번호 문자열
* @return 유효한 주민번호인지 여부 (True/False)
*/
@SuppressWarnings("static-access")
public static boolean checkJuminNumber(String jumin1, String jumin2) {
EgovDateUtil egovDateUtil = new EgovDateUtil();
String juminNumber = jumin1 + jumin2;
String IDAdd = "234567892345"; // 주민등록번호에 가산할
int count_num = 0;
int add_num = 0;
int total_id = 0; //검증을 위한 변수선언
if (juminNumber.length() != 13) return false; // 주민등록번호 자리수가 맞는가를 확인
for (int i = 0; i <12 ; i++){
if(juminNumber.charAt(i)< '0' || juminNumber.charAt(i) > '9') return false; //숫자가 아닌 값이 들어왔는지를 확인
count_num = Character.getNumericValue(juminNumber.charAt(i));
add_num = Character.getNumericValue(IDAdd.charAt(i));
total_id += count_num * add_num; //유효자리 검증식을 적용
}
if(Character.getNumericValue(juminNumber.charAt(0)) == 0 || Character.getNumericValue(juminNumber.charAt(0)) == 1){
if(Character.getNumericValue(juminNumber.charAt(6)) > 4) return false;
String temp = "20" + juminNumber.substring(0,6);
if(!egovDateUtil.checkDate(temp)) return false;
}else{
if(Character.getNumericValue(juminNumber.charAt(6)) > 2) return false;
String temp = "19" + juminNumber.substring(0,6);
if(!egovDateUtil.checkDate(temp)) return false;
} //주민번호 앞자리 날짜유효성체크 & 성별구분 숫자 체크
if(Character.getNumericValue(juminNumber.charAt(12)) == (11 - (total_id % 11)) % 10) //마지막 유효숫자와 검증식을 통한 값의 비교
return true;
else
return false;
}
/**
* <p>XXXXXXXXXXXXX 형식의 13자리 주민번호 1개를 입력 받아 유효한 주민번호인지 검사.</p>
*
*
* @param 13자리 주민번호 문자열
* @return 유효한 주민번호인지 여부 (True/False)
*/
public static boolean checkJuminNumber(String jumin) {
if(jumin.length() != 13) return false;
return checkJuminNumber(jumin.substring(0,6), jumin.substring(6,13)); //주민번호
}
/**
* <p>XXXXXX - XXXXXXX 형식의 법인번호 , 문자열 2개 입력 받아 유효한 법인번호인지 검사.</p>
*
*
* @param 6자리 법인앞번호 문자열 , 7자리 법인뒷번호 문자열
* @return 유효한 법인번호인지 여부 (True/False)
*/
public static boolean checkBubinNumber(String bubin1, String bubin2) {
String bubinNumber = bubin1 + bubin2;
int hap = 0;
int temp = 1; //유효검증식에 사용하기 위한 변수
if(bubinNumber.length() != 13) return false; //법인번호의 자리수가 맞는 지를 확인
for(int i=0; i < 13; i++){
if (bubinNumber.charAt(i) < '0' || bubinNumber.charAt(i) > '9') //숫자가 아닌 값이 들어왔는지를 확인
return false;
}
// 2012.02.27 법인번호 체크로직 수정( i<13 -> i<12 )
// 맨끝 자리 수는 전산시스템으로 오류를 검증하기 위해 부여되는 검증번호임
for ( int i=0; i<12; i++){
if(temp ==3) temp = 1;
hap = hap + (Character.getNumericValue(bubinNumber.charAt(i)) * temp);
temp++;
} //검증을 위한 식의 계산
if ((10 - (hap%10))%10 == Character.getNumericValue(bubinNumber.charAt(12))) //마지막 유효숫자와 검증식을 통한 값의 비교
return true;
else
return false;
}
/**
* <p>XXXXXXXXXXXXX 형식의 13자리 법인번호 1개를 입력 받아 유효한 법인번호인지 검사.</p>
*
*
* @param 13자리 법인번호 문자열
* @return 유효한 법인번호인지 여부 (True/False)
*/
public static boolean checkBubinNumber(String bubin) {
if(bubin.length() != 13) return false;
return checkBubinNumber(bubin.substring(0,6), bubin.substring(6,13));
}
/**
* <p>xxx - xx - xxxx 형식의 사업자번호 ,중간, 문자열 3개 입력 받아 유효한 사업자번호인지 검사.</p>
*
*
* @param 3자리 사업자앞번호 문자열 , 2자리 사업자중간번호 문자열, 5자리 사업자뒷번호 문자열
* @return 유효한 사업자번호인지 여부 (True/False)
*/
public static boolean checkCompNumber(String comp1, String comp2, String comp3) {
String compNumber = comp1 + comp2 + comp3;
int hap = 0;
int temp = 0;
int check[] = {1,3,7,1,3,7,1,3,5}; //사업자번호 유효성 체크 필요한
if(compNumber.length() != 10) //사업자번호의 길이가 맞는지를 확인한다.
return false;
for(int i=0; i < 9; i++){
if(compNumber.charAt(i) < '0' || compNumber.charAt(i) > '9') //숫자가 아닌 값이 들어왔는지를 확인한다.
return false;
hap = hap + (Character.getNumericValue(compNumber.charAt(i)) * check[temp]); //검증식 적용
temp++;
}
hap += (Character.getNumericValue(compNumber.charAt(8))*5)/10;
if ((10 - (hap%10))%10 == Character.getNumericValue(compNumber.charAt(9))) //마지막 유효숫자와 검증식을 통한 값의 비교
return true;
else
return false;
}
/**
* <p>XXXXXXXXXX 형식의 10자리 사업자번호 3개를 입력 받아 유효한 사업자번호인지 검사.</p>
*
*
* @param 10자리 사업자번호 문자열
* @return 유효한 사업자번호인지 여부 (True/False)
*/
public static boolean checkCompNumber(String comp) {
if(comp.length() != 10) return false;
return checkCompNumber(comp.substring(0,3), comp.substring(3,5), comp.substring(5,10));
}
/**
* <p>XXXXXX - XXXXXXX 형식의 외국인등록번호 , 문자열 2개 입력 받아 유효한 외국인등록번호인지 검사.</p>
*
*
* @param 6자리 외국인등록앞번호 문자열 , 7자리 외국인등록뒷번호 문자열
* @return 유효한 외국인등록번호인지 여부 (True/False)
*/
@SuppressWarnings("static-access")
public static boolean checkforeignNumber( String foreign1, String foreign2 ) {
EgovDateUtil egovDateUtil = new EgovDateUtil();
String foreignNumber = foreign1 + foreign2;
int check = 0;
if( foreignNumber.length() != 13 ) //외국인등록번호의 길이가 맞는지 확인한다.
return false;
for(int i=0; i < 13; i++){
if (foreignNumber.charAt(i) < '0' || foreignNumber.charAt(i) > '9') //숫자가 아닌 값이 들어왔는지를 확인한다.
return false;
}
if(Character.getNumericValue(foreignNumber.charAt(0)) == 0 || Character.getNumericValue(foreignNumber.charAt(0)) == 1){
if(Character.getNumericValue(foreignNumber.charAt(6)) == 5 && Character.getNumericValue(foreignNumber.charAt(6)) == 6) return false;
String temp = "20" + foreignNumber.substring(0,6);
if(!egovDateUtil.checkDate(temp)) return false;
}else{
if(Character.getNumericValue(foreignNumber.charAt(6)) == 5 && Character.getNumericValue(foreignNumber.charAt(6)) == 6) return false;
String temp = "19" + foreignNumber.substring(0,6);
if(!egovDateUtil.checkDate(temp)) return false;
} //외국인등록번호 앞자리 날짜유효성체크 & 성별구분 숫자 체크
for( int i = 0 ; i < 12 ; i++ ) {
check += ( ( 9 - i % 8 ) * Character.getNumericValue( foreignNumber.charAt( i ) ) );
}
if ( check % 11 == 0 ){
check = 1;
}else if ( check % 11==10 ){
check = 0;
}else
check = check % 11;
if ( check + 2 > 9 ){
check = check + 2- 10;
}else check = check+2; //검증식을 통합 값의 도출
if( check == Character.getNumericValue( foreignNumber.charAt( 12 ) ) ) //마지막 유효숫자와 검증식을 통한 값의 비교
return true;
else
return false;
}
/**
* <p>XXXXXXXXXXXXX 형식의 13자리 외국인등록번호 1개를 입력 받아 유효한 외국인등록번호인지 검사.</p>
*
*
* @param 13자리 외국인등록번호 문자열
* @return 유효한 외국인등록번호인지 여부 (True/False)
*/
public static boolean checkforeignNumber( String foreign ) {
if(foreign.length() != 13) return false;
return checkforeignNumber(foreign.substring(0,6), foreign.substring(6,13));
}
}

View File

@ -0,0 +1,258 @@
package egovframework.com.utl.fcc.service;
import java.text.NumberFormat;
import java.util.Locale;
/**
* 숫자, 통화, 퍼센트에 대한 형식 변환을 수행하는 클래스
*/
public class EgovNumberFormat {
private static final int MAX_FRACTION_DIGIT = 3;
private static final boolean GROUPING_USED = true;
/**
* 기본 Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param number 숫자
* @return 숫자 문자열
*/
public static String formatNumber(Number number) {
return formatNumber(number, GROUPING_USED, MAX_FRACTION_DIGIT);
}
/**
* Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @return 숫자 문자열
*/
public static String formatNumber(Locale locale, Number number) {
return formatNumber(locale, number, GROUPING_USED, MAX_FRACTION_DIGIT);
}
/**
* 기본 Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @return 숫자 문자열
*/
public static String formatNumber(Number number, boolean groupingUsed) {
return formatNumber(number, groupingUsed, MAX_FRACTION_DIGIT);
}
/**
* Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @return 숫자 문자열
*/
public static String formatNumber(Locale locale, Number number, boolean groupingUsed) {
return formatNumber(locale, number, groupingUsed, MAX_FRACTION_DIGIT);
}
/**
* 기본 Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param number 숫자
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 숫자 문자열
*/
public static String formatNumber(Number number, int maxFactionDigits) {
return formatNumber(number, GROUPING_USED, maxFactionDigits);
}
/**
* Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 숫자 문자열
*/
public static String formatNumber(Locale locale, Number number, int maxFactionDigits) {
return formatNumber(locale, number, GROUPING_USED, maxFactionDigits);
}
/**
* 기본 Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 숫자 문자열
*/
public static String formatNumber(Number number, boolean groupingUsed, int maxFactionDigits) {
NumberFormat numberberFormat = NumberFormat.getNumberInstance();
numberberFormat.setGroupingUsed(groupingUsed);
numberberFormat.setMaximumFractionDigits(maxFactionDigits);
return numberberFormat.format(number);
}
/**
* Locale에 해당하는 형식으로 숫자를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 숫자 문자열
*/
public static String formatNumber(Locale locale, Number number, boolean groupingUsed, int maxFactionDigits) {
NumberFormat numberberFormat = NumberFormat.getNumberInstance(locale);
numberberFormat.setGroupingUsed(groupingUsed);
numberberFormat.setMaximumFractionDigits(maxFactionDigits);
return numberberFormat.format(number);
}
/**
* 기본 Locale에 해당하는 형식으로 통화를 변환한다.
*
* @param number 숫자
* @return 통화 문자열
*/
public static String formatCurrency(Number number) {
return formatCurrency(number, GROUPING_USED);
}
/**
* Locale에 해당하는 형식으로 통화를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @return 통화 문자열
*/
public static String formatCurrency(Locale locale, Number number) {
return formatCurrency(locale, number, GROUPING_USED);
}
/**
* 기본 Locale에 해당하는 형식으로 통화를 변환한다.
*
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @return 통화 문자열
*/
public static String formatCurrency(Number number, boolean groupingUsed) {
NumberFormat numberberFormat = NumberFormat.getCurrencyInstance();
numberberFormat.setGroupingUsed(groupingUsed);
return numberberFormat.format(number);
}
/**
* Locale에 해당하는 형식으로 통화를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @return 통화 문자열
*/
public static String formatCurrency(Locale locale, Number number, boolean groupingUsed) {
NumberFormat numberberFormat = NumberFormat.getCurrencyInstance(locale);
numberberFormat.setGroupingUsed(groupingUsed);
return numberberFormat.format(number);
}
/**
* 기본 Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param number 숫자
* @return 퍼센트 문자열
*/
public static String formatPercent(Number number) {
return formatPercent(number, GROUPING_USED, MAX_FRACTION_DIGIT);
}
/**
* Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @return 퍼센트 문자열
*/
public static String formatPercent(Locale locale, Number number) {
return formatPercent(locale, number, GROUPING_USED, MAX_FRACTION_DIGIT);
}
/**
* 기본 Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @return 퍼센트 문자열
*/
public static String formatPercent(Number number, boolean groupingUsed) {
return formatPercent(number, groupingUsed, MAX_FRACTION_DIGIT);
}
/**
* Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @return 퍼센트 문자열
*/
public static String formatPercent(Locale locale, Number number, boolean groupingUsed) {
return formatPercent(locale, number, groupingUsed, MAX_FRACTION_DIGIT);
}
/**
* 기본 Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param number 숫자
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 퍼센트 문자열
*/
public static String formatPercent(Number number, int maxFactionDigits) {
return formatPercent(number, GROUPING_USED, maxFactionDigits);
}
/**
* Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 퍼센트 문자열
*/
public static String formatPercent(Locale locale, Number number, int maxFactionDigits) {
return formatPercent(locale, number, GROUPING_USED, maxFactionDigits);
}
/**
* 기본 Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 퍼센트 문자열
*/
public static String formatPercent(Number number, boolean groupingUsed, int maxFactionDigits) {
NumberFormat numberberFormat = NumberFormat.getPercentInstance();
numberberFormat.setGroupingUsed(groupingUsed);
numberberFormat.setMaximumFractionDigits(maxFactionDigits);
return numberberFormat.format(number);
}
/**
* Locale에 해당하는 형식으로 퍼센트를 변환한다.
*
* @param locale 로케일
* @param number 숫자
* @param groupingUsed 그룹 분리기호 포함 여부
* @param maxFactionDigits 변환된 문자열에서 출력할 소수점 이하 최대 자리수
* @return 퍼센트 문자열
*/
public static String formatPercent(Locale locale, Number number, boolean groupingUsed, int maxFactionDigits) {
NumberFormat numberberFormat = NumberFormat.getPercentInstance(locale);
numberberFormat.setGroupingUsed(groupingUsed);
numberberFormat.setMaximumFractionDigits(maxFactionDigits);
return numberberFormat.format(number);
}
}

View File

@ -0,0 +1,216 @@
/**
* @Class Name : EgovNumberUtil.java
* @Description : 숫자 데이터 처리 관련 유틸리티
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.02.13 이삼섭 최초 생성
*
* @author 공통 서비스 개발팀 이삼섭
* @since 2009. 02. 13
* @version 1.0
* @see
*
*/
package egovframework.com.utl.fcc.service;
import java.security.SecureRandom;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class EgovNumberUtil {
/**
* 특정숫자 집합에서 랜덤 숫자를 구하는 기능 시작숫자와 종료숫자 사이에서 구한 랜덤 숫자를 반환한다
*
* @param startNum - 시작숫자
* @param endNum - 종료숫자
* @return 랜덤숫자
* @see
*/
public static int getRandomNum(int startNum, int endNum) {
int randomNum = 0;
// 랜덤 객체 생성
SecureRandom rnd = new SecureRandom();
do {
// 종료숫자내에서 랜덤 숫자를 발생시킨다.
randomNum = rnd.nextInt(endNum + 1);
} while (randomNum < startNum); // 랜덤 숫자가 시작숫자보다 작을경우 다시 랜덤숫자를 발생시킨다.
return randomNum;
}
/**
* 특정 숫자 집합에서 특정 숫자가 있는지 체크하는 기능 12345678에서 7이 있는지 없는지 체크하는 기능을 제공함
*
* @param sourceInt - 특정숫자집합
* @param searchInt - 검색숫자
* @return 존재여부
* @see
*/
public static Boolean getNumSearchCheck(int sourceInt, int searchInt) {
String sourceStr = String.valueOf(sourceInt);
String searchStr = String.valueOf(searchInt);
// 특정숫자가 존재하는지 하여 위치값을 리턴한다. 없을 -1
if (sourceStr.indexOf(searchStr) == -1) {
return false;
} else {
return true;
}
}
/**
* 숫자타입을 문자열로 변환하는 기능 숫자 20081212를 문자열 '20081212' 변환하는 기능
*
* @param srcNumber - 숫자
* @return 문자열
* @see
*/
public static String getNumToStrCnvr(int srcNumber) {
String rtnStr = null;
rtnStr = String.valueOf(srcNumber);
return rtnStr;
}
/**
* 숫자타입을 데이트 타입으로 변환하는 기능
* 숫자 20081212를 데이트타입 '2008-12-12' 변환하는 기능
* @param srcNumber - 숫자
* @return String
* @see
*/
public static String getNumToDateCnvr(int srcNumber) {
String pattern = null;
String cnvrStr = null;
String srcStr = String.valueOf(srcNumber);
// Date 형태인 8자리 14자리만 정상처리
if (srcStr.length() != 8 && srcStr.length() != 14) {
throw new IllegalArgumentException("Invalid Number: " + srcStr + " Length=" + srcStr.trim().length());
}
if (srcStr.length() == 8) {
pattern = "yyyyMMdd";
} else if (srcStr.length() == 14) {
pattern = "yyyyMMddhhmmss";
}
SimpleDateFormat dateFormatter = new SimpleDateFormat(pattern, Locale.KOREA);
Date cnvrDate = null;
try {
cnvrDate = dateFormatter.parse(srcStr);
} catch (ParseException e) {
throw new RuntimeException(e);
}
cnvrStr = String.format("%1$tY-%1$tm-%1$td", cnvrDate);
return cnvrStr;
}
/**
* 체크할 숫자 중에서 숫자인지 아닌지 체크하는 기능
* 숫자이면 True, 아니면 False를 반환한다
* @param checkStr - 체크문자열
* @return 숫자여부
* @see
*/
public static Boolean getNumberValidCheck(String checkStr) {
int i;
//String sourceStr = String.valueOf(sourceInt);
int checkStrLt = checkStr.length();
for (i = 0; i < checkStrLt; i++) {
// 아스키코드값( '0'-> 48, '9' -> 57)
if (checkStr.charAt(i) > 47 && checkStr.charAt(i) < 58) {
continue;
} else {
return false;
}
}
return true;
}
/**
* 특정숫자를 다른 숫자로 치환하는 기능 숫자 12345678에서 123를 999로 변환하는 기능을 제공(99945678)
*
* @param srcNumber - 숫자집합
* @param cnvrSrcNumber - 원래숫자
* @param cnvrTrgtNumber - 치환숫자
* @return 치환숫자
* @see
*/
public static int getNumberCnvr(int srcNumber, int cnvrSrcNumber, int cnvrTrgtNumber) {
// 입력받은 숫자를 문자열로 변환
String source = String.valueOf(srcNumber);
String subject = String.valueOf(cnvrSrcNumber);
String object = String.valueOf(cnvrTrgtNumber);
StringBuffer rtnStr = new StringBuffer();
String preStr = "";
String nextStr = source;
// 원본숫자에서 변환대상숫자의 위치를 찾는다.
while (source.indexOf(subject) >= 0) {
preStr = source.substring(0, source.indexOf(subject)); // 변환대상숫자 위치까지 숫자를 잘라낸다
nextStr = source.substring(source.indexOf(subject) + subject.length(), source.length());
source = nextStr;
rtnStr.append(preStr).append(object); // 변환대상위치 숫자에 변환할 숫자를 붙여준다.
}
rtnStr.append(nextStr); // 변환대상 숫자 이후 숫자를 붙여준다.
return Integer.parseInt(rtnStr.toString());
}
/**
* 특정숫자가 실수인지, 정수인지, 음수인지 체크하는 기능 123이 실수인지, 정수인지, 음수인지 체크하는 기능을 제공함
*
* @param srcNumber - 숫자집합
* @return -1(음수), 0(정수), 1(실수)
* @see
*/
public static int checkRlnoInteger(double srcNumber) {
// byte 1바이트 소수점이 없는 숫자로, 범위 -2^7 ~ 2^7 -1
// short 2바이트 소수점이 없는 숫자로, 범위 -2^15 ~ 2^15 -1
// int 4바이트 소수점이 없는 숫자로, 범위 -2^31 ~ 2^31 - 1
// long 8바이트 소수점이 없는 숫자로, 범위 -2^63 ~ 2^63-1
// float 4바이트 소수점이 있는 숫자로, 끝에 F 또는 f 붙는 숫자 (:3.14f)
// double 8바이트 소수점이 있는 숫자로, 끝에 아무것도 붙지 않는 숫자 (:3.14)
// 소수점이 있는 숫자로, 끝에 D 또는 d 붙는 숫자(:3.14d)
String cnvrString = null;
if (srcNumber < 0) {
return -1;
} else {
cnvrString = String.valueOf(srcNumber);
if (cnvrString.indexOf(".") == -1) {
return 0;
} else {
return 1;
}
}
}
}

View File

@ -0,0 +1,904 @@
/**
* @Class Name : EgovStringUtil.java
* @Description : 문자열 데이터 처리 관련 유틸리티
* @Modification Information
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.01.13 박정규 최초 생성
* 2009.02.13 이삼섭 내용 추가
*
* @author 공통 서비스 개발팀 박정규
* @since 2009. 01. 13
* @version 1.0
* @see
*
*/
package egovframework.com.utl.fcc.service;
/*
* Copyright 2001-2006 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the ";License&quot;);
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS"; BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class EgovStringUtil {
/**
* 문자열 <code>""</code>.
*/
public static final String EMPTY = "";
/**
* <p>Padding을 있는 최대 수치</p>
*/
// private static final int PAD_LIMIT = 8192;
/**
* <p>An array of <code>String</code>s used for padding.</p>
* <p>Used for efficient space padding. The length of each String expands as needed.</p>
*/
/*
private static final String[] PADDING = new String[Character.MAX_VALUE];
static {
// space padding is most common, start with 64 chars
PADDING[32] = " ";
}
*/
/**
* 문자열이 지정한 길이를 초과했을때 지정한길이에다가 해당 문자열을 붙여주는 메서드.
* @param source 원본 문자열 배열
* @param output 더할문자열
* @param slength 지정길이
* @return 지정길이로 잘라서 더할분자열 합친 문자열
*/
public static String cutString(String source, String output, int slength) {
String returnVal = null;
if (source != null) {
if (source.length() > slength) {
returnVal = source.substring(0, slength) + output;
} else
returnVal = source;
}
return returnVal;
}
/**
* 문자열이 지정한 길이를 초과했을때 해당 문자열을 삭제하는 메서드
* @param source 원본 문자열 배열
* @param slength 지정길이
* @return 지정길이로 잘라서 더할분자열 합친 문자열
*/
public static String cutString(String source, int slength) {
String result = null;
if (source != null) {
if (source.length() > slength) {
result = source.substring(0, slength);
} else
result = source;
}
return result;
}
/**
* <p>
* String이 비었거나("") 혹은 null 인지 검증한다.
* </p>
*
* <pre>
* StringUtil.isEmpty(null) = true
* StringUtil.isEmpty("") = true
* StringUtil.isEmpty(" ") = false
* StringUtil.isEmpty("bob") = false
* StringUtil.isEmpty(" bob ") = false
* </pre>
*
* @param str - 체크 대상 스트링오브젝트이며 null을 허용함
* @return <code>true</code> - 입력받은 String 문자열 또는 null인 경우
*/
public static boolean isEmpty(String str) {
return str == null || str.length() == 0;
}
/**
* <p>기준 문자열에 포함된 모든 대상 문자(char) 제거한다.</p>
*
* <pre>
* StringUtil.remove(null, *) = null
* StringUtil.remove("", *) = ""
* StringUtil.remove("queued", 'u') = "qeed"
* StringUtil.remove("queued", 'z') = "queued"
* </pre>
*
* @param str 입력받는 기준 문자열
* @param remove 입력받는 문자열에서 제거할 대상 문자열
* @return 제거대상 문자열이 제거된 입력문자열. 입력문자열이 null인 경우 출력문자열은 null
*/
public static String remove(String str, char remove) {
if (isEmpty(str) || str.indexOf(remove) == -1) {
return str;
}
char[] chars = str.toCharArray();
int pos = 0;
for (int i = 0; i < chars.length; i++) {
if (chars[i] != remove) {
chars[pos++] = chars[i];
}
}
return new String(chars, 0, pos);
}
/**
* <p>문자열 내부의 콤마 character(,) 모두 제거한다.</p>
*
* <pre>
* StringUtil.removeCommaChar(null) = null
* StringUtil.removeCommaChar("") = ""
* StringUtil.removeCommaChar("asdfg,qweqe") = "asdfgqweqe"
* </pre>
*
* @param str 입력받는 기준 문자열
* @return " , " 제거된 입력문자열
* 입력문자열이 null인 경우 출력문자열은 null
*/
public static String removeCommaChar(String str) {
return remove(str, ',');
}
/**
* <p>문자열 내부의 마이너스 character(-) 모두 제거한다.</p>
*
* <pre>
* StringUtil.removeMinusChar(null) = null
* StringUtil.removeMinusChar("") = ""
* StringUtil.removeMinusChar("a-sdfg-qweqe") = "asdfgqweqe"
* </pre>
*
* @param str 입력받는 기준 문자열
* @return " - " 제거된 입력문자열
* 입력문자열이 null인 경우 출력문자열은 null
*/
public static String removeMinusChar(String str) {
return remove(str, '-');
}
/**
* 원본 문자열의 포함된 특정 문자열을 새로운 문자열로 변환하는 메서드
* @param source 원본 문자열
* @param subject 원본 문자열에 포함된 특정 문자열
* @param object 변환할 문자열
* @return sb.toString() 새로운 문자열로 변환된 문자열
*/
public static String replace(String source, String subject, String object) {
StringBuffer rtnStr = new StringBuffer();
String preStr = "";
String nextStr = source;
String srcStr = source;
while (srcStr.indexOf(subject) >= 0) {
preStr = srcStr.substring(0, srcStr.indexOf(subject));
nextStr = srcStr.substring(srcStr.indexOf(subject) + subject.length(), srcStr.length());
srcStr = nextStr;
rtnStr.append(preStr).append(object);
}
rtnStr.append(nextStr);
return rtnStr.toString();
}
/**
* 원본 문자열의 포함된 특정 문자열 첫번째 한개만 새로운 문자열로 변환하는 메서드
* @param source 원본 문자열
* @param subject 원본 문자열에 포함된 특정 문자열
* @param object 변환할 문자열
* @return sb.toString() 새로운 문자열로 변환된 문자열 / source 특정문자열이 없는 경우 원본 문자열
*/
public static String replaceOnce(String source, String subject, String object) {
StringBuffer rtnStr = new StringBuffer();
String preStr = "";
String nextStr = source;
if (source.indexOf(subject) >= 0) {
preStr = source.substring(0, source.indexOf(subject));
nextStr = source.substring(source.indexOf(subject) + subject.length(), source.length());
rtnStr.append(preStr).append(object).append(nextStr);
return rtnStr.toString();
} else {
return source;
}
}
/**
* <code>subject</code> 포함된 각각의 문자를 object로 변환한다.
*
* @param source 원본 문자열
* @param subject 원본 문자열에 포함된 특정 문자열
* @param object 변환할 문자열
* @return sb.toString() 새로운 문자열로 변환된 문자열
*/
public static String replaceChar(String source, String subject, String object) {
StringBuffer rtnStr = new StringBuffer();
String preStr = "";
String nextStr = source;
String srcStr = source;
char chA;
for (int i = 0; i < subject.length(); i++) {
chA = subject.charAt(i);
if (srcStr.indexOf(chA) >= 0) {
preStr = srcStr.substring(0, srcStr.indexOf(chA));
nextStr = srcStr.substring(srcStr.indexOf(chA) + 1, srcStr.length());
srcStr = rtnStr.append(preStr).append(object).append(nextStr).toString();
}
}
return srcStr;
}
/**
* <p><code>str</code> <code>searchStr</code> 시작(index) 위치를 반환.</p>
*
* <p>입력값 <code>null</code> 있을 경우 <code>-1</code> 반환.</p>
*
* <pre>
* StringUtil.indexOf(null, *) = -1
* StringUtil.indexOf(*, null) = -1
* StringUtil.indexOf("", "") = 0
* StringUtil.indexOf("aabaabaa", "a") = 0
* StringUtil.indexOf("aabaabaa", "b") = 2
* StringUtil.indexOf("aabaabaa", "ab") = 1
* StringUtil.indexOf("aabaabaa", "") = 0
* </pre>
*
* @param str 검색 문자열
* @param searchStr 검색 대상문자열
* @return 검색 문자열 검색 대상문자열이 있는 시작 위치 검색대상 문자열이 없거나 null인 경우 -1
*/
public static int indexOf(String str, String searchStr) {
if (str == null || searchStr == null) {
return -1;
}
return str.indexOf(searchStr);
}
/**
* <p>오라클의 decode 함수와 동일한 기능을 가진 메서드이다.
* <code>sourStr</code> <code>compareStr</code> 값이 같으면
* <code>returStr</code> 반환하며, 다르면 <code>defaultStr</code> 반환한다.
* </p>
*
* <pre>
* StringUtil.decode(null, null, "foo", "bar")= "foo"
* StringUtil.decode("", null, "foo", "bar") = "bar"
* StringUtil.decode(null, "", "foo", "bar") = "bar"
* StringUtil.decode("하이", "하이", null, "bar") = null
* StringUtil.decode("하이", "하이 ", "foo", null) = null
* StringUtil.decode("하이", "하이", "foo", "bar") = "foo"
* StringUtil.decode("하이", "하이 ", "foo", "bar") = "bar"
* </pre>
*
* @param sourceStr 비교할 문자열
* @param compareStr 비교 대상 문자열
* @param returnStr sourceStr와 compareStr의 값이 같을 반환할 문자열
* @param defaultStr sourceStr와 compareStr의 값이 다를 반환할 문자열
* @return sourceStr과 compareStr의 값이 동일(equal) returnStr을 반환하며,
* <br/>다르면 defaultStr을 반환한다.
*/
public static String decode(String sourceStr, String compareStr, String returnStr, String defaultStr) {
if (sourceStr == null && compareStr == null) {
return returnStr;
}
if (sourceStr == null && compareStr != null) {
return defaultStr;
}
if (sourceStr.trim().equals(compareStr)) {
return returnStr;
}
return defaultStr;
}
/**
* <p>오라클의 decode 함수와 동일한 기능을 가진 메서드이다.
* <code>sourStr</code> <code>compareStr</code> 값이 같으면
* <code>returStr</code> 반환하며, 다르면 <code>sourceStr</code> 반환한다.
* </p>
*
* <pre>
* StringUtil.decode(null, null, "foo") = "foo"
* StringUtil.decode("", null, "foo") = ""
* StringUtil.decode(null, "", "foo") = null
* StringUtil.decode("하이", "하이", "foo") = "foo"
* StringUtil.decode("하이", "하이 ", "foo") = "하이"
* StringUtil.decode("하이", "바이", "foo") = "하이"
* </pre>
*
* @param sourceStr 비교할 문자열
* @param compareStr 비교 대상 문자열
* @param returnStr sourceStr와 compareStr의 값이 같을 반환할 문자열
* @return sourceStr과 compareStr의 값이 동일(equal) returnStr을 반환하며,
* <br/>다르면 sourceStr을 반환한다.
*/
public static String decode(String sourceStr, String compareStr, String returnStr) {
return decode(sourceStr, compareStr, returnStr, sourceStr);
}
/**
* 객체가 null인지 확인하고 null인 경우 "" 바꾸는 메서드
* @param object 원본 객체
* @return resultVal 문자열
*/
public static String isNullToString(Object object) {
String string = "";
if (object != null) {
string = object.toString().trim();
}
return string;
}
/**
*<pre>
* 인자로 받은 String이 null일 경우 &quot;&quot; 리턴한다.
* &#064;param src null값일 가능성이 있는 String .
* &#064;return 만약 String이 null 값일 경우 &quot;&quot; 바꾼 String .
*</pre>
*/
public static String nullConvert(Object src) {
//if (src != null && src.getClass().getName().equals("java.math.BigDecimal")) {
if (src != null && src instanceof java.math.BigDecimal) {
return ((BigDecimal) src).toString();
}
if (src == null || src.equals("null")) {
return "";
} else {
return ((String) src).trim();
}
}
/**
*<pre>
* 인자로 받은 String이 null일 경우 &quot;&quot; 리턴한다.
* &#064;param src null값일 가능성이 있는 String .
* &#064;return 만약 String이 null 값일 경우 &quot;&quot; 바꾼 String .
*</pre>
*/
public static String nullConvertInt(Object src) {
//if (src != null && src.getClass().getName().equals("java.math.BigDecimal")) {
if (src != null && src instanceof java.math.BigDecimal) {
return ((BigDecimal) src).toString();
}
if (src == null || src.equals("null")) {
return "0";
} else {
return ((String) src).trim();
}
}
/**
*<pre>
* 인자로 받은 String이 null일 경우 &quot;&quot; 리턴한다.
* &#064;param src null값일 가능성이 있는 String .
* &#064;return 만약 String이 null 값일 경우 &quot;&quot; 바꾼 String .
*</pre>
*/
public static String nullConvert(String src) {
if (src == null || src.equals("null") || "".equals(src) || " ".equals(src)) {
return "";
} else {
return src.trim();
}
}
/**
*<pre>
* 인자로 받은 String이 null일 경우 &quot;0&quot; 리턴한다.
* &#064;param src null값일 가능성이 있는 String .
* &#064;return 만약 String이 null 값일 경우 &quot;0&quot; 바꾼 String .
*</pre>
*/
public static int zeroConvert(Object src) {
if (src == null || src.equals("null")) {
return 0;
} else {
return Integer.parseInt(((String) src).trim());
}
}
/**
*<pre>
* 인자로 받은 String이 null일 경우 &quot;&quot; 리턴한다.
* &#064;param src null값일 가능성이 있는 String .
* &#064;return 만약 String이 null 값일 경우 &quot;&quot; 바꾼 String .
*</pre>
*/
public static int zeroConvert(String src) {
if (src == null || src.equals("null") || "".equals(src) || " ".equals(src)) {
return 0;
} else {
return Integer.parseInt(src.trim());
}
}
/**
* <p>문자열에서 {@link Character#isWhitespace(char)} 정의된
* 모든 공백문자를 제거한다.</p>
*
* <pre>
* StringUtil.removeWhitespace(null) = null
* StringUtil.removeWhitespace("") = ""
* StringUtil.removeWhitespace("abc") = "abc"
* StringUtil.removeWhitespace(" ab c ") = "abc"
* </pre>
*
* @param str 공백문자가 제거도어야 문자열
* @return the 공백문자가 제거된 문자열, null이 입력되면 <code>null</code> 리턴
*/
public static String removeWhitespace(String str) {
if (isEmpty(str)) {
return str;
}
int sz = str.length();
char[] chs = new char[sz];
int count = 0;
for (int i = 0; i < sz; i++) {
if (!Character.isWhitespace(str.charAt(i))) {
chs[count++] = str.charAt(i);
}
}
if (count == sz) {
return str;
}
return new String(chs, 0, count);
}
/**
* Html 코드가 들어간 문서를 표시할때 태그에 손상없이 보이기 위한 메서드
*
* @param strString
* @return HTML 태그를 치환한 문자열
*/
public static String checkHtmlView(String strString) {
String strNew = "";
StringBuffer strTxt = new StringBuffer("");
char chrBuff;
int len = strString.length();
for (int i = 0; i < len; i++) {
chrBuff = (char) strString.charAt(i);
switch (chrBuff) {
case '<':
strTxt.append("&lt;");
break;
case '>':
strTxt.append("&gt;");
break;
case '"':
strTxt.append("&quot;");
break;
case 10:
strTxt.append("<br>");
break;
case ' ':
strTxt.append("&nbsp;");
break;
//case '&' :
//strTxt.append("&amp;");
//break;
default:
strTxt.append(chrBuff);
}
}
strNew = strTxt.toString();
return strNew;
}
/**
* 문자열을 지정한 분리자에 의해 배열로 리턴하는 메서드.
* @param source 원본 문자열
* @param separator 분리자
* @return result 분리자로 나뉘어진 문자열 배열
*/
public static String[] split(String source, String separator) throws NullPointerException {
String[] returnVal = null;
int cnt = 1;
int index = source.indexOf(separator);
int index0 = 0;
while (index >= 0) {
cnt++;
index = source.indexOf(separator, index + 1);
}
returnVal = new String[cnt];
cnt = 0;
index = source.indexOf(separator);
while (index >= 0) {
returnVal[cnt] = source.substring(index0, index);
index0 = index + 1;
index = source.indexOf(separator, index + 1);
cnt++;
}
returnVal[cnt] = source.substring(index0);
return returnVal;
}
/**
* <p>{@link String#toLowerCase()} 이용하여 소문자로 변환한다.</p>
*
* <pre>
* StringUtil.lowerCase(null) = null
* StringUtil.lowerCase("") = ""
* StringUtil.lowerCase("aBc") = "abc"
* </pre>
*
* @param str 소문자로 변환되어야 문자열
* @return 소문자로 변환된 문자열, null이 입력되면 <code>null</code> 리턴
*/
public static String lowerCase(String str) {
if (str == null) {
return null;
}
return str.toLowerCase();
}
/**
* <p>{@link String#toUpperCase()} 이용하여 대문자로 변환한다.</p>
*
* <pre>
* StringUtil.upperCase(null) = null
* StringUtil.upperCase("") = ""
* StringUtil.upperCase("aBc") = "ABC"
* </pre>
*
* @param str 대문자로 변환되어야 문자열
* @return 대문자로 변환된 문자열, null이 입력되면 <code>null</code> 리턴
*/
public static String upperCase(String str) {
if (str == null) {
return null;
}
return str.toUpperCase();
}
/**
* <p>입력된 String의 앞쪽에서 두번째 인자로 전달된 문자(stripChars) 모두 제거한다.</p>
*
* <pre>
* StringUtil.stripStart(null, *) = null
* StringUtil.stripStart("", *) = ""
* StringUtil.stripStart("abc", "") = "abc"
* StringUtil.stripStart("abc", null) = "abc"
* StringUtil.stripStart(" abc", null) = "abc"
* StringUtil.stripStart("abc ", null) = "abc "
* StringUtil.stripStart(" abc ", null) = "abc "
* StringUtil.stripStart("yxabc ", "xyz") = "abc "
* </pre>
*
* @param str 지정된 문자가 제거되어야 문자열
* @param stripChars 제거대상 문자열
* @return 지정된 문자가 제거된 문자열, null이 입력되면 <code>null</code> 리턴
*/
public static String stripStart(String str, String stripChars) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return str;
}
int start = 0;
if (stripChars == null) {
while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {
start++;
}
} else if (stripChars.length() == 0) {
return str;
} else {
while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) {
start++;
}
}
return str.substring(start);
}
/**
* <p>입력된 String의 뒤쪽에서 두번째 인자로 전달된 문자(stripChars) 모두 제거한다.</p>
*
* <pre>
* StringUtil.stripEnd(null, *) = null
* StringUtil.stripEnd("", *) = ""
* StringUtil.stripEnd("abc", "") = "abc"
* StringUtil.stripEnd("abc", null) = "abc"
* StringUtil.stripEnd(" abc", null) = " abc"
* StringUtil.stripEnd("abc ", null) = "abc"
* StringUtil.stripEnd(" abc ", null) = " abc"
* StringUtil.stripEnd(" abcyx", "xyz") = " abc"
* </pre>
*
* @param str 지정된 문자가 제거되어야 문자열
* @param stripChars 제거대상 문자열
* @return 지정된 문자가 제거된 문자열, null이 입력되면 <code>null</code> 리턴
*/
public static String stripEnd(String str, String stripChars) {
int end;
if (str == null || (end = str.length()) == 0) {
return str;
}
if (stripChars == null) {
while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
end--;
}
} else if (stripChars.length() == 0) {
return str;
} else {
while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
end--;
}
}
return str.substring(0, end);
}
/**
* <p>입력된 String의 , 뒤에서 두번째 인자로 전달된 문자(stripChars) 모두 제거한다.</p>
*
* <pre>
* StringUtil.strip(null, *) = null
* StringUtil.strip("", *) = ""
* StringUtil.strip("abc", null) = "abc"
* StringUtil.strip(" abc", null) = "abc"
* StringUtil.strip("abc ", null) = "abc"
* StringUtil.strip(" abc ", null) = "abc"
* StringUtil.strip(" abcyx", "xyz") = " abc"
* </pre>
*
* @param str 지정된 문자가 제거되어야 문자열
* @param stripChars 제거대상 문자열
* @return 지정된 문자가 제거된 문자열, null이 입력되면 <code>null</code> 리턴
*/
public static String strip(String str, String stripChars) {
if (isEmpty(str)) {
return str;
}
String srcStr = str;
srcStr = stripStart(srcStr, stripChars);
return stripEnd(srcStr, stripChars);
}
/**
* 문자열을 지정한 분리자에 의해 지정된 길이의 배열로 리턴하는 메서드.
* @param source 원본 문자열
* @param separator 분리자
* @param arraylength 배열 길이
* @return 분리자로 나뉘어진 문자열 배열
*/
public static String[] split(String source, String separator, int arraylength) throws NullPointerException {
String[] returnVal = new String[arraylength];
int cnt = 0;
int index0 = 0;
int index = source.indexOf(separator);
while (index >= 0 && cnt < (arraylength - 1)) {
returnVal[cnt] = source.substring(index0, index);
index0 = index + 1;
index = source.indexOf(separator, index + 1);
cnt++;
}
returnVal[cnt] = source.substring(index0);
if (cnt < (arraylength - 1)) {
for (int i = cnt + 1; i < arraylength; i++) {
returnVal[i] = "";
}
}
return returnVal;
}
/**
* 문자열 A에서 Z사이의 랜덤 문자열을 구하는 기능을 제공 시작문자열과 종료문자열 사이의 랜덤 문자열을 구하는 기능
*
* @param startChr - 문자
* @param endChr - 마지막문자
* @return 랜덤문자
* @exception MyException
* @see
*/
public static String getRandomStr(char startChr, char endChr) {
int randomInt;
String randomStr = null;
// 시작문자 종료문자를 아스키숫자로 변환한다.
int startInt = Integer.valueOf(startChr);
int endInt = Integer.valueOf(endChr);
// 시작문자열이 종료문자열보가 클경우
if (startInt > endInt) {
throw new IllegalArgumentException("Start String: " + startChr + " End String: " + endChr);
}
// 랜덤 객체 생성
SecureRandom rnd = new SecureRandom();
do {
// 시작문자 종료문자 중에서 랜덤 숫자를 발생시킨다.
randomInt = rnd.nextInt(endInt + 1);
} while (randomInt < startInt); // 입력받은 문자 'A'(65)보다 작으면 다시 랜덤 숫자 발생.
// 랜덤 숫자를 문자로 변환 스트링으로 다시 변환
randomStr = (char) randomInt + "";
// 랜덤문자열를 리턴
return randomStr;
}
/**
* 문자열을 다양한 문자셋(EUC-KR[KSC5601],UTF-8..) 사용하여 인코딩하는 기능 역으로 디코딩하여 원래의 문자열을
* 복원하는 기능을 제공함 String temp = new String(문자열.getBytes("바꾸기전 인코딩"),"바꿀 인코딩");
* String temp = new String(문자열.getBytes("8859_1"),"KSC5601"); => UTF-8 에서
* EUC-KR
*
* @param srcString - 문자열
* @param srcCharsetNm - 원래 CharsetNm
* @param charsetNm - CharsetNm
* @return ()코딩 문자열
* @exception MyException
* @see
*/
public static String getEncdDcd(String srcString, String srcCharsetNm, String cnvrCharsetNm) {
String rtnStr = null;
if (srcString == null)
return null;
try {
rtnStr = new String(srcString.getBytes(srcCharsetNm), cnvrCharsetNm);
} catch (UnsupportedEncodingException e) {
rtnStr = null;
}
return rtnStr;
}
/**
* 특수문자를 브라우저에서 정상적으로 보이기 위해 특수문자를 처리('<' -> & lT)하는 기능이다
* @param srcString - '<'
* @return 변환문자열('<' -> "&lt"
* @exception MyException
* @see
*/
public static String getSpclStrCnvr(String srcString) {
String rtnStr = null;
StringBuffer strTxt = new StringBuffer("");
char chrBuff;
int len = srcString.length();
for (int i = 0; i < len; i++) {
chrBuff = (char) srcString.charAt(i);
switch (chrBuff) {
case '<':
strTxt.append("&lt;");
break;
case '>':
strTxt.append("&gt;");
break;
case '&':
strTxt.append("&amp;");
break;
default:
strTxt.append(chrBuff);
}
}
rtnStr = strTxt.toString();
return rtnStr;
}
/**
* 응용어플리케이션에서 고유값을 사용하기 위해 시스템에서17자리의TIMESTAMP값을 구하는 기능
*
* @param
* @return Timestamp
* @exception MyException
* @see
*/
public static String getTimeStamp() {
String rtnStr = null;
// 문자열로 변환하기 위한 패턴 설정(년도-- :::(자정이후 ))
String pattern = "yyyyMMddhhmmssSSS";
SimpleDateFormat sdfCurrent = new SimpleDateFormat(pattern, Locale.KOREA);
Timestamp ts = new Timestamp(System.currentTimeMillis());
rtnStr = sdfCurrent.format(ts.getTime());
return rtnStr;
}
/**
* html의 특수문자를 표현하기 위해
*
* @param srcString
* @return String
* @exception Exception
* @see
*/
public static String getHtmlStrCnvr(String srcString) {
String tmpString = srcString;
tmpString = tmpString.replaceAll("&lt;", "<");
tmpString = tmpString.replaceAll("&gt;", ">");
tmpString = tmpString.replaceAll("&amp;", "&");
tmpString = tmpString.replaceAll("&nbsp;", " ");
tmpString = tmpString.replaceAll("&apos;", "\'");
tmpString = tmpString.replaceAll("&quot;", "\"");
return tmpString;
}
/**
* <p>날짜 형식의 문자열 내부에 마이너스 character(-) 추가한다.</p>
*
* <pre>
* StringUtil.addMinusChar("20100901") = "2010-09-01"
* </pre>
*
* @param date 입력받는 문자열
* @return " - " 추가된 입력문자열
*/
public static String addMinusChar(String date) {
if (date.length() == 8) {
return date.substring(0, 4).concat("-").concat(date.substring(4, 6)).concat("-").concat(date.substring(6, 8));
} else {
return "";
}
}
}

View File

@ -0,0 +1,288 @@
/**
* Class Name : EgovFileScrty.java
* Description : Base64인코딩/디코딩 방식을 이용한 데이터를 암호화/복호화하는 Business Interface class
* Modification Information
*
* 수정일 수정자 수정내용
* ------- -------- ---------------------------
* 2009.02.04 박지욱 최초 생성
*
* @author 공통 서비스 개발팀 박지욱
* @since 2009. 02. 04
* @version 1.0
* @see
*
* Copyright (C) 2009 by MOPAS All right reserved.
*/
package egovframework.com.utl.sim.service;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.security.MessageDigest;
import egovframework.com.cmm.util.EgovResourceCloseHelper;
import org.apache.commons.codec.binary.Base64;
public class EgovFileScrty {
// 파일구분자
static final char FILE_SEPARATOR = File.separatorChar;
static final int BUFFER_SIZE = 1024;
/**
* 파일을 암호화하는 기능
*
* @param String source 암호화할 파일
* @param String target 암호화된 파일
* @return boolean result 암호화여부 True/False
* @exception Exception
*/
public static boolean encryptFile(String source, String target) throws Exception {
// 암호화 여부
boolean result = false;
String sourceFile = source.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR);
String targetFile = target.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR);
File srcFile = new File(sourceFile);
BufferedInputStream input = null;
BufferedOutputStream output = null;
byte[] buffer = new byte[BUFFER_SIZE];
try {
if (srcFile.exists() && srcFile.isFile()) {
input = new BufferedInputStream(new FileInputStream(srcFile));
output = new BufferedOutputStream(new FileOutputStream(targetFile));
int length = 0;
while ((length = input.read(buffer)) >= 0) {
byte[] data = new byte[length];
System.arraycopy(buffer, 0, data, 0, length);
output.write(encodeBinary(data).getBytes());
output.write(System.getProperty("line.separator").getBytes());
}
result = true;
}
} finally {
EgovResourceCloseHelper.close(input, output);
}
return result;
}
/**
* 파일을 복호화하는 기능
*
* @param String source 복호화할 파일
* @param String target 복호화된 파일
* @return boolean result 복호화여부 True/False
* @exception Exception
*/
public static boolean decryptFile(String source, String target) throws Exception {
// 복호화 여부
boolean result = false;
String sourceFile = source.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR);
String targetFile = target.replace('\\', FILE_SEPARATOR).replace('/', FILE_SEPARATOR);
File srcFile = new File(sourceFile);
BufferedReader input = null;
BufferedOutputStream output = null;
//byte[] buffer = new byte[BUFFER_SIZE];
String line = null;
try {
if (srcFile.exists() && srcFile.isFile()) {
input = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile)));
output = new BufferedOutputStream(new FileOutputStream(targetFile));
while ((line = input.readLine()) != null) {
byte[] data = line.getBytes();
output.write(decodeBinary(new String(data)));
}
result = true;
}
} finally {
EgovResourceCloseHelper.close(input, output);
}
return result;
}
/**
* 데이터를 암호화하는 기능
*
* @param byte[] data 암호화할 데이터
* @return String result 암호화된 데이터
* @exception Exception
*/
public static String encodeBinary(byte[] data) throws Exception {
if (data == null) {
return "";
}
return new String(Base64.encodeBase64(data));
}
/**
* 데이터를 암호화하는 기능
*
* @param String data 암호화할 데이터
* @return String result 암호화된 데이터
* @exception Exception
*/
@Deprecated
public static String encode(String data) throws Exception {
return encodeBinary(data.getBytes());
}
/**
* 데이터를 복호화하는 기능
*
* @param String data 복호화할 데이터
* @return String result 복호화된 데이터
* @exception Exception
*/
public static byte[] decodeBinary(String data) throws Exception {
return Base64.decodeBase64(data.getBytes());
}
/**
* 데이터를 복호화하는 기능
*
* @param String data 복호화할 데이터
* @return String result 복호화된 데이터
* @exception Exception
*/
@Deprecated
public static String decode(String data) throws Exception {
return new String(decodeBinary(data));
}
/**
* 비밀번호를 암호화하는 기능(복호화가 되면 안되므로 SHA-256 인코딩 방식 적용).
*
* deprecated : 보안 강화를 위하여 salt로 ID를 지정하는 encryptPassword(password, id) 사용
*
* @param String data 암호화할 비밀번호
* @return String result 암호화된 비밀번호
* @exception Exception
*/
@Deprecated
public static String encryptPassword(String data) throws Exception {
if (data == null) {
return "";
}
byte[] plainText = null; // 평문
byte[] hashValue = null; // 해쉬값
plainText = data.getBytes();
MessageDigest md = MessageDigest.getInstance("SHA-256");
// 변경 기존 hash 값에 검증 불가.. => deprecated 시키고 유지
/*
// Random 방식의 salt 추가
SecureRandom ng = new SecureRandom();
byte[] randomBytes = new byte[16];
ng.nextBytes(randomBytes);
md.reset();
md.update(randomBytes);
*/
hashValue = md.digest(plainText);
/*
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(hashValue);
*/
return new String(Base64.encodeBase64(hashValue));
}
/**
* 비밀번호를 암호화하는 기능(복호화가 되면 안되므로 SHA-256 인코딩 방식 적용)
*
* @param password 암호화될 패스워드
* @param id salt로 사용될 사용자 ID 지정
* @return
* @throws Exception
*/
public static String encryptPassword(String password, String id) throws Exception {
if (password == null) return "";
if (id == null) return ""; // KISA 보안약점 조치 (2018-12-11, 신용호)
byte[] hashValue = null; // 해쉬값
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.reset();
md.update(id.getBytes());
hashValue = md.digest(password.getBytes());
return new String(Base64.encodeBase64(hashValue));
}
/**
* 비밀번호를 암호화하는 기능(복호화가 되면 안되므로 SHA-256 인코딩 방식 적용)
* @param data 암호화할 비밀번호
* @param salt Salt
* @return 암호화된 비밀번호
* @throws Exception
*/
public static String encryptPassword(String data, byte[] salt) throws Exception {
if (data == null) {
return "";
}
byte[] hashValue = null; // 해쉬값
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.reset();
md.update(salt);
hashValue = md.digest(data.getBytes());
return new String(Base64.encodeBase64(hashValue));
}
/**
* 비밀번호를 암호화된 패스워드 검증(salt가 사용된 경우만 적용).
*
* @param data 패스워드
* @param encoded 해쉬처리된 패스워드(Base64 인코딩)
* @return
* @throws Exception
*/
public static boolean checkPassword(String data, String encoded, byte[] salt) throws Exception {
byte[] hashValue = null; // 해쉬값
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.reset();
md.update(salt);
hashValue = md.digest(data.getBytes());
return MessageDigest.isEqual(hashValue, Base64.decodeBase64(encoded.getBytes()));
}
}

View File

@ -0,0 +1,395 @@
package nlib.bbs.service;
import java.util.List;
import org.apache.commons.lang.StringEscapeUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;
import nlib.cmm.service.PagingVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : ArticleVO.java
*
* @Description : 게시물 공통 VO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 13.
* @version 1.0
*
*/
public class ArticleVO extends PagingVO {
private String articleId; /* 게시글ID */
private String mngOrgCd; /* 관리문화원코드 */
private String mngOrgNm; /* 관리문화원명 */
@JsonIgnore
private String bdType; /* 게시판유형 */
@JsonIgnore
private String bdTypeName; /* 게시판유형명 */
private String title; /* 제목 */
private String content; /* 내용 */
// 공지사항관련
private String notiYn; /* 공지여부 */
private String openYn; /* 공개여부 */
@JsonIgnore
private String postStartDate; /* 게시시작일자 */
@JsonIgnore
private String postEndDate; /* 게시종료일자 */
// FAQ, QNA관련
private String answer; /* 답변 */
private String answerYn; /* 답변여부 */
@JsonIgnore
private String useYn; /* 사용여부 */
private String questionType; /* 질문유형 */
private String questionTypeName; /* 질문유형명 */
private String secretYn; /* 비밀글여부 */
private String emailRecvYn; /* 답변이미엘수신여부 */
private String email; /* 이메일 */
private int viewCnt; /* 조회수 */
private String bdAttachFileId; /* 첨부파일아이디 */
private String attachYn; /* 첨부파일존재여부 */
private List<AttachFileVO> attachFiles; /* 첨부파일목록 */
private List<AttachFileVO> removedAttachFiles; /* 삭제첨부파일목록 */
@JsonIgnore
private String regId; /* 등록자아이디 */
private String regNm; /* 등록자명 */
private String regDd; /* 등록일자 */
@JsonIgnore
private String modId; /* 등록자아이디 */
private String modDd; /* 등록일자 */
private int rno; /* 글번호 */
@JsonIgnore
private String loginedMbInfoId; /* 로그인 사용자 ID */
private String loginedName; /* 로그인 사용자명 */
private String myQnaYn; /* 내가한 질문인지 여부 */
// 검색관련
private String searchType; /* 검색대상구분 */
private String searchKeyword; /* 검색어 */
private String searchQuestionType; /* 검색FAQ유형 */
@JsonIgnore
private String searchMbInfoId; /* 로그인한 사용자ID */
// 처리결과 관련
private String resultMessage = null; /* 처리결과메시지 */
private String resultCode = null; /* 처리결과코드 */
public int getAttachFileCnt() {
if(attachFiles == null) return 0;
return attachFiles.size();
}
public String getSanitizedContent() {
return StringUtil.sanitizeHtml(content);
}
// SETTER & GETTER
public String getArticleId() {
return articleId;
}
public void setArticleId(String articleId) {
// 쿼리 조건으로 사용되는 항목에 대하여 SQL 인젝션으로 처리될만한 문자 강체 치환 처리
this.articleId = StringUtil.getValidCodeString(articleId);
}
public String getMngOrgCd() {
return mngOrgCd;
}
public void setMngOrgCd(String mngOrgCd) {
// 쿼리 조건으로 사용되는 항목에 대하여 SQL 인젝션으로 처리될만한 문자 강체 치환 처리
this.mngOrgCd = StringUtil.getValidCodeString(mngOrgCd);
}
public String getBdType() {
return bdType;
}
public void setBdType(String bdType) {
this.bdType = bdType;
}
public String getUnescapeTitle() {
return StringEscapeUtils.unescapeHtml(title);
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
/*
* 통합자료관관리시스템과 동일하게 게시글 저장 처리를 수행하며,
* 제목의 경우, DB에 일부 특수문자에 대하여 치환되어 저장되고,
* 내용의 경우, HTML 요청된 그대로 저장하되 표출할 HTML Sanitizing하여 표출토록 처리하기로 협의됨에 따라
* 제목 설정시 치환되어 저장토록 (2021.12.21, 이규모차장님)
*/
this.title = StringUtil.getRemovedQuotesStr(title);
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getNotiYn() {
return notiYn;
}
public void setNotiYn(String notiYn) {
this.notiYn = notiYn;
}
public String getOpenYn() {
return openYn;
}
public void setOpenYn(String openYn) {
this.openYn = openYn;
}
public String getPostStartDate() {
return postStartDate;
}
public void setPostStartDate(String postStartDate) {
this.postStartDate = postStartDate;
}
public String getPostEndDate() {
return postEndDate;
}
public void setPostEndDate(String postEndDate) {
this.postEndDate = postEndDate;
}
public int getViewCnt() {
return viewCnt;
}
public void setViewCnt(int viewCnt) {
this.viewCnt = viewCnt;
}
public String getBdAttachFileId() {
return bdAttachFileId;
}
public void setBdAttachFileId(String bdAttachFileId) {
this.bdAttachFileId = bdAttachFileId;
}
public String getRegId() {
return regId;
}
public void setRegId(String regId) {
this.regId = regId;
}
public String getRegDd() {
return regDd;
}
public void setRegDd(String regDd) {
this.regDd = regDd;
}
public String getModId() {
return modId;
}
public void setModId(String modId) {
this.modId = modId;
}
public String getModDd() {
return modDd;
}
public void setModDd(String modDd) {
this.modDd = modDd;
}
public String getRegNm() {
return regNm;
}
public String getRegNmSec() {
if(StringUtil.isEmpty(regNm)) return null;
return StringUtil.maskName(regNm);
}
public void setRegNm(String regNm) {
this.regNm = regNm;
}
public int getRno() {
return rno;
}
public void setRno(int rno) {
this.rno = rno;
}
public String getSearchType() {
return searchType;
}
public void setSearchType(String searchType) {
this.searchType = searchType;
}
public String getSearchKeyword() {
return searchKeyword;
}
public String getEscapeSearchKeyword() {
return StringUtil.getSqlSearchKeyword(searchKeyword);
}
public void setSearchKeyword(String searchKeyword) {
this.searchKeyword = searchKeyword;
}
public String getAttachYn() {
return attachYn;
}
public void setAttachYn(String attachYn) {
this.attachYn = attachYn;
}
public String getMngOrgNm() {
return mngOrgNm;
}
public void setMngOrgNm(String mngOrgNm) {
this.mngOrgNm = mngOrgNm;
}
public String getBdTypeName() {
return bdTypeName;
}
public void setBdTypeName(String bdTypeName) {
this.bdTypeName = bdTypeName;
}
public List<AttachFileVO> getAttachFiles() {
return attachFiles;
}
public void setAttachFiles(List<AttachFileVO> attachFiles) {
if(attachFiles == null || attachFiles.size() < 1) this.attachFiles = null;
this.attachFiles = attachFiles;
}
public String getAnswerYn() {
return StringUtil.isEmpty(answerYn) ? "N" : answerYn;
}
public void setAnswerYn(String answerYn) {
this.answerYn = answerYn;
}
public String getUseYn() {
return useYn;
}
public void setUseYn(String useYn) {
this.useYn = useYn;
}
public String getQuestionType() {
return questionType;
}
public void setQuestionType(String questionType) {
this.questionType = questionType;
}
public String getQuestionTypeName() {
return questionTypeName;
}
public void setQuestionTypeName(String questionTypeName) {
this.questionTypeName = questionTypeName;
}
public String getAnswer() {
return answer;
}
public String getSanitizedAnswer() {
return StringUtil.sanitizeHtml(answer);
}
public void setAnswer(String answer) {
this.answer = answer;
}
public String getSearchQuestionType() {
return searchQuestionType;
}
public void setSearchQuestionType(String searchQuestionType) {
this.searchQuestionType = searchQuestionType;
}
public String getSearchMbInfoId() {
return searchMbInfoId;
}
public void setSearchMbInfoId(String searchMbInfoId) {
// 쿼리 조건으로 사용되는 항목에 대하여 SQL 인젝션으로 처리될만한 문자 강체 치환 처리
this.searchMbInfoId = StringUtil.getValidCodeString(searchMbInfoId);
}
public String getSecretYn() {
return secretYn;
}
public void setSecretYn(String secretYn) {
this.secretYn = secretYn;
}
public String getLoginedMbInfoId() {
return loginedMbInfoId;
}
public void setLoginedMbInfoId(String loginedMbInfoId) {
// 쿼리 조건으로 사용되는 항목에 대하여 SQL 인젝션으로 처리될만한 문자 강체 치환 처리
this.loginedMbInfoId = StringUtil.getValidCodeString(loginedMbInfoId);
}
public String getMyQnaYn() {
return StringUtil.isEmpty(myQnaYn) ? "N" : myQnaYn;
}
public void setMyQnaYn(String myQnaYn) {
this.myQnaYn = myQnaYn;
}
public String getLoginedName() {
return loginedName;
}
public void setLoginedName(String loginedName) {
this.loginedName = loginedName;
}
public String getEmailRecvYn() {
return StringUtil.isEmpty(emailRecvYn) ? "N" : emailRecvYn;
}
public void setEmailRecvYn(String emailRecvYn) {
this.emailRecvYn = emailRecvYn;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getResultMessage() {
return resultMessage;
}
public void setResultMessage(String resultMessage) {
this.resultMessage = resultMessage;
}
public String getResultCode() {
return resultCode;
}
public void setResultCode(String resultCode) {
this.resultCode = resultCode;
}
public List<AttachFileVO> getRemovedAttachFiles() {
return removedAttachFiles;
}
public void setRemovedAttachFiles(List<AttachFileVO> removedAttachFiles) {
this.removedAttachFiles = removedAttachFiles;
}
}

View File

@ -0,0 +1,109 @@
package nlib.bbs.service;
import java.util.List;
/**
* <pre>
* @Class Name : AttachFileService.java
*
* @Description : 첨부파일을 관리하는 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 16.
* @version 1.0
*
*/
public interface AttachFileService
{
/**
* 첨부파일 개수를 조회한다.
*
* @param attachFileId
* @return
* @throws Exception
*/
public int countAttachFiles(String attachFileId) throws Exception;
/**
* 첨부파일 목록을 조회한다.
*
* @param attachFileId
* @return
* @throws Exception
*/
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception;
/**
* 첨부파일그룹 등록한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public int insertAttachFileGroup(AttachFileVO attachFileVO) throws Exception;
/**
* 첨부파일 등록한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public int insertAttachFile(AttachFileVO attachFileVO) throws Exception;
/**
* 첨부파일그룹을 삭제한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public int deleteAttachFileGroup(String attachFileId) throws Exception;
/**
* 첨부파일 삭제한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public int deleteAttachFile(AttachFileVO attachFileVO) throws Exception;
/**
* 첨부파일 정보를 조회한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public AttachFileVO selectAttachFile(AttachFileVO attachFileVO) throws Exception;
/**
* 다운로드 가능 여부를 확인하다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public boolean checkAttachFileDownload(AttachFileVO attachFileVO) throws Exception;
}

View File

@ -0,0 +1,111 @@
package nlib.bbs.service;
/**
* <pre>
* @Class Name : AttachFileVO.java
*
* @Description : 첨부파일 정보 VO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 14. KNKIM 최초 생성
* @ 2021.11. 24. KNKIM DB컬럼명 수정에 따른 변경 처리 (FILE_STRE_COURS -> FILE_STRE_PATH, FILE_EXTSN -> FILE_EXT)
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 14.
* @version 1.0
*
*/
public class AttachFileVO {
private String bdType; /* 첨부된 게시판 유형 : ancmnt, faq, qna */
private String mbInfoId; /* 사용자ID (권한체크 등에 사용) */
private String subPathKey; /* 첨부파일서브경로 */
private String attachFileId; /* 첨부파일아이디 */
private int fileSn; /* 파일 순번 */
private String fileStrePath; /* 파일 저장결올 */
private String streFileNm; /* 저장파일명 */
private String orignlFileNm; /* 원본파일명 */
private String fileExt; /* 파일확장자 */
private int fileSize; /* 파일 사이즈 */
private String useAt; /* 사용영부 */
// GET/SET
public String getSubPathKey() {
return subPathKey;
}
public void setSubPathKey(String subPathKey) {
this.subPathKey = subPathKey;
}
public String getAttachFileId() {
return attachFileId;
}
public void setAttachFileId(String attachFileId) {
this.attachFileId = attachFileId;
}
public int getFileSn() {
return fileSn;
}
public void setFileSn(int fileSn) {
this.fileSn = fileSn;
}
public String getFileStrePath() {
return fileStrePath;
}
public void setFileStrePath(String fileStrePath) {
this.fileStrePath = fileStrePath;
}
public String getStreFileNm() {
return streFileNm;
}
public void setStreFileNm(String streFileNm) {
this.streFileNm = streFileNm;
}
public String getOrignlFileNm() {
return orignlFileNm;
}
public void setOrignlFileNm(String orignlFileNm) {
this.orignlFileNm = orignlFileNm;
}
public String getFileExt() {
return fileExt;
}
public void setFileExt(String fileExt) {
this.fileExt = (fileExt == null ? null : fileExt.toLowerCase());
}
public int getFileSize() {
return fileSize;
}
public void setFileSize(int fileSize) {
this.fileSize = fileSize;
}
public String getUseAt() {
return useAt;
}
public void setUseAt(String useAt) {
this.useAt = useAt;
}
public String getMbInfoId() {
return mbInfoId;
}
public void setMbInfoId(String mbInfoId) {
this.mbInfoId = mbInfoId;
}
public String getBdType() {
return bdType;
}
public void setBdType(String bdType) {
this.bdType = bdType;
}
}

View File

@ -0,0 +1,61 @@
package nlib.bbs.service;
import java.util.List;
/**
* <pre>
* @Class Name : BoardService.java
*
* @Description : 게시물 관련 공통 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 1. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 1.
* @version 1.0
*
*/
public interface BoardService
{
/**
* 게시글 목록을 조회한다.
*/
public List<ArticleVO> listArticles(ArticleVO ArticleVO) throws Exception;
/**
* 게시글 건수를 조회한다.
*/
public int countArticles(ArticleVO articleVO) throws Exception;
/**
* 조회수를 증가시킨다.
*
* @param
* @return
* @throws Exception
*/
public int updateRead(ArticleVO articleVO) throws Exception;
/**
* 게시글 상세 내용을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public ArticleVO selectArticle(ArticleVO articleVO) throws Exception;
}

View File

@ -0,0 +1,91 @@
package nlib.bbs.service;
/**
* <pre>
* @Class Name : QnaService.java
*
* @Description : 공통 게시물관리 서비스를 상속받아 Q&A 추가 기능을 명시한 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 29. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 29.
* @version 1.0
*
*/
public interface QnaService extends BoardService
{
/**
* 공통적인 게시판 목록, 조회관련한 맴버함수는 BoardService 에서 상속하고,
* QnaService에 추가된 멤버함순만 추가 정의 한다.
*
*/
/**
* 게시글을 등록한다.
*
* @param
* @return
* @throws Exception
*/
public ArticleVO insertArticle(ArticleVO articleVO) throws Exception;
/**
* 게시글을 수정한다.
*
* @param
* @return
* @throws Exception
*/
public int updateArticle(ArticleVO articleVO) throws Exception;
/**
* 게시글을 삭제한다.
*
* @param
* @return
* @throws Exception
*/
public int deleteArticle(ArticleVO articleVO) throws Exception;
/**
* 해당 QNA 글을 변경할 있는지 여부를 확인한다.
*
* @param articleVO
* @return
* @throws Exception
*/
public String canModify(ArticleVO articleVO) throws Exception;
/**
* 해당 QNA 글을 변경할 있는지 여부를 확인한다.
*
* @param articleVO
* @return
* @throws Exception
*/
public String canModify(ArticleVO articleVO, String mbInfoId) throws Exception;
/**
* 해당 QNA 글을 읽을 있는지 여부를 확인한다.
*
* @param articleVO
* @return
* @throws Exception
*/
public String canRead(ArticleVO articleVO) throws Exception;
}

View File

@ -0,0 +1,34 @@
package nlib.bbs.service.impl;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
/**
* <pre>
* @Class Name : AncmntDAO.java
*
* @Description : 공지사항 정보 제공 DAO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 13.
* @version 1.0
*
*/
@Mapper("ancmntDAO")
public interface AncmntDAO extends BoardDAO {
/*
* BoardDAO 상속 내용과 동일
*/
}

View File

@ -0,0 +1,43 @@
package nlib.bbs.service.impl;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* <pre>
* @Class Name : AncmntServiceImpl.java
*
* @Description : 공지사항 서비스 구현
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 13.
* @version 1.0
*
*/
@Service("ancmntService")
public class AncmntServiceImpl extends BoardServiceImpl
{
static Logger log = LoggerFactory.getLogger(AncmntServiceImpl.class);
@Resource(name="ancmntDAO")
AncmntDAO ancmntDAO;
@Override
public BoardDAO getBoardDAO() {
return ancmntDAO;
}
}

View File

@ -0,0 +1,115 @@
package nlib.bbs.service.impl;
import java.util.List;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
import nlib.bbs.service.AttachFileVO;
/**
* <pre>
* @Class Name : AttachFileDAO.java
*
* @Description : 게시판 첨부파일 관리 DAO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 16.
* @version 1.0
*
*/
@Mapper("attachFileDAO")
public interface AttachFileDAO {
/**
* 첨부파일 개수를 조회한다.
*
* @param attachFileId
* @return
* @throws Exception
*/
public int countAttachFiles(String attachFileId) throws Exception;
/**
* 첨부파일 목록을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception;
/**
* 첨부파일그룹을 등록한다.
*
* @param
* @return
* @throws Exception
*/
public int insertAttachFileGroup(AttachFileVO attachFileVO) throws Exception;
/**
* 첨부파일 등록한다.
*
* @param
* @return
* @throws Exception
*/
public int insertAttachFile(AttachFileVO attachFileVO) throws Exception;
/**
* 첨부파일그룹을 삭제한다.
*
* @param
* @return
* @throws Exception
*/
public int deleteAttachFileGroup(String attachFileId) throws Exception;
/**
* 첨부파일그룹에 속한 모든 파일을 삭제한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public int deleteAllFilesOfAttachFileGroup(String attachFileId) throws Exception;
/**
* 첨부파일 삭제한다.
*
* @param
* @return
* @throws Exception
*/
public int deleteAttachFile(AttachFileVO attachFileVO) throws Exception;
/**
* 첨부파일 정보를 조회한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public AttachFileVO selectAttachFile(AttachFileVO attachFileVO) throws Exception;
/**
* 다운로드 가능 여부를 확인하다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public String checkAttachFileDownload(AttachFileVO attachFileVO) throws Exception;
}

View File

@ -0,0 +1,158 @@
package nlib.bbs.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import nlib.bbs.service.AttachFileService;
import nlib.bbs.service.AttachFileVO;
import nlib.bbs.service.QnaService;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : AttachFileServiceImpl.java
*
* @Description : 첨부파일을 관리하는 서비스 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 16.
* @version 1.0
*
*/
@Service("attachFileService")
public class AttachFileServiceImpl implements AttachFileService
{
static Logger log = LoggerFactory.getLogger(AttachFileServiceImpl.class);
@Resource(name="attachFileDAO")
AttachFileDAO attachFileDAO;
@Resource(name = "qnaService")
private QnaService qnaService;
/**
* 첨부파일 개수를 조회한다.
*
* @param attachFileId
* @return
* @throws Exception
*/
public int countAttachFiles(String attachFileId) throws Exception {
return attachFileDAO.countAttachFiles(attachFileId);
}
/**
* 첨부파일 목록을 조회한다.
*
* @param
* @return
* @throws Exception
*/
@Override
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception {
return attachFileDAO.listAttachFiles(attachFileId);
}
/**
* 첨부파일그룹 등록한다.
*
* @param
* @return
* @throws Exception
*/
@Override
public int insertAttachFileGroup(AttachFileVO attachFileVO) throws Exception {
return attachFileDAO.insertAttachFileGroup(attachFileVO);
}
/**
* 첨부파일 등록한다.
*
* @param
* @return
* @throws Exception
*/
@Override
public int insertAttachFile(AttachFileVO attachFileVO) throws Exception {
return attachFileDAO.insertAttachFile(attachFileVO);
}
/**
* 첨부파일그룹을 삭제한다.
*
* @param
* @return
* @throws Exception
*/
@Override
public int deleteAttachFileGroup(String attachFileId) throws Exception {
int ret = attachFileDAO.deleteAttachFileGroup(attachFileId);
attachFileDAO.deleteAllFilesOfAttachFileGroup(attachFileId);
return ret;
}
/**
* 첨부파일 삭제한다.
*
* @param
* @return
* @throws Exception
*/
@Override
public int deleteAttachFile(AttachFileVO attachFileVO) throws Exception {
return attachFileDAO.deleteAttachFile(attachFileVO);
}
/**
* 첨부파일 정보를 조회한다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public AttachFileVO selectAttachFile(AttachFileVO attachFileVO) throws Exception {
if(attachFileVO == null) return null;
if(StringUtil.isEmpty(attachFileVO.getAttachFileId())) return null;
if(attachFileVO.getFileSn() < 0) return null;
return attachFileDAO.selectAttachFile(attachFileVO);
}
/**
* 다운로드 가능 여부를 확인하다.
*
* @param attachFileVO
* @return
* @throws Exception
*/
public boolean checkAttachFileDownload(AttachFileVO attachFileVO) throws Exception {
String bdType = attachFileVO.getBdType();
if(StringUtil.isEmpty(bdType)) return false;
String ret = "Y";
ret = attachFileDAO.checkAttachFileDownload(attachFileVO);
return StringUtil.isEmpty(ret) ? false : (ret.charAt(0) == 'Y');
}
}

View File

@ -0,0 +1,59 @@
package nlib.bbs.service.impl;
import java.util.List;
import nlib.bbs.service.ArticleVO;
/**
* <pre>
* @Class Name : BoardDAO.java
*
* @Description : 공지사항 정보 제공 DAO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 13.
* @version 1.0
*
*/
public interface BoardDAO {
/*
* 게시글 목록을 조회한다.
*/
public abstract List<ArticleVO> listArticles(ArticleVO ArticleVO) throws Exception;
/**
* 게시글 건수를 조회한다.
*/
public abstract int countArticles(ArticleVO ArticleVO) throws Exception;
/**
* 조회수를 증가시킨다.
*
* @param
* @return
* @throws Exception
*/
public abstract int updateRead(ArticleVO notiVO) throws Exception;
/**
* 게시글 상세 내용을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public abstract ArticleVO selectArticle(ArticleVO notiVO) throws Exception;
}

View File

@ -0,0 +1,100 @@
package nlib.bbs.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.AttachFileService;
import nlib.bbs.service.AttachFileVO;
import nlib.bbs.service.BoardService;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : BoardServiceImpl.java
*
* @Description : 게시판 서비스 추상 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 01. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 01.
* @version 1.0
*
*/
public abstract class BoardServiceImpl implements BoardService
{
static Logger log = LoggerFactory.getLogger(BoardServiceImpl.class);
@Resource(name="attachFileService")
AttachFileService attachFileService;
public abstract BoardDAO getBoardDAO();
/*
* 게시글 목록을 조회한다.
*/
public List<ArticleVO> listArticles(ArticleVO articleVO) throws Exception {
return getBoardDAO().listArticles(articleVO);
}
/**
* 게시글 건수를 조회한다.
*/
public int countArticles(ArticleVO articleVO) throws Exception {
return getBoardDAO().countArticles(articleVO);
}
/**
* 조회수를 증가시킨다.
*
* @param
* @return
* @throws Exception
*/
public int updateRead(ArticleVO articleVO) throws Exception {
return getBoardDAO().updateRead(articleVO);
}
/**
* 게시글 상세 내용을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public ArticleVO selectArticle(ArticleVO articleVO) throws Exception {
if(StringUtil.isEmpty(articleVO.getArticleId())) return null;
// 게시글 조회
ArticleVO retVO = getBoardDAO().selectArticle(articleVO);
// 첨부파일 조회
if(StringUtil.isNotEmpty(retVO.getBdAttachFileId())) {
String attachFileId = retVO.getBdAttachFileId();
List<AttachFileVO> listFile = attachFileService.listAttachFiles(attachFileId);
retVO.setAttachFiles(listFile);
}
// 조회수 증가
updateRead(articleVO);
return retVO;
}
}

View File

@ -0,0 +1,34 @@
package nlib.bbs.service.impl;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
/**
* <pre>
* @Class Name : FaqDAO.java
*
* @Description : FAQ DAO 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 15. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 15.
* @version 1.0
*
*/
@Mapper("faqDAO")
public interface FaqDAO extends BoardDAO {
/*
* BoardDAO 상속 내용과 동일
*/
}

View File

@ -0,0 +1,44 @@
package nlib.bbs.service.impl;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* <pre>
* @Class Name : FaqServiceImpl.java
*
* @Description : FAQ 서비스 구현
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 15. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 15.
* @version 1.0
*
*/
@Service("faqService")
public class FaqServiceImpl extends BoardServiceImpl
{
static Logger log = LoggerFactory.getLogger(FaqServiceImpl.class);
@Resource(name="faqDAO")
FaqDAO faqDAO;
@Override
public BoardDAO getBoardDAO() {
return faqDAO;
}
}

View File

@ -0,0 +1,60 @@
package nlib.bbs.service.impl;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
import nlib.bbs.service.ArticleVO;
/**
* <pre>
* @Class Name : QnaDAO.java
*
* @Description : Q&A DAO 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 15. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 15.
* @version 1.0
*
*/
@Mapper("qnaDAO")
public interface QnaDAO extends BoardDAO {
/*
* BoardDAO 상속 내용과 동일
*/
/**
* Q&A 게시글을 등록한다.
*
* @param reqVO
* @return
*/
public int insertArticle(ArticleVO articleVO);
/**
* Q&A 게시글을 수정한다.
*
* @param reqVO
* @return
*/
public int updateArticle(ArticleVO articleVO);
/**
* Q&A 게시글을 삭제한다.
*
* @param reqVO
* @return
*/
public int deleteArticle(ArticleVO articleVO);
}

View File

@ -0,0 +1,270 @@
package nlib.bbs.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.AttachFileService;
import nlib.bbs.service.AttachFileVO;
import nlib.bbs.service.QnaService;
import nlib.cmm.service.NlibProperty;
import nlib.util.StringUtil;
import nlib.util.UUID;
/**
* <pre>
* @Class Name : QnaServiceImpl.java
*
* @Description : Q&A 서비스 구현
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 15. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 15.
* @version 1.0
*
*/
@Service("qnaService")
public class QnaServiceImpl extends BoardServiceImpl implements QnaService
{
static Logger log = LoggerFactory.getLogger(QnaServiceImpl.class);
@Resource(name="qnaDAO")
QnaDAO qnaDAO;
@Resource(name="attachFileService")
AttachFileService attachFileService;
@Override
public BoardDAO getBoardDAO() {
return qnaDAO;
}
/**
* Q&A 게시글을 등록한다.
*
* @param reqVO
* @return
*/
public ArticleVO insertArticle(ArticleVO articleVO) throws Exception {
articleVO.setArticleId(UUID.getNlibCommonID("NQ", 35));
int ret = qnaDAO.insertArticle(articleVO);
if(ret < 1) {
throw new Exception("등록에 실패하였습니다.");
}
articleVO.setResultCode("S001");
if(articleVO.getAttachFileCnt() > 0) {
addAttachFiles(articleVO);
}
articleVO.setResultMessage("정상적으로 등록되었습니다." + (StringUtil.isNotEmpty(articleVO.getResultMessage())? "\\\\n " + articleVO.getResultMessage() : ""));
return articleVO;
}
/**
* 첨부파일을 추가한다.
*
* @param articleVO
* @throws Exception
*/
public void addAttachFiles(ArticleVO articleVO) throws Exception {
int savedCnt = 0;
List<AttachFileVO> attachFileList = articleVO.getAttachFiles();
// 최대 개수
int maxFileCount = NlibProperty.getInt("fileupload.max.files", 5);
// 첨부파일그룹 등록
int groupCnt = attachFileService.insertAttachFileGroup(attachFileList.get(0));
if(groupCnt > 0) {
int curFileCount = attachFileService.countAttachFiles(articleVO.getBdAttachFileId());
int addingCount = maxFileCount - curFileCount;
// 첨부파일 등록
if(addingCount > 0) {
for(int i=0; i<attachFileList.size(); i++) {
if(savedCnt >= addingCount) {
String message = "최대 허용 개수가 도달하여 등록을 중단합니다.";
log.error(message);
articleVO.setResultMessage(message);
break;
}
AttachFileVO attachFileVO = attachFileList.get(i);
int retAttFile = attachFileService.insertAttachFile(attachFileVO);
savedCnt += retAttFile;
if(retAttFile < 1) {
log.error("insertArticle > 첨부파일 등록에 실패하였습니다 : " + attachFileVO.getOrignlFileNm());
}
}
}
if(savedCnt != articleVO.getAttachFileCnt()) {
articleVO.setResultMessage("" + articleVO.getAttachFileCnt() + "개 파일 중 " + savedCnt + "개 파일만 정상등록되었습니다.");
}
} else {
articleVO.setResultMessage("게시글은 등록되었으나, 첨부파일그룹 등록에 실패하여 첨부파일 등록처리가 수행되지 않았습니다.");
}
}
/**
* 첨부파일을 삭제한다.
*
* @param articleVO
* @throws Exception
*/
public void removeAttachFiles(ArticleVO articleVO) throws Exception {
int savedCnt = 0;
List<AttachFileVO> attachFileList = articleVO.getRemovedAttachFiles();
if(attachFileList == null || attachFileList.size() < 1) return;
String attachFileId = attachFileList.get(0).getAttachFileId();
if(StringUtil.isNotEmpty(attachFileId)) {
// 첨부파일 삭제
for(int i=0; i<attachFileList.size(); i++) {
AttachFileVO attachFileVO = attachFileList.get(i);
int retAttFile = attachFileService.deleteAttachFile(attachFileVO);
savedCnt += retAttFile;
if(retAttFile < 1) {
log.error("insertArticle > 첨부파일 삭제에 실패하였습니다 : " + attachFileVO.getOrignlFileNm());
}
}
if(savedCnt != attachFileList.size()) {
articleVO.setResultMessage(String.format("총 %d개 파일 중 %개 파일만 정상 삭제되었습니다.", attachFileList.size(), savedCnt));
}
} else {
articleVO.setResultMessage("첨부파일그룹ID 정보가 누락되어 첨부파일 삭제가 불가합니다.");
}
return;
}
/**
* Q&A 게시글을 수정한다.
*
* @param reqVO
* @return
*/
public int updateArticle(ArticleVO articleVO) throws Exception {
int updateRet = qnaDAO.updateArticle(articleVO);
// 첨부파일 삭제
List<AttachFileVO> removedAttachFiles = articleVO.getRemovedAttachFiles();
if(removedAttachFiles != null && removedAttachFiles.size() > 0) {
removeAttachFiles(articleVO);
}
// 첨부파일 추가
List<AttachFileVO> addedFiles = articleVO.getAttachFiles();
if(addedFiles != null && addedFiles.size() > 0) {
addAttachFiles(articleVO);
}
return updateRet;
}
/**
* Q&A 게시글을 삭제한다.
*
* @param reqVO
* @return
*/
public int deleteArticle(ArticleVO articleVO) throws Exception {
int ret = qnaDAO.deleteArticle(articleVO);
attachFileService.deleteAttachFileGroup(articleVO.getBdAttachFileId());
return ret;
}
/**
* 해당 QNA 글을 변경할 있는지 여부를 확인한다.
* (articleVO.getLoginedMbInfoId() 값을 확인하여 DB에 저장된 게시글을 조회하여 검사하므로 호출 설정 필요)
*
* @param articleVO
* @return
* @throws Exception
*/
public String canModify(ArticleVO articleVO) throws Exception {
if(StringUtil.isEmpty(articleVO.getLoginedMbInfoId())) {
return "로그인 후, 이용하실 수 있습니다.";
}
return canModify(selectArticle(articleVO), articleVO.getLoginedMbInfoId());
}
/**
* 해당 QNA 글을 변경할 있는지 여부를 확인한다.
*
* @param articleVO
* @return
* @throws Exception
*/
public String canModify(ArticleVO articleVO, String mbInfoId) throws Exception {
if(StringUtil.isEmpty(mbInfoId)) {
return "로그인 후, 이용하실 수 있습니다.";
}
if(articleVO == null) {
return "대상 게시글 정보가 없습니다.";
}
if(!"Y".equals(articleVO.getMyQnaYn())) {
return "본인의 글만 변경할 수 있습니다.";
}
if("Y".equals(articleVO.getAnswerYn())) {
return "이미 답변완료된 글은 변경할 수 없습니다.";
}
return null;
}
/**
* 해당 QNA 글을 읽을 있는지 여부를 확인한다.
*
* @param articleVO
* @return
* @throws Exception
*/
public String canRead(ArticleVO articleVO) throws Exception {
ArticleVO savedArticleVO = selectArticle(articleVO);
if("Y".equals(savedArticleVO.getMyQnaYn())) return null;
if("Y".equals(savedArticleVO.getSecretYn())) {
return "다른 사용자의 비밀글은 조회할 수 없습니다.";
}
return null;
}
}

View File

@ -0,0 +1,159 @@
package nlib.bbs.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.BoardService;
import nlib.cmm.NlibCommonController;
import nlib.cmm.service.NlibProperty;
import nlib.cmm.service.PagingVO;
/**
* <pre>
* @Class Name : AncmntController.java
*
* @Description : 공지사항 컨트롤러 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 13.
* @version 1.0
*
*/
@Controller
public class AncmntController extends NlibCommonController
{
private static final Logger log = LoggerFactory.getLogger(AncmntController.class);
static final int DEFUALT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10);
@Resource(name = "ancmntService")
private BoardService ancmntService;
final String[] DISALLOWED_FIELDS = new String[] {
"mngOrgCd",
"mngOrgNm",
"bdType",
"title",
"content",
"notiYn",
"bdAttachFileId",
"attachYn",
"resultMessage",
"resultCode"
};
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(DISALLOWED_FIELDS);
}
/**
* 목록 화면을 표시한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/listAncmnts.do")
public String listAncmnts(
HttpServletRequest req,
@RequestParam Map<String, String> paramMap,
ArticleVO searchArticleVO,
ModelMap model
) throws Exception {
model.addAttribute("searchArticle", searchArticleVO);
return "nlib/bbs/listAncmnts";
}
/**
* 목록 조회한다.
*
* @param request
* @return
*/
@RequestMapping(value="/bbs/listAncmntsAjax.do")
public ResponseEntity<String> listAncmntsAjax(
HttpServletRequest request,
Authentication authentication,
@RequestBody ArticleVO searchArticleVO) throws Exception {
if(searchArticleVO.getPageIndex() < 1) searchArticleVO.setPageIndex(1);
if(searchArticleVO.getPageSize() < 1) searchArticleVO.setPageSize(DEFUALT_PAGE_SIZE);
searchArticleVO.setMngOrgCd(getCurCouncilCd(request));
List<ArticleVO> list = ancmntService.listArticles(searchArticleVO);
int totRecordCount = ancmntService.countArticles(searchArticleVO);
//-------------------------------
// JSON변환 응답 처리
//-------------------------------
// JS-GRID 페이징 처리를 포함한 응답값 처리
// {data: [{...}],
// itemsCount: 255
// }
HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", list);
retMap.put("itemsCount", totRecordCount);
PagingVO pageVO = new PagingVO();
pageVO.setPagingVO(totRecordCount, searchArticleVO.getPageIndex(), searchArticleVO.getPageSize());
retMap.put("pagingPageIndex" , pageVO.getPageIndex());
retMap.put("pagingTotRecordCount", pageVO.getTotRecordCount());
retMap.put("pagingStartPage" , pageVO.getStartPage());
retMap.put("pagingEndPage" , pageVO.getEndPage());
retMap.put("pagingLastPage" , pageVO.getLastPage());
return makeResponseEntityJson(retMap);
}
/**
* 알림 상세 내용 조회한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/selectAncmntArticle.do")
public String selectAncmntArticle(HttpServletRequest req, Authentication authentication, ArticleVO searchArticleVO, ModelMap model) throws Exception {
// 읽음처리 상세내용 조회
ArticleVO articleVO = ancmntService.selectArticle(searchArticleVO);
model.addAttribute("searchArticle", searchArticleVO);
model.addAttribute("article", articleVO);
return "nlib/bbs/selectAncmntArticle";
}
}

View File

@ -0,0 +1,158 @@
package nlib.bbs.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.BoardService;
import nlib.cmm.NlibCommonController;
import nlib.cmm.service.CodeService;
import nlib.cmm.service.NlibProperty;
import nlib.cmm.service.PagingVO;
/**
* <pre>
* @Class Name : FaqController.java
*
* @Description : FAQ 컨트롤러 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 13.
* @version 1.0
*
*/
@Controller
public class FaqController extends NlibCommonController {
private static final Logger log = LoggerFactory.getLogger(FaqController.class);
static final int DEFUALT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10);
@Resource(name = "faqService")
private BoardService faqService;
@Resource(name="codeService")
private CodeService codeService;
/**
* 목록 화면을 표시한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/listFaqs.do")
public String listFaqs(
HttpServletRequest req,
@RequestParam Map<String, String> paramMap,
ArticleVO searchArticleVO,
ModelMap model
) throws Exception {
List<Map<String, String>> questionTypeList = codeService.listCodes("NLIB_FAQ_TYPE_CD");
model.addAttribute("questionTypeList", questionTypeList);
model.addAttribute("searchArticle", searchArticleVO);
return "nlib/bbs/listFaqs";
}
/**
* 목록 조회한다.
*
* @param req
* @return
*/
@RequestMapping(value="/bbs/listFaqsAjax.do")
public ResponseEntity<String> listFaqsAjax(
HttpServletRequest req,
Authentication authentication,
@RequestBody ArticleVO searchArticleVO) throws Exception {
if(searchArticleVO.getPageIndex() < 1) searchArticleVO.setPageIndex(1);
if(searchArticleVO.getPageSize() < 1) searchArticleVO.setPageSize(DEFUALT_PAGE_SIZE);
searchArticleVO.setMngOrgCd(getCurCouncilCd(req));
List<ArticleVO> list = faqService.listArticles(searchArticleVO);
int totRecordCount = faqService.countArticles(searchArticleVO);
//-------------------------------
// JSON변환 응답 처리
//-------------------------------
// JS-GRID 페이징 처리를 포함한 응답값 처리
// {data: [{...}],
// itemsCount: 255
// }
HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", list);
retMap.put("itemsCount", totRecordCount);
PagingVO pageVO = new PagingVO();
pageVO.setPagingVO(totRecordCount, searchArticleVO.getPageIndex(), searchArticleVO.getPageSize());
retMap.put("pagingPageIndex" , pageVO.getPageIndex());
retMap.put("pagingTotRecordCount", pageVO.getTotRecordCount());
retMap.put("pagingStartPage" , pageVO.getStartPage());
retMap.put("pagingEndPage" , pageVO.getEndPage());
retMap.put("pagingLastPage" , pageVO.getLastPage());
return makeResponseEntityJson(retMap);
}
/**
* 알림 상세 내용 조회한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/selectFaqArticleAjax.do")
public ResponseEntity<String> selectFaqArticleAjax(HttpServletRequest req, Authentication authentication, @RequestBody ArticleVO searchArticleVO) throws Exception {
// 읽음처리 상세내용 조회
ArticleVO articleVO = faqService.selectArticle(searchArticleVO);
// AJAX OUT에 XSS처리되지 않은 HTML 전송 차단위한 변경 처리
if(articleVO != null) {
articleVO.setAnswer(articleVO.getSanitizedAnswer());
articleVO.setContent(articleVO.getSanitizedContent());
}
//-------------------------------
// JSON변환 응답 처리
//-------------------------------
// JS-GRID 페이징 처리를 포함한 응답값 처리
// {data: [{...}],
// itemsCount: 255
// }
HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", articleVO);
return makeResponseEntityJson(retMap);
}
}

View File

@ -0,0 +1,602 @@
package nlib.bbs.web;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.AttachFileVO;
import nlib.bbs.service.QnaService;
import nlib.cmm.NlibCommonController;
import nlib.cmm.service.CodeService;
import nlib.cmm.service.NlibProperty;
import nlib.cmm.service.PagingVO;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
import nlib.util.UUID;
/**
* <pre>
* @Class Name : QnaController.java
*
* @Description : Q&A 컨트롤러 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 13.
* @version 1.0
*
*/
@Controller
public class QnaController extends NlibCommonController {
private static final Logger log = LoggerFactory.getLogger(QnaController.class);
static final int DEFUALT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10);
static final String BD_TYPE_QNA = "QNA";
@Resource(name = "qnaService")
private QnaService qnaService;
@Resource(name="codeService")
private CodeService codeService;
/**
* 전체 목록 화면을 표시한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/listQnas.do")
public String listQnas(
HttpServletRequest req,
@RequestParam Map<String, String> paramMap,
ArticleVO searchArticleVO,
ModelMap model
) throws Exception {
model.addAttribute("searchArticle", searchArticleVO);
return "nlib/bbs/listQnas";
}
/**
* 내질문 목록 화면을 표시한다. (권한 적용을 위해 분리함)
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping("/bbs/listMyQnas.do")
public String listMyQnas(
HttpServletRequest req,
@RequestParam Map<String, String> paramMap,
ArticleVO searchArticleVO,
ModelMap model
) throws Exception {
searchArticleVO.setSearchQuestionType("USER");
model.addAttribute("searchArticle", searchArticleVO);
return "nlib/bbs/listQnas";
}
/**
* 목록 조회한다.
*
* @param request
* @return
*/
@RequestMapping(value="/bbs/listQnasAjax.do")
public ResponseEntity<String> listQnasAjax(
HttpServletRequest request,
Authentication authentication,
@RequestBody ArticleVO searchArticleVO) throws Exception {
String message = null;
boolean needToQeury = true;
if(searchArticleVO.getPageIndex() < 1) searchArticleVO.setPageIndex(1);
if(searchArticleVO.getPageSize() < 1) searchArticleVO.setPageSize(DEFUALT_PAGE_SIZE);
searchArticleVO.setMngOrgCd(getCurCouncilCd(request));
String mbInfoId = getMbInfoId(request);
searchArticleVO.setLoginedMbInfoId(mbInfoId);
if(StringUtil.equalsIgnoreCase(searchArticleVO.getSearchQuestionType(), "USER")) {
searchArticleVO.setSearchMbInfoId(mbInfoId);
if(StringUtil.isEmpty(mbInfoId)) needToQeury = false;
} else {
searchArticleVO.setSearchMbInfoId(null);
}
List<ArticleVO> list = null;
int totRecordCount = 0;
if(needToQeury) {
list = qnaService.listArticles(searchArticleVO);
totRecordCount = qnaService.countArticles(searchArticleVO);
} else {
list = new ArrayList<ArticleVO>();
message = "로그인 후, 이용하여 주시기 바랍니다";
}
//-------------------------------
// JSON변환 응답 처리
//-------------------------------
// JS-GRID 페이징 처리를 포함한 응답값 처리
// {data: [{...}],
// itemsCount: 255
// }
HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", list);
retMap.put("itemsCount", totRecordCount);
retMap.put("message", message);
PagingVO pageVO = new PagingVO();
pageVO.setPagingVO(totRecordCount, searchArticleVO.getPageIndex(), searchArticleVO.getPageSize());
retMap.put("pagingPageIndex" , pageVO.getPageIndex());
retMap.put("pagingTotRecordCount", pageVO.getTotRecordCount());
retMap.put("pagingStartPage" , pageVO.getStartPage());
retMap.put("pagingEndPage" , pageVO.getEndPage());
retMap.put("pagingLastPage" , pageVO.getLastPage());
return makeResponseEntityJson(retMap);
}
/**
* 알림 상세 내용 조회한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/selectQnaArticle.do")
public String selectQnaArticle(HttpServletRequest request, Authentication authentication, ArticleVO searchArticleVO, ModelMap model) throws Exception {
// 읽음처리 상세내용 조회
searchArticleVO.setLoginedMbInfoId(getMbInfoId(request));
ArticleVO articleVO = null;
String canRead = qnaService.canRead(searchArticleVO);
if(canRead != null) {
model.addAttribute("message", canRead);
articleVO = searchArticleVO;
} else {
articleVO = qnaService.selectArticle(searchArticleVO);
}
model.addAttribute("searchArticle", searchArticleVO);
model.addAttribute("article", articleVO);
return "nlib/bbs/selectQnaArticle";
}
/**
* 묻고답하기 글작성화면을 표출한다.
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping({"/bbs/insertQnaForm.do", "/bbs/updateQnaForm.do"})
public String insertQnaForm(
HttpServletRequest request
, ArticleVO searchArticleVO
, RedirectAttributes redirectAttrs
, ModelMap model) throws Exception {
NlibLoginVO nlibLoginVO = getNlibLoginVO(request);
searchArticleVO.setLoginedMbInfoId(getMbInfoId(request));
Map rAttrs = redirectAttrs.getFlashAttributes();
ArticleVO redirectSearchArticleVO = (ArticleVO)rAttrs.get("searchArticle");
if(redirectSearchArticleVO != null && StringUtil.isNotEmpty(redirectSearchArticleVO.getTitle())) {
searchArticleVO = redirectSearchArticleVO;
} else {
ArticleVO articleVO = qnaService.selectArticle(searchArticleVO);
if(articleVO != null && !StringUtil.isEmpty(articleVO.getTitle())) {
articleVO.setSearchKeyword(searchArticleVO.getSearchKeyword());
articleVO.setPageIndex(searchArticleVO.getPageIndex());
articleVO.setPageSize(searchArticleVO.getPageSize());
searchArticleVO = articleVO;
}
}
searchArticleVO.setLoginedMbInfoId(nlibLoginVO.getMbInfoId());
searchArticleVO.setLoginedName(nlibLoginVO.getName());
searchArticleVO.setEmail(nlibLoginVO.getEmail());
model.addAttribute("searchArticle", searchArticleVO);
// 첨부파일 업로드 설정값
model.addAttribute("maxFilesize" , NlibProperty.getString("fileupload.max.mbsize"));
model.addAttribute("maxFiles" , NlibProperty.getString("fileupload.max.files"));
model.addAttribute("acceptedFiles", NlibProperty.getString("fileupload.acceptable.ext"));
return "nlib/bbs/insertQnaForm";
}
/**
* 묻고답하기 등록 처리한다.
*
* @param req
* @param authentication
* @param paramMap
* @param model
* @return
*/
@Secured("ROLE_USER")
@RequestMapping("/bbs/insertQnaArticle.do")
public String insertQna(HttpServletRequest request
, Authentication authentication
, ArticleVO articleVO
, String fileList
, RedirectAttributes redirectAttrs
, ModelMap model) throws Exception {
NlibLoginVO loginVO = getNlibLoginVO(authentication);
String message = null;
if(loginVO == null || StringUtil.isEmpty(loginVO.getMbInfoId())) {
message = "로그인하신 후, 이용하여 주시기 바랍니다.";
log.error("inserQna > " + message);
redirectAttrs.addFlashAttribute("searchArticle", articleVO);
redirectAttrs.addFlashAttribute("message", message);
redirectAttrs.addFlashAttribute("title", articleVO.getTitle());
return "redirect:/bbs/insertQnaForm.do";
}
//---------------------------
// 기본 정보 설정
//---------------------------
articleVO.setRegId(loginVO.getMbInfoId());
articleVO.setMngOrgCd(getCurCouncilCd(request)); // 문화원코드
articleVO.setBdType(BD_TYPE_QNA);
articleVO.setAnswerYn("N");
articleVO.setAnswer(null);
if(StringUtil.isEmpty(articleVO.getEmailRecvYn())) articleVO.setEmailRecvYn("N");
if(StringUtil.isEmpty(articleVO.getSecretYn())) articleVO.setSecretYn("N");
//---------------------------
// 첨부파일 정보 설정
//---------------------------
if(StringUtil.isNotEmpty(fileList)) {
String fileListJsonStr = fileList;
if(fileListJsonStr.startsWith("&")) fileListJsonStr = StringEscapeUtils.unescapeHtml(fileListJsonStr);
if(fileListJsonStr.startsWith("\"")) fileListJsonStr = fileListJsonStr.substring(1);
if(fileListJsonStr.endsWith("\"")) fileListJsonStr = fileListJsonStr.substring(0, fileListJsonStr.length()-1);
fileListJsonStr = fileListJsonStr.replaceAll("\\\\", "");
log.debug("fileListJsonStr : " + fileListJsonStr);
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> fileListObj = null;
try {
fileListObj = mapper.readValue(fileListJsonStr, new TypeReference<List<Map<String, Object>>>() {
});
} catch (JsonMappingException e) {
log.error("insertQna Json 변환 처리 오류 JsonMappingException : " + e.toString());
} catch (JsonProcessingException e) {
log.error("insertQna Json 변환 처리 오류 JsonProcessingException : " + e.toString());
}
if(fileListObj != null && fileListObj.size() > 0) {
String attachFileId = (String)(fileListObj.get(0).get("attachFileId"));
if(StringUtil.isEmpty(attachFileId)) {
attachFileId = UUID.getNewAttachFileId();
}
if(StringUtil.isNotEmpty(attachFileId)) {
articleVO.setBdAttachFileId(attachFileId);
String fileSStreCours = NlibProperty.getProperty("fileupload.base.path") + NlibProperty.getProperty("fileupload.bbs.qna.subpath") + "/";
List<AttachFileVO> attachFiles = new ArrayList<AttachFileVO>();
// 최대 개수
int maxFileCount = NlibProperty.getInt("fileupload.max.files", 5);
for(int i=0; i<maxFileCount && i<fileListObj.size(); i++) {
Map finfo = fileListObj.get(i);
AttachFileVO fVO = new AttachFileVO();
fVO.setAttachFileId(attachFileId);
fVO.setFileStrePath(fileSStreCours);
fVO.setStreFileNm((String)finfo.get("streFileNm"));
fVO.setOrignlFileNm((String)finfo.get("orignlFileNm"));
fVO.setFileExt((String)finfo.get("fileExt"));
fVO.setFileSize(((Integer)finfo.get("fileSize")).intValue());
File f = new File(fVO.getFileStrePath() + fVO.getStreFileNm());
if(!f.exists() || !f.isFile()) continue;
attachFiles.add(fVO);
}
articleVO.setAttachFiles(attachFiles);
}
}
}
//---------------------------
// 등록처리
//---------------------------
ArticleVO ret = qnaService.insertArticle(articleVO);
if(ret == null || ret.getResultCode() == null || !ret.getResultCode().startsWith("S")) {
// 등록 실패인 경우
message = (ret == null ? "처리에 실패하였습니다." : ret.getResultMessage());
redirectAttrs.addFlashAttribute("message", message);
redirectAttrs.addFlashAttribute("searchArticle", articleVO);
return "redirect:/board/insertQnAForm.do";
}
redirectAttrs.addFlashAttribute("message", "성공적으로 등록되었습니다.");
return "redirect:/bbs/listQnas.do";
}
/**
* 게시글을 수정한다.
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping("/bbs/updateQnaArticle.do")
public String updateQnaArticle(
HttpServletRequest request
, ArticleVO articleVO
, String fileList
, String delFileList
, RedirectAttributes redirectAttrs
, ModelMap model) throws Exception {
NlibLoginVO nlibLoginVO = getNlibLoginVO(request);
// 권한 변경 가능 상태 체크
articleVO.setLoginedMbInfoId(getMbInfoId(request));
ArticleVO articleOrg = qnaService.selectArticle(articleVO);
String message = qnaService.canModify(articleOrg, getMbInfoId(request));
if(message != null) {
redirectAttrs.addFlashAttribute("searchArticle", articleVO);
redirectAttrs.addFlashAttribute("message", message);
return "redirect:/bbs/listQnas.do";
}
articleVO.setModId(nlibLoginVO.getMbInfoId());
//---------------------------
// 첨부파일 정보 설정
//---------------------------
// 추가 첨부파일
if(StringUtil.isNotEmpty(fileList)) {
String fileListJsonStr = fileList;
if(fileListJsonStr.startsWith("&")) fileListJsonStr = StringEscapeUtils.unescapeHtml(fileListJsonStr);
if(fileListJsonStr.startsWith("\"")) fileListJsonStr = fileListJsonStr.substring(1);
if(fileListJsonStr.endsWith("\"")) fileListJsonStr = fileListJsonStr.substring(0, fileListJsonStr.length()-1);
fileListJsonStr = fileListJsonStr.replaceAll("\\\\", "");
log.debug("fileListJsonStr : " + fileListJsonStr);
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> fileListObj = null;
try {
fileListObj = mapper.readValue(fileListJsonStr, new TypeReference<List<Map<String, Object>>>() {
});
} catch (JsonMappingException e) {
log.error("updateQnaArticle Json 변환 처리 오류 JsonMappingException : " + e.toString());
} catch (JsonProcessingException e) {
log.error("updateQnaArticle Json 변환 처리 오류 JsonProcessingException : " + e.toString());
}
if(fileListObj != null && fileListObj.size() > 0) {
String attachFileId = articleOrg.getBdAttachFileId();
if(StringUtil.isEmpty(attachFileId)) {
attachFileId = UUID.getNewAttachFileId();
articleVO.setBdAttachFileId(attachFileId);
}
if(StringUtil.isNotEmpty(articleVO.getBdAttachFileId())) articleVO.setBdAttachFileId(attachFileId);
String fileSStreCours = NlibProperty.getProperty("fileupload.base.path") + NlibProperty.getProperty("fileupload.bbs.qna.subpath") + "/";
List<AttachFileVO> attachFiles = new ArrayList<AttachFileVO>();
for(int i=0; i<fileListObj.size(); i++) {
Map finfo = fileListObj.get(i);
AttachFileVO fVO = new AttachFileVO();
fVO.setAttachFileId(attachFileId);
fVO.setFileStrePath(fileSStreCours);
fVO.setStreFileNm((String)finfo.get("streFileNm"));
fVO.setOrignlFileNm((String)finfo.get("orignlFileNm"));
fVO.setFileExt((String)finfo.get("fileExt"));
fVO.setFileSize(((Integer)finfo.get("fileSize")).intValue());
File f = new File(fVO.getFileStrePath() + fVO.getStreFileNm());
if(!f.exists() || !f.isFile()) continue;
attachFiles.add(fVO);
}
articleVO.setAttachFiles(attachFiles);
}
}
// 첨부파일 삭제
if(StringUtil.isNotEmpty(delFileList)) {
String removedFileListJsonStr = delFileList;
if(removedFileListJsonStr.startsWith("&")) removedFileListJsonStr = StringEscapeUtils.unescapeHtml(removedFileListJsonStr);
if(removedFileListJsonStr.startsWith("\"")) removedFileListJsonStr = removedFileListJsonStr.substring(1);
if(removedFileListJsonStr.endsWith("\"")) removedFileListJsonStr = removedFileListJsonStr.substring(0, removedFileListJsonStr.length()-1);
removedFileListJsonStr = removedFileListJsonStr.replaceAll("\\\\", "");
log.debug("removedFileListJsonStr : " + removedFileListJsonStr);
ObjectMapper mapper = new ObjectMapper();
List<Map<String, Object>> removedFileListObj = null;
try {
removedFileListObj = mapper.readValue(removedFileListJsonStr, new TypeReference<List<Map<String, Object>>>() {
});
} catch (JsonMappingException e) {
log.error("updateQnaArticle Json 변환 처리 오류 JsonMappingException : " + e.toString());
} catch (JsonProcessingException e) {
log.error("updateQnaArticle Json 변환 처리 오류 JsonProcessingException : " + e.toString());
}
if(removedFileListObj != null && removedFileListObj.size() > 0) {
String attachFileId = (String)(removedFileListObj.get(0).get("attachFileId"));
if(StringUtil.isEmpty(attachFileId)) attachFileId = articleOrg.getBdAttachFileId();
if(StringUtil.isEmpty(attachFileId)) {
log.error("첨부파일 아이디(attachFileId) 값은 필수 항목입니다. 첨부파일 삭제에 실패하였습니다. 그러나, 게시물 변경은 계속 진행됩니다.");
}
if(StringUtil.isNotEmpty(attachFileId) && attachFileId.equals(articleOrg.getBdAttachFileId())) {
List<AttachFileVO> removedAttachFiles = new ArrayList<AttachFileVO>();
for(int i=0; i<removedFileListObj.size(); i++) {
Map remFinfo = removedFileListObj.get(i);
AttachFileVO fVO = new AttachFileVO();
String fileSnStr = (String)remFinfo.get("fileSn");
if(StringUtil.isEmpty(fileSnStr)) {
log.error("파일순번 정보가 존재하지 않습니다. : " + (String)remFinfo.get("streFileNm"));
continue;
}
int fileSn = 0;
try {
fileSn = Integer.parseInt(fileSnStr);
}catch(NumberFormatException e) {
log.error("삭제할 파일순번 정보 오류입니다. : " + fileSnStr + " OF " + (String)remFinfo.get("streFileNm"));
continue;
}
fVO.setAttachFileId(attachFileId);
fVO.setFileSn(fileSn);
removedAttachFiles.add(fVO);
}
articleVO.setRemovedAttachFiles(removedAttachFiles);
}
}
}
// 수정 처리
int ret = qnaService.updateArticle(articleVO);
if(ret < 1) {
redirectAttrs.addFlashAttribute("searchArticle", articleVO);
redirectAttrs.addFlashAttribute("message", "수정이 처리되지 못했습니다.");
return "redirect:/bbs/insertQnaForm.do";
}
model.addAttribute("searchArticle", articleVO);
redirectAttrs.addFlashAttribute("message", "성공적으로 수정하였습니다.");
return "redirect:/bbs/listQnas.do";
}
/**
* 게시글을 삭제한다.
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping("/bbs/deleteQnaArticle.do")
public String deleteQnaArticle(
HttpServletRequest request
, ArticleVO articleVO
, RedirectAttributes redirectAttrs
, ModelMap model) throws Exception {
NlibLoginVO nlibLoginVO = getNlibLoginVO(request);
// 권한 변경 가능 상태 체크
articleVO.setLoginedMbInfoId(getMbInfoId(request));
String message = qnaService.canModify(articleVO);
if(message != null) {
redirectAttrs.addFlashAttribute("searchArticle", articleVO);
redirectAttrs.addFlashAttribute("message", message);
return "redirect:/bbs/insertQnaForm.do";
}
ArticleVO articleOrgVO = qnaService.selectArticle(articleVO);
articleOrgVO.setModId(nlibLoginVO.getMbInfoId());
// 삭제 처리
int ret = qnaService.deleteArticle(articleOrgVO);
if(ret < 1) {
redirectAttrs.addFlashAttribute("searchArticle", articleOrgVO);
redirectAttrs.addFlashAttribute("message", "삭제 처리되지 못했습니다.");
return "redirect:/bbs/insertQnaForm.do";
}
model.addAttribute("searchArticle", articleOrgVO);
redirectAttrs.addFlashAttribute("message", "성공적으로 삭제되었습니다.");
return "redirect:/bbs/listQnas.do";
}
}

View File

@ -0,0 +1,459 @@
package nlib.cmm;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import nlib.cmm.exception.ErrorMessage;
import nlib.restful.DataApiResVO;
import nlib.security.SecUserVO;
import nlib.user.service.LoginService;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
import nlib.util.UUID;
/**
* <pre>
* @Class Name : NlibCommonController.java
*
* @Description : 컨트롤러의 공통적인 기능을 제공하는 컨트롤러 상위 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 23. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 23.
* @version 1.0
*
*/
public class NlibCommonController {
private static final Logger log = LoggerFactory.getLogger(NlibCommonController.class);
@Resource(name = "loginService")
private LoginService _loginService;
private static final int INFO_ID_COUNCIL_CD = 1; /* 현재 지방문화원 코드를 지칭하는 식별자 */
private static final int INFO_ID_COUNCIL_NM = 2; /* 현재 지방문화원 명칭을 지칭하는 식별자 */
/**
* 스프링 시큐리티 Authentication를 통해서 사용자로그인정보 NlibLoginVO를 리턴한다.
*
* @param authentication
* @return
*/
public NlibLoginVO getNlibLoginVO(Authentication authentication) {
if(authentication == null) return new NlibLoginVO();
return (NlibLoginVO)authentication.getPrincipal();
}
public NlibLoginVO getNlibLoginVO(HttpServletRequest request) {
Authentication auth = (Authentication)request.getUserPrincipal();
if(auth == null || !auth.isAuthenticated()) return new NlibLoginVO();
NlibLoginVO loginVO = (NlibLoginVO)auth.getPrincipal();
if(loginVO == null || StringUtil.isEmpty(loginVO.getMbInfoId())) return new NlibLoginVO();
return loginVO;
}
/**
* 인증에 저장된 사용자 로그인 정보 VO의 값을 매개변수값으로 대체하여 저장하고 돌려 준다.
*
* @param request
* @param newLoginVO
* @return
*/
public NlibLoginVO replaceNlibLoginVO(HttpServletRequest request, NlibLoginVO newLoginVO) {
if(newLoginVO == null) return null;
Authentication auth = (Authentication)request.getUserPrincipal();
if(auth == null || !auth.isAuthenticated()) return new NlibLoginVO();
NlibLoginVO loginVO = getNlibLoginVO(request);
if(loginVO == null) return null;
if(!loginVO.getMbInfoId().equals(newLoginVO.getMbInfoId())) {
log.error("replaceNlibLoginVO > 서로 다른 사용자 정보이므로 인증 LoginVO 정보를 변경할 수 없습니다.");
return null;
}
// 복사작업
Method[] methods = NlibLoginVO.class.getMethods();
String mName;
HashMap<String, Method> setterNames = new HashMap<String, Method>();
HashMap<String, Method> getterNames = new HashMap<String, Method>();
final String skipSetterList = "|setIp|setAlerted|setAuthorityList|";
for(Method m : methods) {
mName = m.getName();
if(skipSetterList.contains(mName)) continue;
//log.debug("NlibLoginVO : methods > " + m.getName());
if(mName.toUpperCase().startsWith("SET")) setterNames.put(mName, m);
else if(mName.toUpperCase().startsWith("GET")) getterNames.put(mName, m);
else if(mName.toUpperCase().startsWith("IS")) getterNames.put(mName, m);
}
String getterName;
for(String setterName : setterNames.keySet()) {
getterName = "get" + setterName.substring(3);
Method setter = setterNames.get(setterName);
Method getter = getterNames.get(getterName);
if(setter != null && getter != null) {
try {
String oldValue = (String)getter.invoke(loginVO);
String newValue = (String)getter.invoke(newLoginVO);
setter.invoke(loginVO, getter.invoke(newLoginVO));
//log.debug("replaceNlibLoginVO > Method invoke : " + setterName + " : " + oldValue + " -> " + newValue);
} catch(IllegalAccessException e) {
log.error("replaceNlibLoginVO > Method invoke IllegalAccessException : " + setterName + ", " + getterName);
} catch(IllegalArgumentException e) {
log.error("replaceNlibLoginVO > Method invoke IllegalArgumentException : " + setterName + ", " + getterName);
} catch(InvocationTargetException e) {
log.error("replaceNlibLoginVO > Method invoke InvocationTargetException : " + setterName + ", " + getterName);
}
}
}
return loginVO;
}
/**
* 사용자로그인정보 ID를 리턴한다.
* 로그인하지 않은 경우, null을 리턴한다.
*
* @param request
* @return
*/
public String getMbInfoId(HttpServletRequest request) {
Authentication auth = (Authentication)request.getUserPrincipal();
if(auth == null || !auth.isAuthenticated()) return null;
NlibLoginVO loginVO = (NlibLoginVO)auth.getPrincipal();
if(loginVO == null || StringUtil.isEmpty(loginVO.getMbInfoId())) return null;
return loginVO.getMbInfoId();
}
/**
* 스프링 시큐리티 Authentication를 통해서 사용자로그인정보 SecUserVO를 리턴한다.
*
* @param authentication
* @return
*/
public SecUserVO getSecLoginVO(Authentication authentication) {
if(authentication == null) return null;
return (SecUserVO)authentication.getPrincipal();
}
public ResponseEntity<String> makeResponseEntityJson(DataApiResVO resVO) {
// Convert Json
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8");
try {
jsonStr = mapper.writeValueAsString(resVO);
log.debug("RETURN DATA > json:" + jsonStr);
} catch (JsonProcessingException e) {
ErrorMessage eMsg = new ErrorMessage("ERR_JSON_CONVERT", "응답객체를 JSON으로 변환 처리 중 오류가 발생하였습니다. : " + e.toString());
try { jsonStr = mapper.writeValueAsString(eMsg); } catch (JsonProcessingException ee) {
log.error("makeResponseEntityJson > JsonProcessingException내부 JsonProcessingException : " + ee.toString());
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(headers).body(jsonStr);
}
return ResponseEntity.ok().headers(headers).body(jsonStr);
}
public ResponseEntity<String> makeResponseEntityJson(List<HashMap<String,String>> list) {
// Convert Json
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8");
try {
jsonStr = mapper.writeValueAsString(list);
log.debug("RETURN DATA > json:" + jsonStr);
} catch (JsonProcessingException e) {
ErrorMessage eMsg = new ErrorMessage("ERR_JSON_CONVERT", "응답객체를 JSON으로 변환 처리 중 오류가 발생하였습니다. : " + e.toString());
try { jsonStr = mapper.writeValueAsString(eMsg); } catch (JsonProcessingException ee) {
log.error("makeResponseEntityJson > JsonProcessingException내부 JsonProcessingException : " + ee.toString());
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(headers).body(jsonStr);
}
return ResponseEntity.ok().headers(headers).body(jsonStr);
}
public ResponseEntity<String> makeResponseEntityJson(HashMap<String,Object> retMap) {
// Convert Json
ObjectMapper mapper = new ObjectMapper();
String jsonStr = null;
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_TYPE, "application/json; charset=UTF-8");
try {
jsonStr = mapper.writeValueAsString(retMap);
log.debug("RETURN DATA > json:" + jsonStr);
} catch (JsonProcessingException e) {
ErrorMessage eMsg = new ErrorMessage("ERR_JSON_CONVERT", "응답객체를 JSON으로 변환 처리 중 오류가 발생하였습니다. : " + e.toString());
try { jsonStr = mapper.writeValueAsString(eMsg); } catch (JsonProcessingException ee) {
log.error("makeResponseEntityJson > JsonProcessingException내부 JsonProcessingException : " + ee.toString());
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).headers(headers).body(jsonStr);
}
return ResponseEntity.ok().headers(headers).body(jsonStr);
}
public ModelMap addParamsToModel(Map<String, String> paramMap, ModelMap model) {
return addParamsToModel(paramMap, model, null, null);
}
public ModelMap addParamsToModel(Map<String, String> paramMap, ModelMap model, String upperMapName, String itemNames) {
if(paramMap == null || paramMap.size() < 1) return model;
if(model == null) return model;
String filter = null;
if(StringUtil.isNotEmpty(itemNames)) {
filter = "," + itemNames + ",";
filter = filter.replaceAll(" ", "");
}
boolean existUpperMap = StringUtil.isNotEmpty(upperMapName);
Map<String, String> uppperMap = null;
if(existUpperMap) uppperMap = new HashMap<String, String>();
for(String key : paramMap.keySet()) {
if(filter != null && !filter.contains("," + key + ",")) {
continue;
}
if(existUpperMap) {
uppperMap.put(key, paramMap.get(key));
} else {
model.addAttribute(key, paramMap.get(key));
}
}
if(existUpperMap) model.addAttribute(upperMapName, uppperMap);
return model;
}
public RedirectAttributes addParamsToRedirect(Map<String, String> paramMap, RedirectAttributes redirectAttrs) {
return addParamsToRedirect(paramMap, redirectAttrs, null, null);
}
public RedirectAttributes addParamsToRedirect(Map<String, String> paramMap
, RedirectAttributes redirectAttrs
, String upperMapName
, String itemNames) {
if(paramMap == null || paramMap.size() < 1) return redirectAttrs;
if(redirectAttrs == null) return redirectAttrs;
String filter = null;
if(StringUtil.isNotEmpty(itemNames)) {
filter = "," + itemNames + ",";
filter = filter.replaceAll(" ", "");
}
boolean existUpperMap = StringUtil.isNotEmpty(upperMapName);
Map<String, String> uppperMap = null;
if(existUpperMap) uppperMap = new HashMap<String, String>();
for(String key : paramMap.keySet()) {
if(filter != null && !filter.contains("," + key + ",")) {
continue;
}
if(existUpperMap) {
uppperMap.put(key, paramMap.get(key));
} else {
redirectAttrs.addFlashAttribute(key, paramMap.get(key));
}
}
if(existUpperMap) redirectAttrs.addFlashAttribute(upperMapName, uppperMap);
return redirectAttrs;
}
public String addParamsToUrl(String url, String paramName, String paramValue) {
if(StringUtil.isEmpty(url)) return null;
if(StringUtil.isEmpty(paramName)) return url;
String newUrl = url;
if(url.contains("?")) newUrl += "&";
else newUrl += "?";
newUrl += paramName + "=" + StringUtil.getString(paramValue, "").trim();
return newUrl;
}
/**
* paramMap에 이전 요청에서 전달할 추가한 POST방식의 매개변수값을 paramMap에 추가한다.
*
* @param paramMap
* @param req
*/
public void addParamFromInputFlash(Map<String, String> paramMap, HttpServletRequest req) {
if(req == null) return;
Map<String, String> inFlashMap = (Map<String, String>)RequestContextUtils.getInputFlashMap(req);
if(inFlashMap == null || inFlashMap.size() < 1) return;
if(paramMap == null) paramMap = new HashMap<String, String>();
for(String key : inFlashMap.keySet()) {
String value = inFlashMap.get(key);
if(StringUtil.isNotEmpty(value)) {
paramMap.put(key, value);
}
}
return;
}
/**
* 현재 요청(또는 세션)하고 있는 지방문화원 코드를 리턴한다.
*
* @param request
* @return
*/
private String getCurCouncilInfo(HttpServletRequest request, int which) {
HttpSession session = request.getSession();
return (String)session.getAttribute( (which == INFO_ID_COUNCIL_CD ? "councilCd" : "councilNm"));
}
public String getCurCouncilCd(HttpServletRequest request) {
return getCurCouncilInfo(request, INFO_ID_COUNCIL_CD);
}
public String getCurCouncilNm(HttpServletRequest request) {
return getCurCouncilInfo(request, INFO_ID_COUNCIL_NM);
}
public void setAlerted(HttpServletRequest request, boolean alerted) {
NlibLoginVO nlibLoginVO = getNlibLoginVO(request);
if(nlibLoginVO == null) return;
nlibLoginVO.setAlerted(alerted);
return;
}
public boolean isAlerted(HttpServletRequest request) {
NlibLoginVO nlibLoginVO = getNlibLoginVO(request);
if(nlibLoginVO == null) return false;
return nlibLoginVO.isAlerted();
}
public String getParamStr(Map<String, String> paramMap, String paramName) {
return getParamStr(paramMap, paramName, null);
}
public String getParamStr(Map<String, String> paramMap, String paramName, String defValue) {
if(paramMap == null) return null;
if(StringUtil.isEmpty(paramName)) return null;
String value = (String)paramMap.get(paramName);
return StringUtil.isEmpty(value) ? defValue : value;
}
/**
* 세션에 CSRF 방지를 위한 토큰을 생성한다.
*
* @param request
*/
public final static String SESSION_CSRF_TOKEN_NAME = "SESSION_CSRF_TOKEN";
public String generateCsrfToken(HttpServletRequest request) {
HttpSession session = request.getSession();
String token = UUID.getNewUUID();
session.setAttribute(SESSION_CSRF_TOKEN_NAME, token);
log.debug("generateCsrfToken > " + session.getAttribute(SESSION_CSRF_TOKEN_NAME));
return token;
}
/**
* 입력받은 CSRF 토큰이 유효한지 확인한다.
*
* @param request
* @param pToken
* @return
*/
public boolean isValidCsrfToken(HttpServletRequest request, String pToken) {
HttpSession session = request.getSession();
String sToken = (String)session.getAttribute(SESSION_CSRF_TOKEN_NAME);
if(request == null || StringUtil.isEmpty(pToken) || StringUtil.isEmpty(sToken)) return false;
if(sToken.equals(pToken)) return true;
return false;
}
}

View File

@ -0,0 +1,166 @@
package nlib.cmm.crypto;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import egovframework.rte.fdl.cryptography.EgovPasswordEncoder;
import egovframework.rte.fdl.cryptography.impl.EgovARIACryptoServiceImpl;
import nlib.cmm.service.NlibProperty;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : AriaCrypto.java
*
* @Description : 양방향 Aria 알고리즘 암복호화 처리 클래스 (egov Aria 알고리즘 구현체 사용)
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 8. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 8.
* @version 1.0
*
*/
@Component("ariaCrypto")
public class AriaCrypto {
private static final Logger log = LoggerFactory.getLogger(AriaCrypto.class);
/**
* 기본키를 가지고 암호화한다.
*
* @param value
* @return
* @throws InvalidKeyException
*/
public static String encode(String value){
String ret = null;
try {
ret = AriaUtil.ariaEncrypt(value);
} catch(UnsupportedEncodingException | InvalidKeyException e) {
log.error("ERROR at AriaCrypto.encode : " + e.toString());
ret = null;
}
return ret;
}
/**
* 기본키를 가지고 Egov 모듈을 사용하여 암호화한다.
*
* @param value
* @return
*/
public static String encodeEgov(String value) {
return encodeEgov(value, NlibProperty.getProperty("crypto.aria.defaultKey"));
}
/**
* 전달받은 key(사용자고유번호 혹은 메일주소 salt값) Egov 모듈을 사용하여 암호화한다.
*
* @param value
* @param key
* @return
*/
public static String encodeEgov(String value, String key) {
if(StringUtil.isEmpty(value)) {
log.error("encode : 암호화할 문자열 정보가 없습니다.");
return null;
}
if(StringUtil.isEmpty(key)) {
log.error("encode : 암호화에 사용할 키 정보가 없습니다.");
return null;
}
EgovPasswordEncoder egovPasswordEncoder = new EgovPasswordEncoder();
String hashedPassword = egovPasswordEncoder.encryptPassword(key);
egovPasswordEncoder.setHashedPassword(hashedPassword);
egovPasswordEncoder.setAlgorithm("SHA-256");
EgovARIACryptoServiceImpl egovARIACryptoServiceImpl = new EgovARIACryptoServiceImpl();
egovARIACryptoServiceImpl.setPasswordEncoder(egovPasswordEncoder);
egovARIACryptoServiceImpl.setBlockSize(1025);
return Base64.encodeBase64String(egovARIACryptoServiceImpl.encrypt(value.getBytes(), key));
}
/**
* 기본키를 가지고 복호화한다.
*
* @param value
* @return
*/
public static String decode(String value) {
String ret = null;
try {
ret = AriaUtil.ariaDecrypt(value);
} catch(UnsupportedEncodingException | InvalidKeyException e) {
log.error("ERROR at AriaCrypto.decode : " + e.toString());
ret = null;
}
return ret;
}
/**
* 기본키를 가지고 Egov 모듈을 사용하여 복호화한다.
*
* @param value
* @return
*/
public static String decodeEgov(String value) {
return decodeEgov(value, NlibProperty.getProperty("crypto.aria.defaultKey"));
}
/**
* 전달받은 key(사용자고유번호 혹은 메일주소 salt값) Egov 모듈을 사용하여 복호화한다.
* @param value
* @param key
* @return
*/
public static String decodeEgov(String value, String key) {
if(StringUtil.isEmpty(value)) {
log.error("decode : 복호화할 암호문자열 정보가 없습니다.");
return null;
}
if(StringUtil.isEmpty(key)) {
log.error("decode : 복호화에 사용할 키 정보가 없습니다.");
return null;
}
EgovPasswordEncoder egovPasswordEncoder = new EgovPasswordEncoder();
String hashedPassword = egovPasswordEncoder.encryptPassword(key);
egovPasswordEncoder.setHashedPassword(hashedPassword);
egovPasswordEncoder.setAlgorithm("SHA-256");
EgovARIACryptoServiceImpl egovARIACryptoServiceImpl = new EgovARIACryptoServiceImpl();
egovARIACryptoServiceImpl.setPasswordEncoder(egovPasswordEncoder);
egovARIACryptoServiceImpl.setBlockSize(1025);
return new String(egovARIACryptoServiceImpl.decrypt(Base64.decodeBase64(value), key));
}
}

View File

@ -0,0 +1,590 @@
//
// ARIA.java
//
// A pure Java implementation of ARIA
// following the official ARIA specification at
//
package nlib.cmm.crypto;
import java.io.PrintStream;
import java.security.InvalidKeyException;
public class AriaEngine {
private static final char[] HEX_DIGITS = {
'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
};
private static final int[][] KRK = {
{0x517cc1b7, 0x27220a94, 0xfe13abe8, 0xfa9a6ee0},
{0x6db14acc, 0x9e21c820, 0xff28b1d5, 0xef5de2b0},
{0xdb92371d, 0x2126e970, 0x03249775, 0x04e8c90e}
};
private static final byte[] S1 = new byte[256];
private static final byte[] S2 = new byte[256];
private static final byte[] X1 = new byte[256];
private static final byte[] X2 = new byte[256];
private static final int[] TS1 = new int[256];
private static final int[] TS2 = new int[256];
private static final int[] TX1 = new int[256];
private static final int[] TX2 = new int[256];
private String publicKey = "CREDIF_MASTERKEY";
private String privateKey = "";
// Static initializer. For setting up the tables
static {
int[] exp = new int[256];
int[] log = new int[256];
exp[0] = 1;
for (int i=1; i < 256; i++) {
int j = (exp[i-1] << 1) ^ exp[i-1];
if ((j & 0x100) != 0) j ^= 0x11b;
exp[i] = j;
}
for (int i=1; i < 255; i++)
log[exp[i]] = i;
int[][] A = {
{1, 0, 0, 0, 1, 1, 1, 1},
{1, 1, 0, 0, 0, 1, 1, 1},
{1, 1, 1, 0, 0, 0, 1, 1},
{1, 1, 1, 1, 0, 0, 0, 1},
{1, 1, 1, 1, 1, 0, 0, 0},
{0, 1, 1, 1, 1, 1, 0, 0},
{0, 0, 1, 1, 1, 1, 1, 0},
{0, 0, 0, 1, 1, 1, 1, 1}
};
int[][] B = {
{0, 1, 0, 1, 1, 1, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 1, 1, 1},
{1, 0, 0, 1, 1, 1, 0, 1},
{0, 0, 1, 0, 1, 1, 0, 0},
{1, 0, 0, 0, 0, 0, 0, 1},
{0, 1, 0, 1, 1, 1, 0, 1},
{1, 1, 0, 1, 0, 0, 1, 1}
};
for (int i=0; i<256; i++) {
int t=0, p;
if (i==0)
p=0;
else
p=exp[255-log[i]];
for (int j=0; j<8; j++) {
int s=0;
for (int k=0; k<8; k++) {
if (((p>>>(7-k))&0x01)!=0)
s^=A[k][j];
}
t=(t<<1)^s;
}
t^=0x63;
S1[i]=(byte)t;
X1[t]=(byte)i;
}
for (int i = 0; i < 256; i++) {
int t = 0, p;
if (i==0)
p=0;
else
p=exp[(247*log[i])%255];
for (int j = 0; j < 8; j++) {
int s = 0;
for (int k = 0; k < 8; k++) {
if (((p >>> k) & 0x01) != 0)
s ^= B[7-j][k];
}
t = (t << 1) ^ s;
}
t^=0xe2;
S2[i] = (byte) t;
X2[t] = (byte) i;
}
for (int i = 0; i < 256; i++) {
TS1[i]=0x00010101*(S1[i]&0xff);
TS2[i]=0x01000101*(S2[i]&0xff);
TX1[i]=0x01010001*(X1[i]&0xff);
TX2[i]=0x01010100*(X2[i]&0xff);
}
}
private int keySize=0;
private int numberOfRounds=0;
private byte[] masterKey=null;
private int[] encRoundKeys=null, decRoundKeys=null;
public AriaEngine(int keySize) throws InvalidKeyException {
setKeySize(keySize);
}
/**
* Resets the class so that it can be reused for another master key.
*/
void reset() {
this.keySize=0;
this.numberOfRounds=0;
this.masterKey=null;
this.encRoundKeys=null;
this.decRoundKeys=null;
}
int getKeySize() {
return this.keySize;
}
void setKeySize(int keySize) throws InvalidKeyException {
this.reset();
if (keySize!=128 && keySize!=192 && keySize!=256)
throw new InvalidKeyException("keySize="+keySize);
this.keySize = keySize;
switch (keySize) {
case 128:
this.numberOfRounds = 12;
break;
case 192:
this.numberOfRounds = 14;
break;
case 256:
this.numberOfRounds = 16;
}
}
void setKey(byte[] masterKey) throws InvalidKeyException {
if (masterKey.length*8<keySize)
throw new InvalidKeyException("masterKey size="+masterKey.length);
this.decRoundKeys = null;
this.encRoundKeys = null;
this.masterKey = (byte[])masterKey.clone();
}
void setupEncRoundKeys() throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
if (this.encRoundKeys==null)
this.encRoundKeys = new int[4*(this.numberOfRounds+1)];
this.decRoundKeys = null;
doEncKeySetup(this.masterKey, this.encRoundKeys, this.keySize);
}
void setupDecRoundKeys() throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.encRoundKeys==null)
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
else
setupEncRoundKeys();
this.decRoundKeys = (int[])encRoundKeys.clone();
doDecKeySetup(this.masterKey, this.decRoundKeys, this.keySize);
}
void setupRoundKeys() throws InvalidKeyException {
setupDecRoundKeys();
}
private static void doCrypt(byte[] i, int ioffset, int[] rk, int nr, byte[] o, int ooffset) {
int t0, t1, t2, t3, j=0;
t0 = toInt(i[ 0+ioffset], i[ 1+ioffset], i[ 2+ioffset], i[ 3+ioffset]);
t1 = toInt(i[ 4+ioffset], i[ 5+ioffset], i[ 6+ioffset], i[ 7+ioffset]);
t2 = toInt(i[ 8+ioffset], i[ 9+ioffset], i[10+ioffset], i[11+ioffset]);
t3 = toInt(i[12+ioffset], i[13+ioffset], i[14+ioffset], i[15+ioffset]);
for (int r=1; r<nr/2; r++) {
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
t0=TX1[(t0>>>24)&0xff]^TX2[(t0>>>16)&0xff]^TS1[(t0>>>8)&0xff]^TS2[t0&0xff];
t1=TX1[(t1>>>24)&0xff]^TX2[(t1>>>16)&0xff]^TS1[(t1>>>8)&0xff]^TS2[t1&0xff];
t2=TX1[(t2>>>24)&0xff]^TX2[(t2>>>16)&0xff]^TS1[(t2>>>8)&0xff]^TS2[t2&0xff];
t3=TX1[(t3>>>24)&0xff]^TX2[(t3>>>16)&0xff]^TS1[(t3>>>8)&0xff]^TS2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t3=badc(t3); t0=cdab(t0); t1=dcba(t1);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
}
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t0^=rk[j++]; t1^=rk[j++]; t2^=rk[j++]; t3^=rk[j++];
o[ 0+ooffset] = (byte)(X1[0xff&(t0>>>24)] ^ (rk[j ]>>>24));
o[ 1+ooffset] = (byte)(X2[0xff&(t0>>>16)] ^ (rk[j ]>>>16));
o[ 2+ooffset] = (byte)(S1[0xff&(t0>>> 8)] ^ (rk[j ]>>> 8));
o[ 3+ooffset] = (byte)(S2[0xff&(t0 )] ^ (rk[j ] ));
o[ 4+ooffset] = (byte)(X1[0xff&(t1>>>24)] ^ (rk[j+1]>>>24));
o[ 5+ooffset] = (byte)(X2[0xff&(t1>>>16)] ^ (rk[j+1]>>>16));
o[ 6+ooffset] = (byte)(S1[0xff&(t1>>> 8)] ^ (rk[j+1]>>> 8));
o[ 7+ooffset] = (byte)(S2[0xff&(t1 )] ^ (rk[j+1] ));
o[ 8+ooffset] = (byte)(X1[0xff&(t2>>>24)] ^ (rk[j+2]>>>24));
o[ 9+ooffset] = (byte)(X2[0xff&(t2>>>16)] ^ (rk[j+2]>>>16));
o[10+ooffset] = (byte)(S1[0xff&(t2>>> 8)] ^ (rk[j+2]>>> 8));
o[11+ooffset] = (byte)(S2[0xff&(t2 )] ^ (rk[j+2] ));
o[12+ooffset] = (byte)(X1[0xff&(t3>>>24)] ^ (rk[j+3]>>>24));
o[13+ooffset] = (byte)(X2[0xff&(t3>>>16)] ^ (rk[j+3]>>>16));
o[14+ooffset] = (byte)(S1[0xff&(t3>>> 8)] ^ (rk[j+3]>>> 8));
o[15+ooffset] = (byte)(S2[0xff&(t3 )] ^ (rk[j+3] ));
}
void encrypt(byte[] i, int ioffset, byte[] o, int ooffset) throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.encRoundKeys==null)
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
else
setupEncRoundKeys();
doCrypt(i, ioffset, this.encRoundKeys, this.numberOfRounds, o, ooffset);
}
byte[] encrypt(byte[] i, int ioffset) throws InvalidKeyException {
byte[] o = new byte[16];
this.encrypt(i, ioffset, o, 0);
return o;
}
public void decrypt(byte cipher[], byte plain[], int size)
throws InvalidKeyException {
int iLoop = size / 16;
int offset = 0;
for (int i = 0; i < iLoop; i++) {
decrypt(cipher, offset, plain, offset);
offset += 16;
}
}
void decrypt(byte[] i, int ioffset, byte[] o, int ooffset) throws InvalidKeyException {
if (this.keySize==0)
throw new InvalidKeyException("keySize");
if (this.decRoundKeys==null)
if (this.masterKey==null)
throw new InvalidKeyException("masterKey");
else
setupDecRoundKeys();
doCrypt(i, ioffset, this.decRoundKeys, this.numberOfRounds, o, ooffset);
}
byte[] decrypt(byte[] i, int ioffset) throws InvalidKeyException {
byte[] o = new byte[16];
this.decrypt(i, ioffset, o, 0);
return o;
}
private static void doEncKeySetup(byte[] mk, int[] rk, int keyBits) {
int t0, t1, t2, t3, q, j=0;
int[] w0 = new int[4];
int[] w1 = new int[4];
int[] w2 = new int[4];
int[] w3 = new int[4];
w0[0] = toInt(mk[ 0], mk[ 1], mk[ 2], mk[ 3]);
w0[1] = toInt(mk[ 4], mk[ 5], mk[ 6], mk[ 7]);
w0[2] = toInt(mk[ 8], mk[ 9], mk[10], mk[11]);
w0[3] = toInt(mk[12], mk[13], mk[14], mk[15]);
q = (keyBits - 128) / 64;
t0=w0[0]^KRK[q][0]; t1=w0[1]^KRK[q][1];
t2=w0[2]^KRK[q][2]; t3=w0[3]^KRK[q][3];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
if (keyBits > 128) {
w1[0] = toInt(mk[16], mk[17], mk[18], mk[19]);
w1[1] = toInt(mk[20], mk[21], mk[22], mk[23]);
if (keyBits > 192) {
w1[2] = toInt(mk[24], mk[25], mk[26], mk[27]);
w1[3] = toInt(mk[28], mk[29], mk[30], mk[31]);
} else {
w1[2]=w1[3]=0;
}
} else {
w1[0]=w1[1]=w1[2]=w1[3]=0;
}
w1[0]^=t0; w1[1]^=t1; w1[2]^=t2; w1[3]^=t3;
t0=w1[0]; t1=w1[1]; t2=w1[2]; t3=w1[3];
q = (q==2)? 0 : (q+1);
t0^=KRK[q][0]; t1^=KRK[q][1]; t2^=KRK[q][2]; t3^=KRK[q][3];
t0=TX1[(t0>>>24)&0xff]^TX2[(t0>>>16)&0xff]^TS1[(t0>>>8)&0xff]^TS2[t0&0xff];
t1=TX1[(t1>>>24)&0xff]^TX2[(t1>>>16)&0xff]^TS1[(t1>>>8)&0xff]^TS2[t1&0xff];
t2=TX1[(t2>>>24)&0xff]^TX2[(t2>>>16)&0xff]^TS1[(t2>>>8)&0xff]^TS2[t2&0xff];
t3=TX1[(t3>>>24)&0xff]^TX2[(t3>>>16)&0xff]^TS1[(t3>>>8)&0xff]^TS2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t3=badc(t3); t0=cdab(t0); t1=dcba(t1);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t0^=w0[0]; t1^=w0[1]; t2^=w0[2]; t3^=w0[3];
w2[0]=t0; w2[1]=t1; w2[2]=t2; w2[3]=t3;
q = (q==2)? 0 : (q+1);
t0^=KRK[q][0]; t1^=KRK[q][1]; t2^=KRK[q][2]; t3^=KRK[q][3];
t0=TS1[(t0>>>24)&0xff]^TS2[(t0>>>16)&0xff]^TX1[(t0>>>8)&0xff]^TX2[t0&0xff];
t1=TS1[(t1>>>24)&0xff]^TS2[(t1>>>16)&0xff]^TX1[(t1>>>8)&0xff]^TX2[t1&0xff];
t2=TS1[(t2>>>24)&0xff]^TS2[(t2>>>16)&0xff]^TX1[(t2>>>8)&0xff]^TX2[t2&0xff];
t3=TS1[(t3>>>24)&0xff]^TS2[(t3>>>16)&0xff]^TX1[(t3>>>8)&0xff]^TX2[t3&0xff];
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
w3[0]=t0^w1[0]; w3[1]=t1^w1[1]; w3[2]=t2^w1[2]; w3[3]=t3^w1[3];
gsrk(w0, w1, 19, rk, j); j+=4;
gsrk(w1, w2, 19, rk, j); j+=4;
gsrk(w2, w3, 19, rk, j); j+=4;
gsrk(w3, w0, 19, rk, j); j+=4;
gsrk(w0, w1, 31, rk, j); j+=4;
gsrk(w1, w2, 31, rk, j); j+=4;
gsrk(w2, w3, 31, rk, j); j+=4;
gsrk(w3, w0, 31, rk, j); j+=4;
gsrk(w0, w1, 67, rk, j); j+=4;
gsrk(w1, w2, 67, rk, j); j+=4;
gsrk(w2, w3, 67, rk, j); j+=4;
gsrk(w3, w0, 67, rk, j); j+=4;
gsrk(w0, w1, 97, rk, j); j+=4;
if (keyBits > 128) {
gsrk(w1, w2, 97, rk, j); j+=4;
gsrk(w2, w3, 97, rk, j); j+=4;
}
if (keyBits > 192) {
gsrk(w3, w0, 97, rk, j); j+=4;
gsrk(w0, w1, 109, rk, j);
}
}
/**
* Main bulk of the decryption key setup method. Here we assume that
* the int array rk already contains the encryption round keys.
* @param mk the master key
* @param rk the array which contains the encryption round keys at the
* beginning of the method execution. At the end of method execution
* this will hold the decryption round keys.
* @param keyBits the length of the master key
* @return
*/
private static void doDecKeySetup(byte[] mk, int[] rk, int keyBits) {
int a=0, z;
int[] t = new int[4];
z=32+keyBits/8;
swapBlocks(rk, 0, z);
a+=4; z-=4;
for (; a<z; a+=4, z-=4)
swapAndDiffuse(rk, a, z, t);
diff(rk, a, t, 0);
rk[a]=t[0]; rk[a+1]=t[1]; rk[a+2]=t[2]; rk[a+3]=t[3];
}
private static int toInt(byte b0, byte b1, byte b2, byte b3) {
return (b0&0xff)<<24 ^ (b1&0xff)<<16 ^ (b2&0xff)<<8 ^ b3&0xff;
}
private static void toByteArray(int i, byte[] b, int offset) {
b[offset ] = (byte)(i>>>24);
b[offset+1] = (byte)(i>>>16);
b[offset+2] = (byte)(i>>> 8);
b[offset+3] = (byte)(i );
}
private static int m(int t) {
return 0x00010101*((t>>>24)&0xff) ^ 0x01000101*((t>>>16)&0xff) ^
0x01010001*((t>>>8)&0xff) ^ 0x01010100*(t&0xff);
}
private static final int badc(int t) {
return ((t<<8)&0xff00ff00) ^ ((t>>>8)&0x00ff00ff);
}
private static final int cdab(int t) {
return ((t<<16)&0xffff0000) ^ ((t>>>16)&0x0000ffff);
}
private static final int dcba(int t) {
return (t&0x000000ff)<<24 ^ (t&0x0000ff00)<<8 ^ (t&0x00ff0000)>>>8 ^ (t&0xff000000)>>>24;
}
private static final void gsrk(int[] x, int[] y, int rot, int[] rk, int offset) {
int q=4-(rot/32), r=rot%32, s=32-r;
rk[offset] = x[0] ^ y[(q )%4]>>>r ^ y[(q+3)%4]<<s;
rk[offset+1] = x[1] ^ y[(q+1)%4]>>>r ^ y[(q )%4]<<s;
rk[offset+2] = x[2] ^ y[(q+2)%4]>>>r ^ y[(q+1)%4]<<s;
rk[offset+3] = x[3] ^ y[(q+3)%4]>>>r ^ y[(q+2)%4]<<s;
}
private static final void diff(int[] i, int offset1, int[] o, int offset2) {
int t0, t1, t2, t3;
t0=m(i[offset1]); t1=m(i[offset1+1]); t2=m(i[offset1+2]); t3=m(i[offset1+3]);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
t1=badc(t1); t2=cdab(t2); t3=dcba(t3);
t1^=t2; t2^=t3; t0^=t1; t3^=t1; t2^=t0; t1^=t2;
o[offset2]=t0; o[offset2+1]=t1; o[offset2+2]=t2; o[offset2+3]=t3;
}
private static final void swapBlocks(int[] arr, int offset1, int offset2) {
int t;
for (int i=0; i<4; i++) {
t = arr[offset1+i];
arr[offset1+i] = arr[offset2+i];
arr[offset2+i] = t;
}
}
private static final void swapAndDiffuse(int[] arr, int offset1, int offset2, int[] tmp) {
diff(arr, offset1, tmp, 0);
diff(arr, offset2, arr, offset1);
arr[offset2]=tmp[0]; arr[offset2+1]=tmp[1];
arr[offset2+2]=tmp[2]; arr[offset2+3]=tmp[3];
}
private static void byteToHex(PrintStream out, byte b) {
char[] buf = {
HEX_DIGITS[(b >>> 4) & 0x0F],
HEX_DIGITS[ b & 0x0F]
};
out.print(new String(buf));
}
private static void intToHex(PrintStream out, int i) {
byte[] b = new byte[4];
toByteArray(i, b, 0);
byteToHex(out, b[0]);
byteToHex(out, b[1]);
byteToHex(out, b[2]);
byteToHex(out, b[3]);
}
private static void printRoundKeys(PrintStream out, int[] roundKeys) {
for (int i=0; i<roundKeys.length; ) { out.print("* ");
intToHex(out, roundKeys[i++]); out.print(" ");
intToHex(out, roundKeys[i++]); out.print(" ");
intToHex(out, roundKeys[i++]); out.print(" ");
intToHex(out, roundKeys[i++]); out.print(" \n");
}
}
public int getBufferSize(int size) {
if (size % 16 != 0)
size = (size / 16 + 1) * 16;
return size;
}
public void encrypt(byte plain[], byte cipher[], int size)throws InvalidKeyException {
int len = getBufferSize(size);
int iLoop = len / 16;
int iMod = size % 16;
int iCopySize = 16;
int offset = 0;
byte in[] = new byte[16];
for (int i = 0; i < iLoop; i++) {
if (i >= iLoop - 1)
if (iMod == 0)
iCopySize = 16;
else
iCopySize = iMod;
for (int j = 0; j < 16; j++)
in[j] = 0;
System.arraycopy(plain, offset, in, 0, iCopySize);
encrypt(in, 0, cipher, offset);
offset += iCopySize;
}
}
/* hex to byte[] convert */
public static byte[] hexToByteArray(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
byte[] ba = new byte[hex.length() / 2];
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
return ba;
}
/* byte to hexa convert */
public static String byteArrayToHex(byte[] ba) {
if (ba == null || ba.length == 0) {
return null;
}
StringBuffer sb = new StringBuffer(ba.length * 2);
String hexNumber;
for (int x = 0; x < ba.length; x++) {
hexNumber = "0" + Integer.toHexString(0xff & ba[x]);
sb.append(hexNumber.substring(hexNumber.length() - 2));
}
return sb.toString();
}
public AriaEngine(int keySize, String privateKey)throws InvalidKeyException {
this.keySize = 0;
numberOfRounds = 0;
masterKey = null;
encRoundKeys = null;
decRoundKeys = null;
setKeySize(keySize);
byte[] mk = new byte[32];
this.privateKey = privateKey;
byte[] p1Key = this.publicKey.getBytes();
System.arraycopy(p1Key, 0, mk, 0, p1Key.length);
this.setKey(mk);
this.setupRoundKeys();
byte[] p2Key = new byte[32];
byte[] mk2 = new byte[32];
byte[] privateKeyByte = privateKey.getBytes();
if (privateKeyByte.length > 32) {
System.arraycopy(privateKeyByte, 0, mk2, 0, 32);
} else {
System.arraycopy(privateKeyByte, 0, mk2, 0, privateKeyByte.length);
}
byte[] makeKey = new byte[32];
this.encrypt(mk2, makeKey, mk2.length);
this.setKey(makeKey);
this.setupRoundKeys();
}
public static void main(String[] args) throws InvalidKeyException {
}
}

View File

@ -0,0 +1,380 @@
/**
* 전자정부 제공 ARIAUTIL
* ARIAUtil
*/
package nlib.cmm.crypto;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import nlib.cmm.service.NlibProperty;
public class AriaUtil {
private static final Logger log = LoggerFactory.getLogger(AriaUtil.class);
public static String ariaEncrypt(String str, String privateKey)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes().length];
p = str.getBytes();
int len = str.getBytes().length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return AriaEngine.byteArrayToHex(c).toUpperCase();
}
/**
* @param privateKey
* @param src
* @param dest
* @throws IOException
* @throws InvalidKeyException
* @throws UnsupportedEncodingException
*/
public static void ariaFileEncrypt(String privateKey, String src, String dest)
throws IOException, InvalidKeyException, UnsupportedEncodingException {
File f = new File(src);
FileInputStream fis = new FileInputStream(src);
long length = f.length();
byte[] b = new byte[(int)length];
try {
int offset = 0;
int numRead = 0;
while (offset < b.length && (numRead=fis.read(b, offset, b.length-offset)) >= 0 ) {
if( (offset + numRead) <= Integer.MAX_VALUE) {
offset += numRead;
} else {
throw new IOException(f.getName() + " too long.");
}
}
if (offset < b.length) {
throw new IOException(f.getName());
}
} finally{
fis.close();
}
AriaEngine instance = new AriaEngine(256, privateKey);
int len = b.length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, b.length);
instance.encrypt(b, c, b.length);
FileOutputStream fos = new FileOutputStream(dest);
try {
fos.write(c);
} catch (IOException e) {
log.error(e.toString());
} finally {
try {
fos.close();
} catch (IOException e) {
log.error(e.toString());
}
}
}
/*
*Aria 복호화
*/
public static String ariaDecrypt(String strHex, String privateKey)
throws InvalidKeyException, UnsupportedEncodingException {
if (strHex==null || strHex.equals("")) return "";
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = AriaEngine.hexToByteArray(strHex);
if(c == null) return null;
p = new byte[c.length];
instance.decrypt(c, p, p.length);
StringBuffer buf = new StringBuffer();
buf.append(new String(p));
return buf.toString().trim();
}
public static void ariaFileDecrypt(String privateKey, String src, String dest)
throws IOException, InvalidKeyException, UnsupportedEncodingException {
File f = new File(src);
FileInputStream fis = new FileInputStream(src);
long length = f.length();
byte[] b = new byte[(int)length];
try {
int offset = 0;
int numRead = 0;
while (offset < b.length && (numRead=fis.read(b, offset, b.length-offset)) >= 0) {
if( (offset + numRead) <= Integer.MAX_VALUE) {
offset += numRead;
} else {
throw new IOException(f.getName() + " too long.");
}
}
if (offset < b.length) {
throw new IOException(f.getName());
}
} finally{
fis.close();
}
AriaEngine instance = new AriaEngine(256, privateKey);
int len = b.length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
byte[] c = new byte[len];
System.arraycopy(b, 0, c, 0, b.length);
instance.decrypt(b, c, b.length);
FileOutputStream fos = new FileOutputStream(dest);
try {
fos.write(c);
} catch (IOException e) {
log.error(e.toString());
} finally {
try {
fos.close();
} catch (IOException e) {
log.error(e.toString());
}
}
}
private static String makeMasterKey(String str) {
String appendStr = "Naravision KebiPortal Solution";
StringBuffer buf = new StringBuffer();
buf.append(str).append(appendStr);
return buf.substring(0,32);
}
/*
*Aria 기본 복호화
*/
public static String ariaDecrypt(String strHex)
throws InvalidKeyException, UnsupportedEncodingException {
String originalData = strHex;
if (strHex==null || strHex.equals("")) return "";
StringBuffer buf = null;
try {
String privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = hexToByteArray(strHex);
if(c == null)
{
return null;
}
p = new byte[c.length];
instance.decrypt(c, p, p.length);
buf = new StringBuffer();
buf.append(new String(p));
return buf.toString().trim();
} catch (Exception e) {
log.error("ERROR at AriaCrypto.hexToByteArray : " + e.toString());
return originalData;
}
}
/*
*aria 기본 암호화
*/
public static String ariaEncrypt(String str)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
String privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes().length];
p = str.getBytes();
int len = str.getBytes().length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return byteArrayToHex(c).toUpperCase();
}
/*
*캐릭터셋 변경 암호화
*/
public static String ariaCharEncrypt(String str, String charset)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
String privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes(charset).length];
p = str.getBytes(charset);
int len = str.getBytes(charset).length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return byteArrayToHex(c).toUpperCase();
}
/*
*캐릭터셋 변경 암호화
*(서버타입설정 열람서버 : read, 등록관리서버 : regi)
*/
public static String ariaCharEncrypt(String str, String charset, String server)
throws InvalidKeyException, UnsupportedEncodingException {
if (str==null || str.equals("")) return "";
String privateKey = "";
if(server.equals("regi")) privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
else privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
p = new byte[str.getBytes(charset).length];
p = str.getBytes(charset);
int len = str.getBytes(charset).length;
if ((len % 16) != 0) {
len = (len / 16 + 1) * 16;
}
c = new byte[len];
System.arraycopy(p, 0, c, 0, p.length);
instance.encrypt(p, c, p.length);
return byteArrayToHex(c).toUpperCase();
}
/*
*Aria 캐릭터셋 변경 복호화
*/
public static String ariaCharDecrypt(String strHex, String charset)
throws InvalidKeyException, UnsupportedEncodingException {
if (strHex==null || strHex.equals("")) return "";
String privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = hexToByteArray(strHex);
if(c == null) return null;
p = new byte[c.length];
instance.decrypt(c, p, p.length);
StringBuffer buf = new StringBuffer();
buf.append(new String(p,charset));
return buf.toString().trim();
}
/*
*Aria 캐릭터셋 변경 복호화
*(서버타입설정 열람서버 : read, 등록관리서버 : regi)
*/
public static String ariaCharDecrypt(String strHex, String charset, String server)
throws InvalidKeyException, UnsupportedEncodingException {
if (strHex==null || strHex.equals("")) return "";
String privateKey = "";
if(server.equals("regi")) privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
else privateKey = NlibProperty.getProperty("crypto.aria.defaultKey");
byte[] p;
byte[] c;
AriaEngine instance = new AriaEngine(256, privateKey);
c = hexToByteArray(strHex);
if(c == null) return null;
p = new byte[c.length];
instance.decrypt(c, p, p.length);
StringBuffer buf = new StringBuffer();
buf.append(new String(p,charset));
return buf.toString().trim();
}
// hex to byte[]
public static byte[] hexToByteArray(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
byte[] ba = new byte[hex.length() / 2];
try {
for (int i = 0; i < ba.length; i++) {
ba[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
}
}catch(NumberFormatException e){
log.error("ERROR at AriaCrypto.hexToByteArray : " + e.toString());
}catch(Exception e) {
log.error("ERROR at AriaCrypto.hexToByteArray : " + e.toString());
}
return ba;
}
// byte[] to hex
public static String byteArrayToHex(byte[] ba) {
if (ba == null || ba.length == 0) {
return null;
}
StringBuffer sb = new StringBuffer(ba.length * 2);
String hexNumber;
for (int x = 0; x < ba.length; x++) {
hexNumber = "0" + Integer.toHexString(0xff & ba[x]);
sb.append(hexNumber.substring(hexNumber.length() - 2));
}
return sb.toString();
}
}

View File

@ -0,0 +1,62 @@
package nlib.cmm.crypto;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import egovframework.rte.fdl.cryptography.EgovPasswordEncoder;
/**
* <pre>
* @Class Name : NlibPasswordEncoder.java
*
* @Description : 스프링 시큐리티 비밀번호 암호화 처리를 위하여 전자정부 프레임워크의 SHA256 알고리즘 구현체를 사용한 비밀번호 인코더 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 9. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 9.
* @version 1.0
*
*/
@Component("nlibPasswordEncoder")
public class NlibPasswordEncoder implements PasswordEncoder { /* extends EgovPasswordEncoder */
private static final Logger log = LoggerFactory.getLogger(NlibPasswordEncoder.class);
@Resource(name = "egovEnvPasswordEncoderService")
EgovPasswordEncoder egovPasswordEncoder;
/*
* 비밀번호를 SHA-256 알고리즘을 사용하여 암호화한다.
*/
@Override
public String encode(CharSequence rawPassword) {
log.debug("encode > rawPassword = " + rawPassword);
return egovPasswordEncoder.encryptPassword(rawPassword.toString());
}
/*
* 입력된 비밀번호가 일치하는 확인한다.
*/
@Override
public boolean matches(CharSequence rawPassword, String encodedPassword) {
log.debug("matches > rawPassword = " + rawPassword);
log.debug("matches > encodedPassword = " + encodedPassword);
return egovPasswordEncoder.checkPassword(rawPassword.toString(), encodedPassword);
}
}

View File

@ -0,0 +1,55 @@
package nlib.cmm.exception;
/**
* <pre>
* @Class Name : ErrorMessage.java
*
* @Description : AJAX 응답값 오류 정보 VO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 16.
* @version 1.0
*
*/
public class ErrorMessage {
String code = null;
String message = null;
public ErrorMessage() {
super();
}
public ErrorMessage(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@ -0,0 +1,91 @@
package nlib.cmm.fileupload;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Map;
import javax.activation.MimetypesFileTypeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.servlet.view.AbstractView;
/**
* <pre>
* @Class Name : DownloadView.java
*
* @Description : 파일 다운로드 VIEW 처리 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 8. 3. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 8. 3.
* @version 1.0
*
*/
public class DownloadView extends AbstractView {
private static final Logger log = LoggerFactory.getLogger(DownloadView.class);
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
File file = (File) model.get("downloadFile");
if(file == null) return;
String fileName = (String) model.get("fname");
String encfileName = null;
String userAgent = request.getHeader("User-Agent");
if (userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("Trident") > -1) {
encfileName = URLEncoder.encode(fileName, "utf-8").replaceAll("\\+", "%20");
} else if (userAgent.indexOf("Chrome") > -1) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < fileName.length(); i++) {
char c = fileName.charAt(i);
if (c > '~') {
sb.append(URLEncoder.encode("" + c, "UTF-8"));
} else {
sb.append(c);
}
}
encfileName = sb.toString();
} else {
encfileName = new String(fileName.getBytes("utf-8"));
}
response.setContentType(getContentType());
MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
response.setContentType(mimetypesFileTypeMap.getContentType(fileName));
response.setContentLength((int) file.length());
response.setHeader("Content-Disposition", "attachment; filename=\"" + encfileName + "\";");
response.setHeader("Content-Transfer-Encoding", "binary");
try( FileInputStream fis = new FileInputStream(file);
OutputStream out = response.getOutputStream())
{
FileCopyUtils.copy(fis, out);
out.flush();
} catch (FileNotFoundException e) {
log.error("renderMergedOutputModel FileNotFoundException ERROR : " + e.toString());
}
}
}

View File

@ -0,0 +1,322 @@
package nlib.cmm.fileupload;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import nlib.bbs.service.AttachFileService;
import nlib.bbs.service.AttachFileVO;
import nlib.cmm.NlibCommonController;
import nlib.cmm.exception.ErrorMessage;
import nlib.cmm.service.NlibProperty;
import nlib.util.FileUtil;
import nlib.util.StringUtil;
import nlib.util.UUID;
/**
* <pre>
* @Class Name : FileUploadController.java
*
* @Description : 파일 업로드를 처리하는 컨트롤러
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 15. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 15.
* @version 1.0
*
*/
@Controller
public class FileUploadController extends NlibCommonController {
private static final Logger log = LoggerFactory.getLogger(FileUploadController.class);
/**
* 첨부파일이 저장되는 최상위 위치
*/
private String FILEUPLOAD_BASE_PATH = NlibProperty.getProperty("fileupload.base.path");
/**
* 경로 부적합 오류 메시지
*/
private static final String MSG_NOT_VALID_FILE_PATH = "파일 경로가 부적합합니다. 관리자에게 문의하여 주시기 바랍니다.";
@Resource(name="attachFileService")
private AttachFileService attachFileService;
/**
* 파일업로드(Ajax) 처리
* - 화면 : Javascript Free Open Framework DropZone 사용
*
* @param multiRequest
* @param subPathKey
* @param response : 파일정보를 담은 JSON String
* @return
*/
@Secured("ROLE_USER")
@ResponseBody
@RequestMapping(value="/fileupload/uploadFilesAjax.do", produces="application/json")
public ResponseEntity uploadFilesAjax(
final MultipartHttpServletRequest multiRequest
, @RequestParam(name="subPathKey") String subPathKey
, HttpServletResponse response) {
String message = null;
// TODO : 권한 체크 추가할
List<AttachFileVO> result = new ArrayList<AttachFileVO>();
try {
// 최상위 위치
if(FileUtil.isEmpty(FILEUPLOAD_BASE_PATH)) {
message = "첨부파일이 저장되는 최상위 위치정보값이 정확하지 않습니다.";
log.error(message + " : FILEUPLOAD_BASE_PATH 값 부재");
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
}
// 서브 위치
if(StringUtil.isEmpty(subPathKey)) {
message = "첨부파일이 저장되는 하위 위치정보값이 정확하지 않습니다.";
log.error(message + " : 매개변수 subPathKey 값 부재");
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
}
String subPath = NlibProperty.getProperty(subPathKey);
if(StringUtil.isEmpty(subPath)) {
message = "첨부파일이 저장되는 하위 위치정보값을 찾을 수 없습니다.";
log.error(message + " : 매개변수 subPathKey의 속성값 부재");
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
}
// 위치정보 적합 확인
if(FileUtil.isNotValid(FILEUPLOAD_BASE_PATH + subPath)) {
message = MSG_NOT_VALID_FILE_PATH;
log.error(message + " : " + (FILEUPLOAD_BASE_PATH + subPath));
ErrorMessage errorMessage = new ErrorMessage("ERROR", message);
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
}
// 파일 업로드 처리
final Map<String, MultipartFile> files = multiRequest.getFileMap();
log.debug("uploadFilesAjax : 진입 > 파일수 = " + (files == null ? " files null " : files.size()));
File dir = new File(FILEUPLOAD_BASE_PATH + subPath);
if(!dir.exists() || !dir.isDirectory()) dir.mkdirs();
if(!files.isEmpty()) {
Iterator<Entry<String, MultipartFile>> itr = files.entrySet().iterator();
MultipartFile file;
String filePath = "";
AttachFileVO atvo;
// 허용 파일 확장자
String acceptableExtList = StringUtil.getString(NlibProperty.getString("fileupload.acceptable.ext"), null);
if(acceptableExtList != null) acceptableExtList = "," + acceptableExtList.trim().toLowerCase();
boolean acceptableExt = false;
// 최대 파일크기
int maxFileSize = NlibProperty.getInt("fileupload.max.mbsize", 10) * 1024 * 1024;
// 최대 개수
int maxFileCount = NlibProperty.getInt("fileupload.max.files", 5);
while (itr.hasNext()) {
if(result.size() >= maxFileCount) {
log.error("최대 개수를 초과하여 이후 파일은 처리되지 않습니다.");
break;
}
acceptableExt = false;
Entry<String, MultipartFile> entry = itr.next();
file = entry.getValue();
String orignlFileNm = file.getOriginalFilename();
//--------------------------------------
// 파일명이 없는 경우 처리 SKIP
// (첨부가 되지 않은 input file type)
//--------------------------------------
if (orignlFileNm == null || "".equals(orignlFileNm)) {
continue;
}
// 파일 확장자
int index = orignlFileNm.lastIndexOf(".");
String fileExt = (index < 1 ? "" : orignlFileNm.substring(index + 1)).toLowerCase();
if(acceptableExtList != null) {
if(acceptableExtList.contains("." + fileExt)) {
acceptableExt = true;
} else if(acceptableExtList.contains("image/*")) {
acceptableExt = ".jpg,.jpe,.jpge,.bmp,.gif,.png".contains("." + fileExt);
}
}
if(!acceptableExt) {
log.error("허용되지 않는 파일 확장자 입니다. : " + orignlFileNm);
continue;
}
int size = (int)file.getSize();
if(size > maxFileSize) {
log.error("첨부파일이 허용 크기를 초과합니다. : " + orignlFileNm);
continue;
}
String streFileNm = UUID.getNewStreFileNm();
filePath = FILEUPLOAD_BASE_PATH + subPath + "/" + streFileNm;
log.debug("FILE UPLOAD : filePath=" + filePath);
file.transferTo(new File(FileUtil.filePathBlackList(filePath)));
atvo = new AttachFileVO();
atvo.setSubPathKey(subPathKey);
//atvo.setAttachFileId(attachFileId); // 실제 DB 저장 처리될때 설정함
atvo.setStreFileNm(streFileNm);
atvo.setOrignlFileNm(orignlFileNm);
atvo.setFileExt(fileExt);
atvo.setFileSize(size);
result.add(atvo);
}
}
} catch(SecurityException e) {
log.error("uploadFilesAjax SecurityException : " + e.toString());
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
} catch(IllegalStateException e) {
log.error("uploadFilesAjax IllegalStateException : " + e.toString());
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
} catch(IOException e) {
log.error("uploadFilesAjax IOException : " + e.toString());
ErrorMessage errorMessage = new ErrorMessage("ERROR", "처리에 실패하였습니다(1)");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
}
// Convert Json
ObjectMapper mapper = new ObjectMapper();
String json;
try {
json = mapper.writeValueAsString(result);
log.debug("RETURN DATA > json:" + json);
} catch (JsonProcessingException e) {
json = null;
log.error("uploadFilesAjax Error : " + e.toString());
ErrorMessage errorMessage = new ErrorMessage("ERROR", "JSON 변환 처리에 실패하였습니다 : " + e.toString());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(errorMessage);
}
HttpHeaders responseHeaders = new HttpHeaders();
ResponseEntity ret = ResponseEntity.ok().headers(responseHeaders).body(json);
return ret;
}
/**
* 파일 다운로드를 처리한다.
*
* @param params
* @param mv
* @return
* @throws Exception
*/
@RequestMapping(value="/fileupload/downloadAttachFile.do")
public ModelAndView downloadAttachFile(HttpServletRequest request, AttachFileVO attachFileVO, ModelAndView mv) throws Exception {
//---------------------------------
// 권한체크
//---------------------------------
// 공지사항, FAQ : 모두 공개
// QnA : 공개된 글인 경우, 모두 공개
// QnA : 비밀글 (본인에 한정)
attachFileVO.setMbInfoId(getMbInfoId(request));
boolean hasAuth = attachFileService.checkAttachFileDownload(attachFileVO);
if(!hasAuth) {
throw new Exception("잘못된 접근입니다. 파일다운로드를 할 수 있는 권한이 없습니다.");
}
AttachFileVO retAttachFileVO = attachFileService.selectAttachFile(attachFileVO);
if(retAttachFileVO == null || StringUtil.isEmpty(retAttachFileVO.getAttachFileId())) {
throw new Exception("잘못된 접근이므로 파일다운로드를 할 수 없습니다.");
}
if(StringUtil.isEmpty(retAttachFileVO.getFileStrePath()) || StringUtil.isEmpty(retAttachFileVO.getStreFileNm())) {
throw new Exception("파일정보가 올바르지 않습니다.");
}
if(StringUtil.isEmpty(retAttachFileVO.getOrignlFileNm())) {
retAttachFileVO.setOrignlFileNm("첨부파일." + retAttachFileVO.getFileExt());
}
if(StringUtil.isEmpty(retAttachFileVO.getOrignlFileNm())) {
retAttachFileVO.setOrignlFileNm("첨부파일." + retAttachFileVO.getFileExt());
}
String fullPath = retAttachFileVO.getFileStrePath() + retAttachFileVO.getStreFileNm();
log.debug("downloadAttachFile > fullPath = " + fullPath);
if(FileUtil.isNotValid(fullPath)) {
throw new Exception(MSG_NOT_VALID_FILE_PATH);
}
File file = new File(FileUtil.filePathBlackList(fullPath));
if(!file.isFile()) {
throw new Exception("해당 파일이 존재하지 않습니다. 관리자에게 문의하여 주시기 바랍니다.");
}
mv.setViewName("downloadView"); // dispatcher-servlet.xml내 BeanNameViewResolver 정의
mv.addObject("downloadFile", file);
mv.addObject("fname", retAttachFileVO.getOrignlFileNm());
return mv;
}
}

View File

@ -0,0 +1,84 @@
package nlib.cmm.interceptor;
import java.util.HashMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import nlib.cmm.service.NlibProperty;
import nlib.user.service.LoginService;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : NlibInterceptor.java
*
* @Description : 소장자료관 인터셉터로써 지방문화원 접속 정보를 세션에 저장 처리
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 8. 31. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 8. 31.
* @version 1.0
*
*/
public class NlibInterceptor extends HandlerInterceptorAdapter {
private static final Logger log = LoggerFactory.getLogger(NlibInterceptor.class);
@Resource(name = "loginService")
private LoginService loginService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//---------------------------------------
// 지방문화원 접속 정보를 세션에 담기
//---------------------------------------
HttpSession session = request.getSession();
log.debug("preHandle > sessionid=" + session.getId());
String councilCd = (String)session.getAttribute("councilCd");
String councilNm = (String)session.getAttribute("councilNm");
if(StringUtil.isEmpty(councilCd)) {
// 지방문화원 코드 확인
String councilDnsHost = StringUtil.getHostName(request.getRequestURL().toString());
HashMap<String, String> councilInfoMap = loginService.selectCouncilInfoByDnsHost(councilDnsHost);
if(councilInfoMap == null || councilInfoMap.size() < 1) {
log.error("preHandle > [오류] 등록되지 않은 도메인입니다. 지방문화원 정보에 도메인 호스트명을 등록해 주시기 바랍니다. : " + councilDnsHost);
log.error("preHandle > [오류] 도메인이 등록되지 않음에 따라 Default 도메인으로 등록되나, 로그인/회원가입 및 기타 서비스 이용시 문제 발생할 수 있습니다. " + NlibProperty.getString("nlib.council.cd") + ", " + NlibProperty.getString("nlib.council.nm"));
councilCd = null;
councilNm = null;
} else {
councilCd = councilInfoMap.get("councilCd");
councilNm = councilInfoMap.get("councilNm");
}
if(StringUtil.isEmpty(councilCd)) councilCd = NlibProperty.getString("nlib.council.cd");
if(StringUtil.isEmpty(councilNm)) councilNm = NlibProperty.getString("nlib.council.nm");
if(StringUtil.isEmpty(councilDnsHost)) councilDnsHost = NlibProperty.getString("nlib.council.dns.host");
session.setAttribute("councilCd" , councilCd);
session.setAttribute("councilNm" , councilNm);
session.setAttribute("councilDnsHost", councilDnsHost);
}
return true;
}
}

View File

@ -0,0 +1,169 @@
package nlib.cmm.qrcode;
import java.awt.image.BufferedImage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import egovframework.com.utl.sim.service.EgovFileScrty;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : QRCodeUtil.java
*
* @Description : QR 코드 생성 처리
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* --------------------------------------------------------
* 참고 : 바코드 정보
* --------------------------------------------------------
* [Universal Product Code : UPC] : 1D 바코드
* - UPC-A : 12자리 (6자리 제조사ID번호 + 5자리품목번호 + 1자리 체크 숫자)
* - UPC-E : 8자리 (주로 작은 패키지용으로 사용)
*
* [European Article Number : EAN Codes]
* - EAN-13(Most commonly), EAN-8, JAN-13, ISBN
* - EAN-13 : UPC 코드와 유사, "o" + UPC-A코드
*
* [Code 128]
* - 함축 고밀도 선형 코드로, 물류/배송에서 주문/유통 목적으로 주로 사용
* - 아스키 128자 인코딩 가능
*
* [PDF417]
* - 다중 1D 바코드가 다른 1D 바코드위에 쌓여서 구성되는 선형 바코드
* - 일반적인 선형 바코드기기 사용 가능
* - 여행 승차권,ID카드,물품목록 관리용으로 사용
* - 체크숫자 대신 Reed-Solomon 오류 교정 방식 사용
*
* [QR Codes : Quick Response Code]
* - 바코드 매트릭스 ,2D 바코드로 가장 많이 쓰여지고 있는 바코드
* - 제한된 공간에 많은 양의 정보를 담을 있음
*
* 라이브러리
* - Barbecue : 오픈소스 자바 라이브러리, 1D바코드, PNG/GIF/JPEG/SVG 생성 기능
* - Barcode4j : 오픈소스 라이브러리, 2D바코드 포멧 지원, DataMarix, PDF417
* - ZXing(Zebra Crossing) : 오픈소스, 자바로 구현된 멀티포멧 1D/2D바코드 이미지 처리 라이브러리, QR코드 지원하는 자바 라이브러리 (본시스템에서 사용하는 LIB)
* - QRGen : ZXing을 사용한 간단한 자바 QR코드 생성 API
*
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 6. 25. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 6. 25.
* @version 1.0
*
*/
@Service("qrCodeService")
public class QRCodeUtil {
private static final Logger log = LoggerFactory.getLogger(QRCodeUtil.class);
/**
* QR코드로 생성할 있는 최대문자열 바이트 길이
*
* QR코드로 생성할 있는 코드값은 다음과 같으나, 시스템 용도에 충분한 크기인 "2000"자로 크기를 제한한다.
*
* - Numeric only Max. 7,089 characters (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
* - Alphanumeric Max. 4,296 characters (09, AZ [upper-case only], space, $, %, *, +, -, ., /, :)
* - Binary/byte Max. 2,953 characters (8-bit bytes) (23624 bits)
*/
public static final int MAX_QRTEXT_BYTES = 2000;
/**
* 입력된 문자열에 대한 QR 2D 바코드를 BufferedImage 생성하여 리턴한다.
*
*
* @param barcodeText
* @return
* @throws Exception
*/
public static BufferedImage generateQRCodeImageByZxing(String barcodeText) throws Exception {
if(StringUtil.isEmpty(barcodeText)) {
throw new Exception("QR 2D바코드로 생성할 문자 정보가 없습니다.");
}
if(barcodeText.getBytes().length > MAX_QRTEXT_BYTES) {
throw new Exception(String.format("QR 2D바코드로 생성할 문자의 길이는 %d 바이트를 초과할 수 없습니다.", MAX_QRTEXT_BYTES));
}
QRCodeWriter barcodeWriter = new QRCodeWriter();
BitMatrix bitMatrix = barcodeWriter.encode(barcodeText, BarcodeFormat.QR_CODE, 200, 200);
return MatrixToImageWriter.toBufferedImage(bitMatrix);
}
/**
* 사용자정보를 가지고, QRCode 바코드를 BufferedImage 생성하여 리턴한다.
*
* (1) "사용자고유번호;이메일;이름;" 형식으로 문자열을 구성
* (2) 앞의 (1) 문자열을 암호화 처리
* (3) 앞의 (2) 암호화 문자열로 QRCode 생성하여 BufferedImage형식으로 리턴
*
* @param loginVO
* @return
* @throws Exception
*/
public static BufferedImage generateMemberQrcodeImage(NlibLoginVO loginVO) throws Exception {
if(loginVO == null) {
throw new Exception("QR 2D바코드로 생성할 사용자 정보가 없습니다.");
}
if(StringUtil.isEmpty(loginVO.getMbNo())) {
throw new Exception("QR 2D바코드로 생성에 필요한 회원번호 정보가 없습니다.");
}
return generateQRCodeImageByZxing(loginVO.getMbNo());
}
/**
* 사용자 QR코드 추출 정보를 통해 사용자정보VO를 생성하여 리턴한다.
*
* @param encodedBarcodeText
* @return
* @throws Exception
*/
public static NlibLoginVO getMemberInfoFromQRCode(String encodedBarcodeText) throws Exception {
if(StringUtil.isEmpty(encodedBarcodeText)) {
throw new Exception("사용자 QR코드 추출 정보가 정보가 없습니다.");
}
log.debug("getMemberInfoFromQRCode : encodedBarcodeText=" + encodedBarcodeText);
String barcodeText = new String(EgovFileScrty.decodeBinary(encodedBarcodeText));
log.debug("getMemberInfoFromQRCode : decodedBarcodeText=" + barcodeText);
String[] split = barcodeText.split(";");
if(split.length < 3) {
throw new Exception("사용자 QR코드 추출 정보가 적합하지 않습니다.");
}
NlibLoginVO info = new NlibLoginVO();
info.setMbInfoId(split[0]);
info.setEmail(split[1]);
info.setName(split[2]);
return info;
}
}

View File

@ -0,0 +1,54 @@
package nlib.cmm.service;
import java.util.List;
import java.util.Map;
/**
* <pre>
* @Class Name : CodeService.java
*
* @Description : 코드 조회 공통 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 26. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 26.
* @version 1.0
*
*/
public interface CodeService
{
/**
* 공통코드를 조회한다.
*
* @param iCodeId
* @return
* @throws Exception
*/
public List<Map<String, String>> listCodes(String iCodeId) throws Exception;
/**
* 주제분류코드를 조회한다.
*
* @return
* @throws Exception
*/
public List<Map<String, String>> listCtClsfs() throws Exception;
/**
* 자료유형 최상위 코드목록을 조회한다.
*/
public List<Map<String, String>> listTypeDivCodes() throws Exception;
}

View File

@ -0,0 +1,106 @@
package nlib.cmm.service;
import java.util.List;
import java.util.Map;
import nlib.col.service.CollectionVO;
/**
* <pre>
* @Class Name : MainService.java
*
* @Description : 메인화면 서비스 인터페이스 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 01. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 01.
* @version 1.0
*
*/
public interface MainService
{
/**
* 지역문화원의 키워드 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<Map<String, String>> listKeywords(String mngOrgCd);
/**
* 문화원 PICK한 자료 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listOrgPicks(String mngOrgCd);
/**
* 유형별인기자료 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listPops(CollectionVO searchVO);
/**
* 유형별인기자료 리스트를 조회한다. : 기본 자료유형 문서로 검색
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listPops(String mngOrgCd);
/**
* 유형별인기자료 리스트를 조회한다.
*
* @param mngOrgCd
* @param typeDivCd
* @return
*/
public List<CollectionVO> listPops(String mngOrgCd, String typeDivCd);
/**
* 온라인자료관 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listOnline(String mngOrgCd);
/**
* 지방문화원별 배너 정보를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<Map<String, String>> listBannerInfos(String mngOrgCd);
/**
* 메인화면 배너ID에 대한 정보를 가져온다.
*
* @return
*/
public Map<String, String> getBannerInfo(String bannerId);
/**
* 메인화면 footer 문화원 전체 이름을 가져온다.
*
* @return
*/
public List<Map<String, String>> listDeptTree(String mngOrgNm);
}

View File

@ -0,0 +1,173 @@
package nlib.cmm.service;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : NlibProperty.java
*
* @Description : NLIB용 프로퍼티 파일을 읽어서 메모리에 로딩하고 관리하는 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 16.
* @version 1.0
*
*/
@Service("nlibProperty")
public class NlibProperty {
private static final Logger log = LoggerFactory.getLogger(NlibProperty.class);
/**
* 메모리에 로딩될 프로퍼티 객체 선언
*/
public static Properties properties = null;
/**
* nlib.properties 파일로 부터 속성을 읽어 들인다.
*
* @return 정상적으로 로딩한 건수를 리턴한다. 오류 발생 , 음수값이 리턴된다.
*/
public static int loadProperties() {
String nlibPropPath = null;
int propCount = -1;
if(properties == null) properties = new Properties();
else properties.clear();
nlibPropPath = NlibProperty.class.getResource("").getPath();
nlibPropPath = nlibPropPath.substring(0, nlibPropPath.lastIndexOf("/nlib/") + 6) + "nlib.properties";
log.debug("NLIB Properties File Path : " + nlibPropPath);
try (InputStream input = new FileInputStream(nlibPropPath)) {
properties.load(input);
Enumeration<String> propEnum = (Enumeration<String>)properties.propertyNames();
String propName = null;
while(propEnum.hasMoreElements()) {
propName = propEnum.nextElement();
log.debug("Loading NLIB Properties : " + propName + " = " + properties.getProperty(propName));
}
log.debug("Loading is Done!");
propCount = properties.size();
} catch (FileNotFoundException ex) { // FileNotFoundException
if(properties != null) properties.clear();
log.error("Error in Loading NLIB Properties FileNotFoundException : " + nlibPropPath);
return -2;
} catch (IOException ex) { // FileNotFoundException
if(properties != null) properties.clear();
log.error("Error in Loading NLIB Properties : IOException " + nlibPropPath);
return -3;
}
return propCount;
}
/**
* name 값을 키로하는 속성값을 리턴한다.
*
* @param name
* @return
*/
public static String getProperty(String name) {
if(properties == null || properties.size() < 1) {
if(loadProperties() < 0) return null;
}
String value = properties.getProperty(name);
if(value != null) value = value.trim();
return value;
}
/**
* name 값을 키로하는 속성값을 문자열 형태로 리턴한다. (getProperty(..) 동일)
*
* @param name
* @return
*/
public static String getString(String name) {
return getProperty(name);
}
public static String getString(String name, String defaultValue) {
String val = getProperty(name);
if(StringUtil.isEmpty(val)) return defaultValue;
return val;
}
/**
* name 값을 키로하는 속성값을 정부형태로 리턴한다.
* 만일 값이 부재이거나 정부값으로 적합하지 않을 경우, defaultValue를 리턴한다.
*
* @param name
* @param defaultValue
* @return
*/
public static int getInt(String name, int defaultValue) {
try {
return getInt(name);
} catch(NumberFormatException e) {
log.error("[속성값 읽기 오류] NumberFormatException : " + e.toString());
return defaultValue;
} catch(Exception e) {
log.error("[속성값 읽기 오류] 기타 오류 " + e.toString());
return defaultValue;
}
}
/**
* name 값을 키로하는 속성값을 정부형태로 리턴한다.
*
* @param name
* @return
* @throws Exception
*/
public static int getInt(String name) throws Exception {
if(StringUtil.isEmpty(name)) {
throw new Exception("속성값의 명칭 정보가 부적합합니다.");
}
String val = getProperty(name);
if(StringUtil.isEmpty(val)) {
throw new Exception("해당 속성값이 존재하지 않습니다.");
}
return Integer.parseInt(val.trim());
}
}

View File

@ -0,0 +1,72 @@
package nlib.cmm.service;
import java.util.List;
/**
* <pre>
* @Class Name : NotificationService.java
*
* @Description : 알림관련 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021 09. 06. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021 09. 06.
* @version 1.0
*
*/
public interface NotificationService
{
/*
* 사용자 알림 목록을 조회한다.
*/
public List<NotificationVO> listNotifications(NotificationVO notificationVO) throws Exception;
/**
* 사용자 알림 목록의 건수를 조회한다.
*/
public int countNotifications(String recvUserId) throws Exception;
/**
* 읽지 않은 알림 건수를 조회한다.
*
* @param mbInfoId
* @return
* @throws Exception
*/
public int countUnreadNotification(String mbInfoId) throws Exception;
/**
* 알림을 읽음으로 변경한다.
* 만일, 이미 읽음표시된 경우에는 변경 없다.
*
* @param notiVO (notiId, recvUserId 필수)
* @return
* @throws Exception
*/
public int updateRead(NotificationVO notiVO) throws Exception;
/**
* 알림내용 상세 조회
*
* @param notiVO (notiId, recvUserId 필수)
* @return
* @throws Exception
*/
public NotificationVO selectNotification(NotificationVO notiVO) throws Exception;
}

View File

@ -0,0 +1,136 @@
package nlib.cmm.service;
/**
* <pre>
* @Class Name : NotificationVO.java
*
* @Description : 알림 정보 VO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021 09. 06. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021 09. 06.
* @version 1.0
*
*/
public class NotificationVO extends PagingVO {
private String notiId; /* 알림ID */
private String title; /* 알림제목 */
private String content; /* 알림내용 */
private String notiMethod; /* 알림방법 */
private String notiTypeCd; /* 알림유형코드(알림내용구분코드) */
private String notiTypeNm; /* 알림유형코드명 */
private String readDd; /* 알림확인일시 */
private String RegId; /* 등록자아이디 */
private String regDd; /* 등록일자 */
private String recvUserId; /* 알림대상자 회원아이디 */
private String readYn; /* 알림확인여부 */
private int totCnt = 0; /* 알림건수(최근1개월) */
private int rno = 0; /* 행번호 */
private String mngOrgCd; /* 관리문화원코드 */
private String mngOrgNm; /* 관리문화원명 */
public String getNotiId() {
return notiId;
}
public void setNotiId(String notiId) {
this.notiId = notiId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getNotiMethod() {
return notiMethod;
}
public void setNotiMethod(String notiMethod) {
this.notiMethod = notiMethod;
}
public String getNotiTypeCd() {
return notiTypeCd;
}
public void setNotiTypeCd(String notiTypeCd) {
this.notiTypeCd = notiTypeCd;
}
public String getReadDd() {
return readDd;
}
public void setReadDd(String readDd) {
this.readDd = readDd;
}
public String getRegId() {
return RegId;
}
public void setRegId(String regId) {
RegId = regId;
}
public String getRegDd() {
return regDd;
}
public void setRegDd(String regDd) {
this.regDd = regDd;
}
public String getRecvUserId() {
return recvUserId;
}
public void setRecvUserId(String recvUserId) {
this.recvUserId = recvUserId;
}
public int getTotCnt() {
return totCnt;
}
public void setTotCnt(int totCnt) {
this.totCnt = totCnt;
}
public String getReadYn() {
return readYn;
}
public void setReadYn(String readYn) {
this.readYn = readYn;
}
public String getNotiTypeNm() {
return notiTypeNm;
}
public void setNotiTypeNm(String notiTypeNm) {
this.notiTypeNm = notiTypeNm;
}
public int getRno() {
return rno;
}
public void setRno(int rno) {
this.rno = rno;
}
public String getMngOrgCd() {
return mngOrgCd;
}
public void setMngOrgCd(String mngOrgCd) {
this.mngOrgCd = mngOrgCd;
}
public String getMngOrgNm() {
return mngOrgNm;
}
public void setMngOrgNm(String mngOrgNm) {
this.mngOrgNm = mngOrgNm;
}
}

View File

@ -0,0 +1,172 @@
package nlib.cmm.service;
/**
* <pre>
* @Class Name : PagingVO.java
*
* @Description : 페이지 정보 VO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 09. 06. KNKIM 최초 생성
* @ 2021. 10. 01. JSYOO 화면 페이징 공통 모듈 개발
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 09. 06.
* @version 1.0
*
*/
public class PagingVO {
public final int DEFAULT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10);
private int pageIndex = 1; /* 페이지 번호 */
private int pageSize = DEFAULT_PAGE_SIZE; /* 페이지 크기 (1페이지당 보여줄 자료건수) */
private int totRecordCount = 0; /* 총건수 */
private int pageStart = 0; /* 시작번호 (쿼리 limit용)*/
private int startPage = 0; /* 시작페이지 */
private int endPage = 0; /* 현재 노출페이지중 마지막 페이지 (ex << < 1 2 3 4 5 > >> 중 5 ) */
private int lastPage = 0; /* 마지막페이지 */
private int cntPage = DEFAULT_PAGE_SIZE; /* 페이지 네비게이션에 표시되는 페이지 개수 (ex) << < 1 2 3 4 5 > >> */
public int getStartPage() {
return startPage;
}
public int getCntPage() {
return cntPage;
}
public void setCntPage(int cntPage) {
this.cntPage = cntPage;
}
public void setStartPage(int startPage) {
this.startPage = startPage;
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int endPage) {
this.endPage = endPage;
}
public int getLastPage() {
return lastPage;
}
public void setLastPage(int lastPage) {
this.lastPage = lastPage;
}
public int getPageStart() {
return pageStart;
}
public void setPageStart(int pageStart) {
this.pageStart = pageStart;
}
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
if(pageIndex < 1) pageIndex = 1;
else this.pageIndex = pageIndex;
}
public void setPageIndex(String sPageIndex) {
try {
pageIndex = Integer.parseInt(sPageIndex);
} catch(NumberFormatException e) {
pageIndex = 1;
}
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
if(pageSize < 1) pageSize = DEFAULT_PAGE_SIZE;
else this.pageSize = pageSize;
}
public void setPageSize(String sPageSize) {
try {
pageSize = Integer.parseInt(sPageSize);
} catch(NumberFormatException e) {
pageSize = NlibProperty.getInt("list.paging.page.size", 10);
}
}
public int getTotRecordCount() {
return totRecordCount;
}
public void setTotRecordCount(int totRecordCount) {
this.totRecordCount = totRecordCount;
}
public int getPageStartRowNum() {
if(pageIndex < 1) pageIndex = 1;
if(pageSize < 1) pageSize = 10;
return ((pageIndex - 1) * pageSize);
}
public void setPagingVO(int totRecordCount, int pageIndex, int pageSize) {
setPageIndex(pageIndex);
// 현재 페이지
setPageSize(pageSize);
// 페이지 게시글수
setTotRecordCount(totRecordCount);
// 게시글 갯수
calcLastPage(totRecordCount, pageSize);
// 제일 마지막 페이지 계산
// 시작 페이지 계산 - 아래.
calcStartEndPage(pageIndex, cntPage);
setPageStart(pageIndex, pageSize);
}
// 제일 마지막 페이지 계산
public void calcLastPage(int totRecordCount, int pageSize) {
setLastPage((int) Math.ceil((double) totRecordCount / (double) pageSize));
}
// 시작, 페이지 계산
public void calcStartEndPage(int pageIndex, int cntPage) {
setEndPage(((int) Math.ceil((double) pageIndex / (double) cntPage)) * cntPage);
if (getLastPage() < getEndPage()) {
setEndPage(getLastPage());
}
if (getTotRecordCount() > 0) {
if (getEndPage() % cntPage == 0) {
setStartPage(1 + (getEndPage() / cntPage - 1) * cntPage);
} else {
setStartPage(getEndPage() / cntPage * cntPage + 1);
}
}
if (getStartPage() < 1) {
setStartPage(1);
}
}
// DB 쿼리에서 사용할 start값 계산
public void setPageStart(int pageIndex, int pageSize) {
this.pageStart = ((pageIndex - 1) * pageSize);
}
}

View File

@ -0,0 +1,54 @@
package nlib.cmm.service.impl;
import java.util.List;
import java.util.Map;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
/**
* <pre>
* @Class Name : CodeDAO.java
*
* @Description : 공통코드 조회 DAO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 27. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 27.
* @version 1.0
*
*/
@Mapper("codeDAO")
public interface CodeDAO {
/**
* 공통코드를 조회한다.
*
* @param iCodeId
* @return
* @throws Exception
*/
public List<Map<String, String>> listCodes(String iCodeId) throws Exception;
/**
* 주제분류코드를 조회한다.
*
* @return
* @throws Exception
*/
public List<Map<String, String>> listCtClsfs() throws Exception;
/**
* 자료유형 최상위 코드목록을 조회한다.
*/
public List<Map<String, String>> listTypeDivCodes() throws Exception;
}

View File

@ -0,0 +1,75 @@
package nlib.cmm.service.impl;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import egovframework.rte.fdl.cmmn.EgovAbstractServiceImpl;
import nlib.cmm.service.CodeService;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : CodeServiceImpl.java
*
* @Description : 코드 조회 공통 서비스 구현
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 26. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 26.
* @version 1.0
*
*/
@Service("codeService")
public class CodeServiceImpl extends EgovAbstractServiceImpl implements CodeService
{
private static final Logger log = LoggerFactory.getLogger(CodeServiceImpl.class);
@Resource(name="codeDAO")
private CodeDAO codeDAO;
/**
* 공통코드를 조회한다.
*
* @param iCodeId
* @return
* @throws Exception
*/
public List<Map<String, String>> listCodes(String iCodeId) throws Exception {
if(StringUtil.isEmpty(iCodeId)) return null;
return codeDAO.listCodes(iCodeId.toUpperCase());
}
/**
* 주제분류코드를 조회한다.
*
* @return
* @throws Exception
*/
public List<Map<String, String>> listCtClsfs() throws Exception {
return codeDAO.listCtClsfs();
}
/**
* 자료유형 최상위 코드목록을 조회한다.
*/
public List<Map<String, String>> listTypeDivCodes() throws Exception {
return codeDAO.listTypeDivCodes();
}
}

View File

@ -0,0 +1,66 @@
package nlib.cmm.service.impl;
import java.util.List;
import java.util.Map;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
import nlib.col.service.CollectionVO;
@Mapper("mainDAO")
public interface MainDAO {
/**
* 지역문화원의 키워드 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<Map<String, String>> listKeywords(String mngOrgCd);
/**
* 문화원 PICK한 자료 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listOrgPicks(String mngOrgCd);
/**
* 유형별인기자료 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listPops(CollectionVO searchVO);
/**
* 온라인자료관 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listOnline(String mngOrgCd);
/**
* 지방문화원별 배너 정보를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<Map<String, String>> listBannerInfos(String mngOrgCd);
/**
* 메인화면 배너ID에 대한 정보를 가져온다.
*
* @return
*/
public Map<String, String> getBannerInfo(String bannerId);
/**
* 메인화면 footer 문화원 전체 이름을 가져온다.
*
* @return
*/
public List<Map<String, String>> listDeptTree(String mngOrgNm);
}

View File

@ -0,0 +1,142 @@
package nlib.cmm.service.impl;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import nlib.cmm.service.MainService;
import nlib.col.service.CollectionVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : MainServiceImpl.java
*
* @Description :
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 07. 01. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 07. 01.
* @version 1.0
*
*/
@Service("mainService")
public class MainServiceImpl implements MainService
{
private static final Logger log = LoggerFactory.getLogger(MainServiceImpl.class);
@Resource(name="mainDAO")
private MainDAO mainDAO;
/**
* 지역문화원의 키워드 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<Map<String, String>> listKeywords(String mngOrgCd) {
return mainDAO.listKeywords(mngOrgCd);
}
/**
* 문화원 PICK한 자료 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listOrgPicks(String mngOrgCd) {
return mainDAO.listOrgPicks(mngOrgCd);
}
/**
* 유형별인기자료 리스트를 조회한다. : 기본 자료유형 문서로 검색
*
* @param searchVO
* @return
*/
public List<CollectionVO> listPops(CollectionVO searchVO) {
return mainDAO.listPops(searchVO);
}
/**
* 유형별인기자료 리스트를 조회한다. : 기본 자료유형 문서로 검색
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listPops(String mngOrgCd) {
CollectionVO searchVO = new CollectionVO();
searchVO.setMngOrgCd(mngOrgCd);
searchVO.setTypeDivCd("IT_DOC"); // 문서
return listPops(mngOrgCd, null);
}
/**
* 유형별인기자료 리스트를 조회한다.
*
* @param mngOrgCd
* @param typeDivCd
* @return
*/
public List<CollectionVO> listPops(String mngOrgCd, String typeDivCd) {
CollectionVO searchVO = new CollectionVO();
searchVO.setMngOrgCd(mngOrgCd);
if(StringUtil.isEmpty(typeDivCd)) typeDivCd = "IT_DOC";
searchVO.setTypeDivCd(typeDivCd);
return listPops(searchVO);
}
/**
* 온라인자료관 리스트를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<CollectionVO> listOnline(String mngOrgCd) {
return mainDAO.listOnline(mngOrgCd);
}
/**
* 지방문화원별 배너 정보를 조회한다.
*
* @param mngOrgCd
* @return
*/
public List<Map<String, String>> listBannerInfos(String mngOrgCd) {
return mainDAO.listBannerInfos(mngOrgCd);
}
/**
* 메인화면 배너ID에 대한 정보를 가져온다.
*
* @return
*/
public Map<String, String> getBannerInfo(String bannerId) {
return mainDAO.getBannerInfo(bannerId);
}
@Override
public List<Map<String, String>> listDeptTree(String mngOrgNm) {
return mainDAO.listDeptTree(mngOrgNm);
}
}

View File

@ -0,0 +1,90 @@
package nlib.cmm.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Repository;
import egovframework.com.cmm.service.impl.EgovComAbstractDAO;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
import nlib.cmm.service.NotificationVO;
import nlib.cmm.service.NlibProperty;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : NotificationDAO.java
*
* @Description : 알림 정보 제공 DAO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 27. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 27.
* @version 1.0
*
*/
@Repository("notificationDAO")
public class NotificationDAO extends EgovComAbstractDAO {
/*
* 사용자 알림 목록을 조회한다.
*/
public List<NotificationVO> listNotifications(NotificationVO searchNotificationVO) throws Exception {
return selectList("NotificationDAO.listNotifications", searchNotificationVO);
}
/**
* 사용자 알림 목록의 건수를 조회한다.
*/
public int countNotifications(String recvUserId) throws Exception {
return selectOne("NotificationDAO.countNotifications", recvUserId);
}
/*
* 사용자가 확인하지 않은 알림 건수를 조회한다.
*/
public int countUnreadNotification(String recvUserId) throws Exception {
return selectOne("NotificationDAO.countUnreadNotification", recvUserId);
}
/**
* 알림을 읽음으로 변경한다.
* 만일, 이미 읽음표시된 경우에는 변경 없다.
*
* @param notiVO (notiId, recvUserId 필수)
* @return
* @throws Exception
*/
public int updateRead(NotificationVO notiVO) throws Exception {
return update("NotificationDAO.updateRead", notiVO);
}
/**
* 알림내용 상세 조회
*
* @param notiVO (notiId, recvUserId 필수)
* @return
* @throws Exception
*/
public NotificationVO selectNotification(NotificationVO notiVO) throws Exception {
return selectOne("NotificationDAO.selectNotification", notiVO);
}
}

View File

@ -0,0 +1,93 @@
package nlib.cmm.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import nlib.cmm.service.NotificationService;
import nlib.cmm.service.NotificationVO;
/**
* <pre>
* @Class Name : NotificationServiceImpl.java
*
* @Description : 알림관련 서비스 구현 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021 09. 06. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021 09. 06.
* @version 1.0
*
*/
@Service("notificationService")
public class NotificationServiceImpl implements NotificationService
{
private static final Logger log = LoggerFactory.getLogger(NotificationServiceImpl.class);
@Resource(name="notificationDAO")
private NotificationDAO notificationDAO;
/**
* 사용자 알림 목록을 조회한다.
*/
public List<NotificationVO> listNotifications(NotificationVO notificationVO) throws Exception {
return notificationDAO.listNotifications(notificationVO);
}
/**
* 사용자 알림 목록의 건수를 조회한다.
*/
public int countNotifications(String recvUserId) throws Exception {
return notificationDAO.countNotifications(recvUserId);
}
/**
* 읽지 않은 알림 건수를 조회한다.
*
* @param mbInfoId
* @return
* @throws Exception
*/
public int countUnreadNotification(String recvUserId) throws Exception {
return notificationDAO.countUnreadNotification(recvUserId);
}
/**
* 알림을 읽음으로 변경한다.
* 만일, 이미 읽음표시된 경우에는 변경 없다.
*
* @param notiVO (notiId, recvUserId 필수)
* @return
* @throws Exception
*/
public int updateRead(NotificationVO notiVO) throws Exception {
return notificationDAO.updateRead(notiVO);
}
/**
* 알림내용 상세 조회
*
* @param notiVO (notiId, recvUserId 필수)
* @return
* @throws Exception
*/
public NotificationVO selectNotification(NotificationVO notiVO) throws Exception {
updateRead(notiVO);
return notificationDAO.selectNotification(notiVO);
}
}

View File

@ -0,0 +1,180 @@
package nlib.cmm.session;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import egovframework.com.ext.oauth.service.OAuthUniversalUser;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : SessionConfig.java
*
* @Description : 멀티도메인에서의 로그인 처리를 위해 지방문화원에서 해당 세션에서 로그인처리 가능한 정보를 관리하는 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 8. 25. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 8. 25.
* @version 1.0
*
*/
@WebListener
public class SessionConfig implements HttpSessionListener {
private static final Logger log = LoggerFactory.getLogger(SessionConfig.class);
/* 사용자 정보를 구분하는 구분자 */
private static final String DELIMITER = "\t";
/* 세션별 로그인 처리 가능한 정보 목록 */
private static final Map<String, Object> loginSessions = new ConcurrentHashMap<>();
/* 세션별 회원가입 처리 가능한 정보 목록 */
private static final Map<String, Object> memberSessions = new ConcurrentHashMap<>();
@Override
public void sessionCreated(HttpSessionEvent se) {
log.debug("Session sessionCreated (O) : " + se.getSession().getId());
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
String sessionId = se.getSession().getId();
log.debug("Session sessionDestroyed (X) : " + sessionId);
if(loginSessions.get(sessionId) != null){
removeLoginInfo(sessionId);
}
if(memberSessions.get(sessionId) != null){
removeNewMemberInfo(sessionId);
}
}
/**
* 지방문화원 해당 세션에 로그인 처리 가능한 SNS유형 SNSID 정보를 저장한다.
*
* @param sessionId
* @param snsType
* @param snsId
*/
public static void setLoginInfo(String sessionId, OAuthUniversalUser oUser) {
log.debug("setLoginInfo : " + sessionId + ", " + oUser.getSnsType() + ", " + oUser.getSnsId());
loginSessions.put(sessionId, oUser);
}
/**
* 지방문화원 해당 세션에 로그인 처리 가능한 SNS 유형 SNS ID 정보를 리턴한다.
* 리턴유형 문자열 배열
* [0] : snsType
* [1] : snsId
*
* @param sessionId
* @return
*/
public static OAuthUniversalUser getLoginInfo(String sessionId) {
if(StringUtil.isEmpty(sessionId)) return null;
return (OAuthUniversalUser)loginSessions.get(sessionId);
}
/**
* 지방문화원 해당 세션에 로그인 처리 가능한 SNS 유형 SNS ID 정보를 리턴하고 목록에서 삭제한다.
* 리턴유형 문자열 배열
* [0] : snsType
* [1] : snsId
*
* @param sessionId
* @return
*/
public static OAuthUniversalUser popLoginInfo(String sessionId) {
OAuthUniversalUser ret = getLoginInfo(sessionId);
removeLoginInfo(sessionId);
return ret;
}
/**
* 지방문화원 해당 세션에 로그인 처리 가능한 정보를 삭제한다.
* (로그인 처리 완료 또는 세션 종료 , 삭제)
*
* @param sessionId
* @param snsType
* @param snsId
*/
public static void removeLoginInfo(String sessionId) {
if(StringUtil.isNotEmpty(sessionId)){
loginSessions.remove(sessionId);
log.debug("removeLoginInfo > sessionId = " + sessionId);
}
}
/**
* 지방문화원 해당 세션에 회원가입 처리 가능한 SNS유형 SNS 프로파일 정보를 저장한다.
*
* @param sessionId
* @param snsType
* @param snsId
*/
public static void setNewMemberInfo(String sessionId, OAuthUniversalUser oUser) {
log.debug("setLoginInfo : " + sessionId + ", " + oUser.getSnsId());
memberSessions.put(sessionId, oUser);
}
/**
* 지방문화원 해당 세션에 회원가입 처리 가능한 SNS 유형 SNS 프로파일 정보를 리턴한다.
*
* @param sessionId
* @return
*/
public static OAuthUniversalUser getNewMemberInfo(String sessionId) {
if(StringUtil.isEmpty(sessionId)) return null;
return (OAuthUniversalUser)memberSessions.get(sessionId);
}
/**
* 지방문화원 해당 세션에 회원가입 처리 가능한 SNS 유형 SNS 프로파일 정보를 리턴한다.
*
* @param sessionId
* @return
*/
public static OAuthUniversalUser popNewMemberInfo(String sessionId) {
OAuthUniversalUser ret = getNewMemberInfo(sessionId);
removeNewMemberInfo(sessionId);
return ret;
}
/**
* 지방문화원 해당 세션에 회원가입 처리 가능한 정보를 삭제한다.
* (회원가입 처리 완료 또는 세션 종료 , 삭제)
*
* @param sessionId
* @param snsType
* @param snsId
*/
public static void removeNewMemberInfo(String sessionId) {
if(StringUtil.isNotEmpty(sessionId)){
memberSessions.remove(sessionId);
log.debug("removeNewMemberInfo > sessionId = " + sessionId);
}
}
}

View File

@ -0,0 +1,90 @@
package nlib.cmm.snslogin;
public class GoogleOAuthRequest {
private String redirectUri;
private String clientId;
private String clientSecret;
private String code;
private String responseType;
private String scope;
private String accessType;
private String grantType;
private String state;
private String includeGrantedScopes;
private String loginHint;
private String prompt;
public String getRedirectUri() {
return redirectUri;
}
public void setRedirectUri(String redirectUri) {
this.redirectUri = redirectUri;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getClientSecret() {
return clientSecret;
}
public void setClientSecret(String clientSecret) {
this.clientSecret = clientSecret;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getResponseType() {
return responseType;
}
public void setResponseType(String responseType) {
this.responseType = responseType;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getAccessType() {
return accessType;
}
public void setAccessType(String accessType) {
this.accessType = accessType;
}
public String getGrantType() {
return grantType;
}
public void setGrantType(String grantType) {
this.grantType = grantType;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getIncludeGrantedScopes() {
return includeGrantedScopes;
}
public void setIncludeGrantedScopes(String includeGrantedScopes) {
this.includeGrantedScopes = includeGrantedScopes;
}
public String getLoginHint() {
return loginHint;
}
public void setLoginHint(String loginHint) {
this.loginHint = loginHint;
}
public String getPrompt() {
return prompt;
}
public void setPrompt(String prompt) {
this.prompt = prompt;
}
}

View File

@ -0,0 +1,49 @@
package nlib.cmm.snslogin;
public class GoogleOAuthResponse {
private String accessToken;
private String expiresIn;
private String refreshToken;
private String scope;
private String tokenType;
private String idToken;
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public String getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(String expiresIn) {
this.expiresIn = expiresIn;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public String getTokenType() {
return tokenType;
}
public void setTokenType(String tokenType) {
this.tokenType = tokenType;
}
public String getIdToken() {
return idToken;
}
public void setIdToken(String idToken) {
this.idToken = idToken;
}
}

View File

@ -0,0 +1,52 @@
package nlib.cmm.web;
import java.util.List;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import nlib.cmm.NlibCommonController;
/**
* <pre>
* @Class Name : EncryptorConfigTest.java
*
* @Description : properties 암호화 로그 테스트
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 12. 21. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 12. 21.
* @version 1.0
*
*/
@Controller
public class EncryptorConfigTest {
private static final Logger log = LoggerFactory.getLogger(EncryptorConfigTest.class);
@RequestMapping(value = "/system/EncryptorTest.do")
public String EncryptorTest(String key,String value,ModelMap model) {
StandardPBEStringEncryptor pbeEnc = new StandardPBEStringEncryptor();
pbeEnc.setAlgorithm("PBEWithMD5AndDES");
pbeEnc.setPassword(key); // PBE (XML PASSWORD설정)
log.info("키값 : "+ key + " 암호화할 값 : " + value + " -> 암호화된 값 : " + pbeEnc.encrypt(value));
model.addAttribute("code", "정상");
model.addAttribute("message", "정상적으로 처리되었습니다.");
return "nlib/cmm/common";
}
}

View File

@ -0,0 +1,242 @@
package nlib.cmm.web;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.activation.MimetypesFileTypeMap;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.RequestCache;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.BoardService;
import nlib.bbs.service.QnaService;
import nlib.cmm.NlibCommonController;
import nlib.cmm.service.CodeService;
import nlib.cmm.service.MainService;
import nlib.cmm.service.NlibProperty;
import nlib.cmm.service.NotificationService;
import nlib.cmm.service.PagingVO;
import nlib.col.service.CartService;
import nlib.col.service.CollectionVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : MainController.java
*
* @Description : 메인화면에 표시할 정보를 처리하는 Controller 클래스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 6. 22. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 6. 22.
* @version 1.0
*
*/
@Controller
public class MainController extends NlibCommonController {
private static final Logger log = LoggerFactory.getLogger(MainController.class);
@Resource(name="notificationService")
private NotificationService notificationService;
@Resource(name = "cartService")
private CartService cartService;
@Resource(name = "codeService")
private CodeService codeService;
@Resource(name = "mainService")
private MainService mainService;
@Resource(name = "ancmntService")
private BoardService ancmntService;
@Resource(name = "qnaService")
private QnaService qnaService;
@RequestMapping( {"/index.do"} )
public String setContent(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication,
ModelMap model) throws Exception {
// 캐쉬된 Reqeust 히스토리 삭제
RequestCache cache = new HttpSessionRequestCache();
cache.removeRequest(request, response);
String mngOrgCd = getCurCouncilCd(request);
//------------------------------------------------
// 추천 자료 관련
//------------------------------------------------
// 추천키워드
List<Map<String, String>> listKeywords = mainService.listKeywords(mngOrgCd);
model.addAttribute("listKeywords", listKeywords);
// 문화원 PICK
model.addAttribute("mngOrgNm", getCurCouncilNm(request));
model.addAttribute("listOrgPicks", mainService.listOrgPicks(mngOrgCd));
// 유형별 인기자료
//List<Map<String, String>> listTypeDivCodes = codeService.listTypeDivCodes();
//model.addAttribute("listTypeDivCodes", listTypeDivCodes);
List<CollectionVO> listPops = mainService.listPops(mngOrgCd, null); // 전체
model.addAttribute("listPops", listPops);
// 온라인자료관
model.addAttribute("listOnline", mainService.listOnline(mngOrgCd));
//------------------------------------------------
// 게시판관련
//------------------------------------------------
ArticleVO searchArticleVO = new ArticleVO();
searchArticleVO.setPageIndex(1);
searchArticleVO.setPageSize(3);
searchArticleVO.setMngOrgCd(getCurCouncilCd(request));
// 공지사항
List<ArticleVO> listAncmnt = ancmntService.listArticles(searchArticleVO);
model.addAttribute("listAncmnt", listAncmnt);
// Q&A
String mbInfoId = getMbInfoId(request);
searchArticleVO.setLoginedMbInfoId(mbInfoId);
List<ArticleVO> listQna = qnaService.listArticles(searchArticleVO);
model.addAttribute("listQna", listQna);
// 메인 화면 배너
List<Map<String, String>> listBannerInfos = mainService.listBannerInfos(mngOrgCd);
model.addAttribute("listBannerInfos", listBannerInfos);
return "nlib/cmm/home";
}
@RequestMapping( {"/cmm/headerSubPart.do"} )
public String headerSub(
HttpServletRequest request,
HttpServletResponse response,
Authentication authentication,
ModelMap model) throws Exception {
// 캐쉬된 Reqeust 히스토리 삭제
RequestCache cache = new HttpSessionRequestCache();
cache.removeRequest(request, response);
log.debug((authentication == null ? "손님 메인 접속" : authentication.getName() + " 메인 접속"));
String mbInfoId = getMbInfoId(request);
// 카트 건수 확인
int cartCnt = 0;
if(StringUtil.isEmpty(mbInfoId)) {
cartCnt = cartService.countCartItemsFromCookie(request, response, "1");
cartCnt += cartService.countCartItemsFromCookie(request, response, "2");
} else {
cartCnt = cartService.countCartItems(mbInfoId, "0");
}
// 알림 확인
int unreadNotiCnt = 0;
if(StringUtil.isNotEmpty(mbInfoId)) {
unreadNotiCnt = notificationService.countUnreadNotification(mbInfoId);
}
if(!isAlerted(request)) {
setAlerted(request, true);
}
model.addAttribute("cartCnt", cartCnt);
model.addAttribute("unreadNotiCnt", unreadNotiCnt);
model.addAttribute("docViewUrl", NlibProperty.getString("pdf.url"));
model.addAttribute("videoViewUrl", NlibProperty.getString("video.url"));
model.addAttribute("imageViewUrl", NlibProperty.getString("image.url"));
return "nlib/cmm/headerSubPart";
}
/**
* 목록 조회한다.
*
* @param req
* @return
* @return
*/
@RequestMapping(value="/cmm/listDeptTree.do", method = { RequestMethod.POST })
public String listDeptTree(@RequestParam Map<String, Object> map, ModelMap model) throws Exception {
String mngOrgNm = (String)map.get("mngOrgNm");
// 문화원명 조회
List<Map<String, String>> listDeptTree = mainService.listDeptTree(mngOrgNm);
model.addAttribute("listDeptTree", listDeptTree);
return "nlib/cmm/footerSubPart";
}
@RequestMapping(value = "/main/bannerImage.do")
public void getBannerImage(HttpServletRequest request, HttpServletResponse response, String atchFileId) throws IOException {
Map<String, String> bannerInfo = mainService.getBannerInfo(atchFileId);
boolean exists = false;
if(bannerInfo != null && StringUtil.isNotEmpty(bannerInfo.get("fileStrePath")) && StringUtil.isNotEmpty(bannerInfo.get("streFileNm")) && StringUtil.isNotEmpty(bannerInfo.get("orignlFileNm"))) {
try {
String fileName = bannerInfo.get("fileStrePath") + bannerInfo.get("streFileNm");
MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
response.setContentType(mimetypesFileTypeMap.getContentType(bannerInfo.get("orignlFileNm")));
response.getOutputStream().write(Files.readAllBytes(Paths.get(fileName)));
exists = true;
} catch(IOException e) {
log.error("메인 화면 배너 관련 파일을 확인할 수 없습니다. : bannerId=" + atchFileId);
}
}
if(!exists) {
try {
String fileName = NlibProperty.getString("main.banner.img.path");
MimetypesFileTypeMap mimetypesFileTypeMap = new MimetypesFileTypeMap();
response.setContentType(mimetypesFileTypeMap.getContentType(bannerInfo.get("orignlFileNm")));
response.getOutputStream().write(Files.readAllBytes(Paths.get(fileName)));
exists = true;
} catch(IOException e) {
log.error("메인 화면 배너 기본 배너 파일을 확인할 수 없습니다. : main.banner.img.path=" + NlibProperty.getString("main.banner.img.path"));
}
}
return;
}
}

View File

@ -0,0 +1,189 @@
package nlib.cmm.web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import nlib.cmm.NlibCommonController;
import nlib.cmm.service.NotificationService;
import nlib.cmm.service.NotificationVO;
import nlib.cmm.service.PagingVO;
import nlib.cmm.service.NlibProperty;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : NotificationController.java
*
* @Description : 사용자 홈페이지 알림 안내 컨트롤러
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 6. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 6.
* @version 1.0
*
*/
@Controller
public class NotificationController extends NlibCommonController {
private static final Logger log = LoggerFactory.getLogger(NotificationController.class);
static final int DEFUALT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10);
@Resource(name="notificationService")
private NotificationService notificationService;
/**
* 알림 목록 화면을 표시한다.
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping("/cmm/listNotifications.do")
public String listNotifications(
HttpServletRequest req,
@RequestParam Map<String, String> paramMap,
ModelMap model
) throws Exception {
String mbInfoId = getMbInfoId(req);
int pageIndex = StringUtil.toNumber(paramMap.get("pageIndex"), 1);
int pageSize = StringUtil.toNumber(paramMap.get("pageSize"), DEFUALT_PAGE_SIZE);
log.debug("listNotifications > pageIndex = " + pageIndex);
log.debug("listNotifications > pageSize = " + pageSize);
NotificationVO searchNotificationVO = new NotificationVO();
searchNotificationVO.setPageIndex(pageIndex);
searchNotificationVO.setPageSize(pageSize);
searchNotificationVO.setRecvUserId(mbInfoId);
List<NotificationVO> list = notificationService.listNotifications(searchNotificationVO);
int totRecordCount = (list == null) ? 0 : list.size();
searchNotificationVO.setTotRecordCount(totRecordCount);
model.addAttribute("notificationList", list);
model.addAttribute("searchNotificationVO", searchNotificationVO);
model.addAttribute("pageSize", pageSize);
model.addAttribute("pageIndex", pageIndex);
return "nlib/cmm/listNotifications";
}
/**
* 알림 목록 조회한다.
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping(value="/cmm/listNotificationsAjax.do")
public ResponseEntity<String> listNotificationsAjax(HttpServletRequest req,
Authentication authentication, @RequestBody(required = false) Map<String, String> paramMap) throws Exception {
String mbInfoId = getMbInfoId(req);
if(paramMap == null) paramMap = new HashMap<String, String>();
int pageIndex = StringUtil.toNumber(paramMap.get("pageIndex"), 1);
int pageSize = StringUtil.toNumber(paramMap.get("pageSize"), DEFUALT_PAGE_SIZE);
log.debug("listNotificationsAjax > pageIndex = " + pageIndex);
log.debug("listNotificationsAjax > pageSize = " + pageSize);
NotificationVO searchNotificationtVO = new NotificationVO();
searchNotificationtVO.setPageIndex(pageIndex);
searchNotificationtVO.setPageSize(pageSize);
searchNotificationtVO.setRecvUserId(mbInfoId);
List<NotificationVO> list = notificationService.listNotifications(searchNotificationtVO);
int totRecordCount = notificationService.countNotifications(mbInfoId);
//-------------------------------
// JSON변환 응답 처리
//-------------------------------
// JS-GRID 페이징 처리를 포함한 응답값 처리
// {data: [{...}],
// itemsCount: 255
// }
HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", list);
retMap.put("itemsCount", totRecordCount);
PagingVO pageVO = new PagingVO();
pageVO.setPagingVO(totRecordCount, pageIndex, pageSize);
retMap.put("pagingPageIndex" , pageVO.getPageIndex());
retMap.put("pagingTotRecordCount", pageVO.getTotRecordCount());
retMap.put("pagingStartPage" , pageVO.getStartPage());
retMap.put("pagingEndPage" , pageVO.getEndPage());
retMap.put("pagingLastPage" , pageVO.getLastPage());
return makeResponseEntityJson(retMap);
}
/**
* 알림 상세 내용 조회한다.
*
* @param req
* @return
*/
@Secured("ROLE_USER")
@RequestMapping("/cmm/selectNotificationAjax.do")
public ResponseEntity<String> selectNotificationAjax(HttpServletRequest req, Authentication authentication, @RequestBody Map<String, String> paramMap) throws Exception {
String notiId = paramMap.get("notiId"); // 알림ID
String pageIndex = paramMap.get("pageIndex");
String pageSize = paramMap.get("pageSize");
log.debug("selectNotificationAjax > notiId = " + notiId);
NotificationVO paramNotiVO = new NotificationVO();
paramNotiVO.setNotiId(notiId);
paramNotiVO.setRecvUserId(getMbInfoId(req));
paramNotiVO.setPageIndex(pageIndex);
paramNotiVO.setPageSize(pageSize);
// 읽음처리 상세내용 조회
NotificationVO notiVO = notificationService.selectNotification(paramNotiVO);
//-------------------------------
// JSON변환 응답 처리
//-------------------------------
// JS-GRID 페이징 처리를 포함한 응답값 처리
// {data: [{...}],
// itemsCount: 255
// }
HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", notiVO);
return makeResponseEntityJson(retMap);
}
}

View File

@ -0,0 +1,110 @@
package nlib.col.service;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : CartCookieVO.java
*
* @Description : 비로그인 회원의 카트정보를 담는 쿠키 정보값
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 10. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 10. 13.
* @version 1.0
*
*/
public class CartCookieVO {
String rentValues = null; /* 대출 목록으로 ":"로 구분되어 짐 */
String readValues = null; /* 방문열람 목록으로 ":"로 구분되어 짐 */
/**
* 쿠키 카트값에 자료 항목을 추가한다.
*
* @param cartTypeCd
* @param masterId
* @return
*/
public String addCartItem(String cartTypeCd, String masterId) {
if(StringUtil.isEmpty(cartTypeCd)) return "카트구분 정보가 없습니다.";
if(StringUtil.isEmpty(masterId)) return "자료정보가 없습니다.";
String cartStr = null;
if("1".equals(cartTypeCd)) cartStr = getRentValues();
else if("2".equals(cartTypeCd)) cartStr = getReadValues();
else return "카트구분 정보가 적합하지 않습니다.";
cartStr = (StringUtil.isEmpty(cartStr) ? ":" : cartStr);
if(cartStr.contains(":" + masterId + ":")) return "이미 카트에 존재합니다.";
cartStr += (":" + masterId + ":");
if("1".equals(cartTypeCd)) setRentValues(cartStr);
else if("2".equals(cartTypeCd)) setReadValues(cartStr);
return null;
}
/**
* 쿠키 카트값에서 자료 항목을 삭제한다.
*
* @param cartTypeCd
* @param masterId
* @return
*/
public String removeCartItem(String cartTypeCd, String masterId) {
if(StringUtil.isEmpty(cartTypeCd)) return "카트구분 정보가 없습니다.";
if(StringUtil.isEmpty(masterId)) return "자료정보가 없습니다.";
String cartStr = null;
if("1".equals(cartTypeCd)) cartStr = getRentValues();
else if("2".equals(cartTypeCd)) cartStr = getReadValues();
else return "카트구분 정보가 적합하지 않습니다.";
cartStr = (StringUtil.isEmpty(cartStr) ? ":" : cartStr);
if(StringUtil.isEmpty(cartStr) || !cartStr.contains(":" + masterId + ":")) return "해당 자료는 카트에 존재하지 않습니다.";
int startIdx = cartStr.indexOf(":" + masterId + ":");
if(startIdx < 0) return "해당 자료는 카트에 존재하지 않습니다.";
int endIdx = startIdx + (":" + masterId).length();
cartStr = cartStr.substring(0, startIdx) + cartStr.substring(endIdx);
if("1".equals(cartTypeCd)) setRentValues(cartStr);
else if("2".equals(cartTypeCd)) setReadValues(cartStr);
return null;
}
// GET & SET
public String getRentValues() {
return rentValues;
}
public void setRentValues(String rentValues) {
this.rentValues = rentValues;
}
public String getReadValues() {
return readValues;
}
public void setReadValues(String readValues) {
this.readValues = readValues;
}
}

View File

@ -0,0 +1,142 @@
package nlib.col.service;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* <pre>
* @Class Name : CartService.java
*
* @Description : 카트 관리 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021-10-08 KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021-10-08
* @version 1.0
*
*/
public interface CartService
{
/**
* (로그인자용) 로그인한 사용자의 카트 목록을 조회한다.
*
* @param mbInfoId
* @param cartDivCd
* @return
* @throws Exception
*/
public List<CollectionVO> listCartItems(String mbInfoId, String cartTypeCd) throws Exception;
/**
* (비로그인자용) 쿠키에서 카트 목록을 조회한다.
*
* @param request
* @param cartDivCd
* @return
* @throws Exception
*/
public List<CollectionVO> listCartItemsFromCookie(HttpServletRequest request, HttpServletResponse response, String cartDivCd) throws Exception;
/**
* (로그인자용) 카트 영역 구분코드를 변경한다. (대출 <-> 방문열람)
*
* @param mbInfoId
* @param targetCartItems
* @return
* @throws Exception
*/
public String changeCartType(CollectionVO cartVO) throws Exception;
/**
* (비로그인자용) 카트 영역 구분코드를 변경한다. (대출 <-> 방문열람)
*
* @param request
* @param targetCartItems
* @return
* @throws Exception
*/
public String changeCartTypeToCookie(HttpServletRequest request, HttpServletResponse response, CollectionVO cartVO) throws Exception;
/**
* (로그인자용) 카트에 추가한다.
*
* @param cartVO
* @return
* @throws Exception
*/
public String insertCartItem(CollectionVO cartVO);
/**
* (비로그인자용) 카트에 추가한다.
*
* @param cartVO
* @return
* @throws Exception
*/
public String insertCartItemToCookie(HttpServletRequest request, HttpServletResponse response, CollectionVO cartVO) throws Exception;
/**
* (로그인자용) 카트에서 선택된 자료들을 삭제한다.
*
* @param targetCartItems
* @return
* @throws Exception
*/
public String deleteCartItems(CollectionVO cartVO) throws Exception;
/**
* (비로그인자용) 카트에서 선택된 자료들을 삭제한다.
*
* @param targetCartItems
* @return
* @throws Exception
*/
public String deleteCartItemsFromCookie(HttpServletRequest request, HttpServletResponse response, CollectionVO cartVO) throws Exception;
/**
* 쿠키 카트(비로그인 상태의 카트정보) 존재하는 경우, 해당 사용자 카트(DB) 등록한 , 쿠키 카트 삭제한다.
*
* @param mbInfoId
* @param request
* @param response
* @return
* @throws Exception
*/
public int mergeCart(String mbInfoId, HttpServletRequest request, HttpServletResponse response) throws Exception;
/**
* 쿠키 카트(비로그인 상태의 카트정보) 존재하는 자료 개수를 리턴한다.
*
* @param request
* @param response
* @param cartTypeCd
* @return
* @throws Exception
*/
public int countCartItemsFromCookie(HttpServletRequest request, HttpServletResponse response, String cartTypeCd) throws Exception;
/**
* 사용자 카트의 자료 개수를 리턴한다.
*
* @param mbInfoId
* @param cartTypeCd
* @return
* @throws Exception
*/
public int countCartItems(String mbInfoId, String cartTypeCd) throws Exception;
}

View File

@ -0,0 +1,116 @@
package nlib.col.service;
import java.util.HashMap;
import java.util.List;
/**
* <pre>
* @Class Name : CollectionService.java
*
* @Description : 소장자료 정보를 조회하는 서비스 인터페이스
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 10. 6. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 10. 6.
* @version 1.0
*
*/
public interface CollectionService {
/**
* 자료 상세정보를 조회한다.
*
* @param searchVO
* @return
* @throws Exception
*/
public CollectionVO getItemInfo(CollectionVO searchVO);
/**
* 목록의 자료정보에 상세정보를 조회하여 설정한 리턴한다.
*
* @param list
* @return
* @throws Exception
*/
public List<CollectionVO> setDetailInfoForList(List<CollectionVO> list) throws Exception;
/**
* 목록의 자료정보에 상세정보를 조회하여 설정한 리턴한다.
*
* @param list
* @param mbInfoId
* @param defaultThumbnailUrl
* @return
* @throws Exception
*/
public List<CollectionVO> setDetailInfoForList(List<CollectionVO> list, String mbInfoId) throws Exception;
/**
* 목록의 자료정보에 상세정보를 조회하여 설정한 리턴한다.
*
* @param list
* @param mbInfoId
* @param defaultThumbnailUrl
* @return
* @throws Exception
*/
public List<CollectionVO> setDetailInfoForHashList(List<HashMap<String, String>> list, String mbInfoId) throws Exception;
/**
* 자료 마스터ID 목록 문자열을 받아 CollectionVO 리스트 생성하여 리턴한다.
*
* @param masterIds
* @return
*/
public List<CollectionVO> makeListOfCollectionVO(String masterIds);
/**
* 자료 마스터ID 목록 문자열을 받아 상세내용을 조회하고, CollectionVO 리스트 생성하여 리턴한다.
*
* @param masterIds
* @return
*/
public List<CollectionVO> makeInfoListOfCollectionVO(String masterIds, String mbInfoId) throws Exception;
/**
* 자료상세조회 원문보기시에 로그
* @param colVO
*/
public void insertDataInquiryLog(CollectionVO colVO) throws Exception;
/**
* 함께 볼만한 자료 리스트
* @param vo
* @return
* @throws Exception
*/
public List<CollectionVO> selectSeeTogetherList(CollectionVO vo) throws Exception;
/**
* 유사한 자료 리스트
* @param vo
* @return
* @throws Exception
*/
public List<CollectionVO> selectSimilarList(CollectionVO vo) throws Exception;
/**
* 문화원 코드 조회
*
* @param vo
* @return
*/
public CollectionVO selectMngOrgInfo(String masterId) throws Exception;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,244 @@
package nlib.col.service;
import nlib.cmm.service.PagingVO;
import java.io.Serializable;
/**
* <pre>
* @Class Name : DeptVO.java
*
* @Description : 부서(문화원) VO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 30. JSYOO 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP JSYOO
* @since 2021. 9. 30.
* @version 1.0
*
*/
public class DeptVO {
private String deptSeq; /* 조직코드 */
private String orgCd; /* 처리과코드 */
private String deptNm; /* 조직명 */
private String deptAbbrNm; /* 조직약칭 */
private String hupperDeptSeq; /* 최상위조직코드 */
private String upDeptSeq; /* 상위조직코드 */
private String topDeptYn; /* 최상위여부 */
private String deptLv; /* 기관레벨-차수 */
private String sortSeq; /* 서열 */
private String closeFlag; /* 폐지여부(0:미폐지, 1:폐지) */
private String chngRsn; /* 변경사유 */
private String applyStartYmd; /* 적용시작일 */
private String applyCloseYmd; /* 적용종료일 */
private String syncYn; /* RMS연계여부 */
private String useYn; /* 사용여부 */
private String regId; /* 등록자 */
private String regDd; /* 등록일자 */
private String modId; /* 수정자 */
private String modDd; /* 수정일자 */
private String regionCd; /* 지역 */
private String remark; /* 비고 */
private String cloudId; /* 클라우드ID */
private String zipCode; /* 우편번호 */
private String address; /* 주소 */
private String addressDetail; /* 상세주소 */
private String phoneNo; /* 전화번호 */
private String faxNo; /* 팩스번호 */
private String latitude; /* 위도 */
private String longitude; /* 경도 */
private String domainHostNm; /* 도메인호스트명 */
public String getDeptSeq() {
return deptSeq;
}
public void setDeptSeq(String deptSeq) {
this.deptSeq = deptSeq;
}
public String getOrgCd() {
return orgCd;
}
public void setOrgCd(String orgCd) {
this.orgCd = orgCd;
}
public String getDeptNm() {
return deptNm;
}
public void setDeptNm(String deptNm) {
this.deptNm = deptNm;
}
public String getDeptAbbrNm() {
return deptAbbrNm;
}
public void setDeptAbbrNm(String deptAbbrNm) {
this.deptAbbrNm = deptAbbrNm;
}
public String getHupperDeptSeq() {
return hupperDeptSeq;
}
public void setHupperDeptSeq(String hupperDeptSeq) {
this.hupperDeptSeq = hupperDeptSeq;
}
public String getUpDeptSeq() {
return upDeptSeq;
}
public void setUpDeptSeq(String upDeptSeq) {
this.upDeptSeq = upDeptSeq;
}
public String getTopDeptYn() {
return topDeptYn;
}
public void setTopDeptYn(String topDeptYn) {
this.topDeptYn = topDeptYn;
}
public String getDeptLv() {
return deptLv;
}
public void setDeptLv(String deptLv) {
this.deptLv = deptLv;
}
public String getSortSeq() {
return sortSeq;
}
public void setSortSeq(String sortSeq) {
this.sortSeq = sortSeq;
}
public String getCloseFlag() {
return closeFlag;
}
public void setCloseFlag(String closeFlag) {
this.closeFlag = closeFlag;
}
public String getChngRsn() {
return chngRsn;
}
public void setChngRsn(String chngRsn) {
this.chngRsn = chngRsn;
}
public String getApplyStartYmd() {
return applyStartYmd;
}
public void setApplyStartYmd(String applyStartYmd) {
this.applyStartYmd = applyStartYmd;
}
public String getApplyCloseYmd() {
return applyCloseYmd;
}
public void setApplyCloseYmd(String applyCloseYmd) {
this.applyCloseYmd = applyCloseYmd;
}
public String getSyncYn() {
return syncYn;
}
public void setSyncYn(String syncYn) {
this.syncYn = syncYn;
}
public String getUseYn() {
return useYn;
}
public void setUseYn(String useYn) {
this.useYn = useYn;
}
public String getRegId() {
return regId;
}
public void setRegId(String regId) {
this.regId = regId;
}
public String getRegDd() {
return regDd;
}
public void setRegDd(String regDd) {
this.regDd = regDd;
}
public String getModId() {
return modId;
}
public void setModId(String modId) {
this.modId = modId;
}
public String getModDd() {
return modDd;
}
public void setModDd(String modDd) {
this.modDd = modDd;
}
public String getRegionCd() {
return regionCd;
}
public void setRegionCd(String regionCd) {
this.regionCd = regionCd;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getCloudId() {
return cloudId;
}
public void setCloudId(String cloudId) {
this.cloudId = cloudId;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddressDetail() {
return addressDetail;
}
public void setAddressDetail(String addressDetail) {
this.addressDetail = addressDetail;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
public String getFaxNo() {
return faxNo;
}
public void setFaxNo(String faxNo) {
this.faxNo = faxNo;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getDomainHostNm() {
return domainHostNm;
}
public void setDomainHostNm(String domainHostNm) {
this.domainHostNm = domainHostNm;
}
}

View File

@ -0,0 +1,22 @@
package nlib.col.service;
import java.util.List;
import nlib.restful.DataApiReqVO;
import nlib.restful.DataApiResVO;
public interface InterestService
{
public List<CollectionVO> listInterests(CollectionVO vo);
public int countListInterests(CollectionVO vo);
public void deleteInterests(List<String> masterIdList, String mbInfoId);
public void insertInterest(CollectionVO vo);
public int countInterest(CollectionVO vo);
public List<DeptVO> selectOrgList(CollectionVO vo);
}

View File

@ -0,0 +1,78 @@
package nlib.col.service;
import java.util.HashMap;
import java.util.List;
import nlib.restful.DataApiResVO;
/**
* <pre>
* @Class Name : ReadService.java
*
* @Description :
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 10. 27. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 10. 27.
* @version 1.0
*
*/
public interface ReadService {
/**
* 열람신청희망 가능 일자 목록을 조회한다.
*
* @param mbInfoId
* @return
*/
public List<HashMap<String, String>> listDates();
/**
* 열람을 신청한다.
*
* @param list
* @param mbInfoId
* @param mngOrgCd
* @return
*/
public List<CollectionVO> insertReadItems(List<CollectionVO> list, String mbInfoId, CollectionVO readVO, boolean fromCart) throws Exception;
/**
* 사용자의 열람건이 존재하는 문화원 정보 목록을 조회한다.
*
* @param mbInfoId
* @return
*/
public List<HashMap<String, String>> listReadMngOrg(String mbInfoId);
/**
* 열람 목록 조회한다.
*
* @param searchVO
* @return
*/
public DataApiResVO listReadItems(CollectionVO searchVO);
/**
* 열람신청을 취소한다.
*
* @param searchVO
* @return
*/
public DataApiResVO cancelReadItem(CollectionVO searchVO);
}

Some files were not shown because too many files have changed in this diff Show More