반응형

신규 고도화 사업을 진행하게되어 기존 소스를 받았는데, 구조가 뭔가 이상하다.

 

분명히 전자정부프레임워크라고 했는데, egov관련된 정보는 어디에도 안보이고 pom.xml부터 에러가 발생한다.

pom.xml에 parent라는 태그가 보인다.

찾아보니 메이븐을 부모, 자식형태로 구성해서 공통화를 할 수 있다고 한다.

오... 같은 프로젝트에 공통으로 쓰는 라이브러리가 많을때 쓰면 좋을 것 같다. (근데 전자정부인데 이렇게 마음대로 구조를 나눠도 되나...?😨)

 

pom.xml parent, modules구조로 나누기

먼저 조상(부모)가 될 프로젝트를 구성한다. (egov기준으로 예시를 작성하겠습니다.)

해당 프로젝트에선 딱히 뭔가를 만들지 않고, pom.xml만 작성한다.

 

Parent Project

1. 신규 프로젝트 생성

 

2. Project name, Group id를 작성한다.

egov-prj-parent 프로젝트 생성

 

3. egov구조 sample데이터도 전부 체크해준다.

 

4. 프로젝트가 생성되면 프로젝트 우클릭 > Properties > Java Build Path로 갑니다.

각 항목들을 모두 제거해서 프로젝트를 비워줍니다.

 

제거하면 다 사라지고 껍데기만 남는데 필요없는 src폴더까지 지워줍니다.

 

5. pom.xml을 수정합니다.

pom.xml

<?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>com.psw</groupId>
	<artifactId>egov-prj-parent</artifactId>
	<version>1.0.0</version>
	<packaging>pom</packaging>
	<name>egov-prj-parent</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.25.RELEASE</spring.maven.artifact.version>
		<egovframework.rte.version>3.10.0</egovframework.rte.version>
	</properties>
	
	<modules>
        <module>egov-prj-child1</module>
        <module>egov-prj-child2</module>
    </modules>

	<repositories>
        <repository>
            <id>mvn2s</id>
            <url>https://repo1.maven.org/maven2/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
			<id>egovframe</id>
			<url>http://maven.egovframe.go.kr/maven</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
        <repository>
            <id>egovframe_old1</id>
            <url>http://maven.egovframe.kr:8080/maven/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>egovframe_old2</id>
            <url>http://www.egovframe.go.kr/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>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </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>org.hsqldb</groupId>
			<artifactId>hsqldb</artifactId>
			<version>2.5.0</version>
		</dependency>

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>3.0.8</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>
					<version>3.1</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
						<encoding>UTF-8</encoding>
						<maxmem>1024m</maxmem>
					</configuration>
				</plugin>
				<plugin>
                	<groupId>org.apache.maven.plugins</groupId>
                	<artifactId>maven-war-plugin</artifactId>
                	<version>2.4</version>
                	<configuration>
                		<failOnMissingWebXml>false</failOnMissingWebXml>
                	</configuration>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>hibernate3-maven-plugin</artifactId>
                    <version>3.0</version>
                    <configuration>
                        <components>
                            <component>
                                <name>hbm2ddl</name>
                                <implementation>annotationconfiguration</implementation>
                            </component>
                        </components>
                    </configuration>
                    <dependencies>
                        <dependency>
                            <groupId>org.hsqldb</groupId>
                            <artifactId>hsqldb</artifactId>
                            <version>2.5.0</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.12.0</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>3.1.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>3.0.0</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>
</project>

너무나도 기네요...

공통으로 사용할 메이븐은 parent에 넣고 사용할 예정이고 여기서 테스트를 위해 tiles만 추가해두겠습니다.

 

modules부분에서 하위 프로젝트를 지정합니다.

 

Child1 Project

1. child1 프로젝트 생성하기

 

2. egov 프로젝트를 생성하고 pom.xml을 바로 수정합니다.

(설정이나 삭제 과정은 없습니다.)

pom.xml

<?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>
	<parent>
		<groupId>com.psw</groupId>
		<artifactId>egov-prj-parent</artifactId>
		<version>1.0.0</version>
	</parent>
	<artifactId>egov-prj-child1</artifactId>
	<packaging>war</packaging>
	<version>1.0.0</version>
	<name>egov-prj-child1</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.25.RELEASE</spring.maven.artifact.version>
		<egovframework.rte.version>3.10.0</egovframework.rte.version>
	</properties>

	<repositories>
		<repository>
			<id>mvn2s</id>
			<url>https://repo1.maven.org/maven2/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>true</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>egovframe</id>
			<url>http://maven.egovframe.go.kr/maven</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>egovframe_old1</id>
			<url>http://maven.egovframe.kr:8080/maven/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
		<repository>
			<id>egovframe_old2</id>
			<url>http://www.egovframe.go.kr/maven/</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>false</enabled>
			</snapshots>
		</repository>
	</repositories>

	<dependencies>

	</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>
					<version>3.1</version>
					<configuration>
						<source>1.8</source>
						<target>1.8</target>
						<encoding>UTF-8</encoding>
						<maxmem>1024m</maxmem>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.apache.maven.plugins</groupId>
					<artifactId>maven-war-plugin</artifactId>
					<version>2.4</version>
					<configuration>
						<failOnMissingWebXml>false</failOnMissingWebXml>
					</configuration>
				</plugin>
				<plugin>
					<groupId>org.codehaus.mojo</groupId>
					<artifactId>hibernate3-maven-plugin</artifactId>
					<version>3.0</version>
					<configuration>
						<components>
							<component>
								<name>hbm2ddl</name>
								<implementation>annotationconfiguration</implementation>
							</component>
						</components>
					</configuration>
					<dependencies>
						<dependency>
							<groupId>org.hsqldb</groupId>
							<artifactId>hsqldb</artifactId>
							<version>2.5.0</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.12.0</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>3.1.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>3.0.0</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>
</project>

parent부분에 부모로 받을  groupId와 artifactId를 매칭해줍니다.

<dependencies>부분은 비웁니다. 부모에서 상속받은 메이븐만 사용할 예정입니다.

 

3. 해당 워크스페이스가 동작하고 있는 경로로가서 child1프로젝트를 parent프로젝트로 넣습니다.

parent프로젝트 복사한다.

나중에 child2도 생성해서 똑같이 복사하면 됩니다. 지금은 1만 복사합니다.

 

4. eclipse로 돌아와서 프로젝트를 새로고침 해보면, child1이 들어와있는걸 볼 수 있습니다.

parent 안에 child1

 

5. 필요없어진 egov-prj-child1은 지웁니다.

 

6. 이제 개발해야할 child1의 소스를 import하겠습니다.

parent안에 있는 child1를 해야합니다.

 

Package Explorer - 우클릭 - import
Maven - Exsiting Maven Projects
child1 선택

 

그럼 정상적으로 import가 된다.

지웠던 egov-prj-child1가 생성되었다.

 

7. child1프로젝트에 타일즈 세팅후 톰캣 구동을 해보니 정상적으로 페이지가 뜬다. 😆

tiles 적용 완료

 

Child2 Project

child1 프로젝트와 마찬가지로 동일하게 설정하고 import후 개발을 진행하면 된다.

반응형
반응형

프로젝트 기능을 수행하다보면 각종 다양한 접근 방식이나 데이터 처리로 인해 오류를 만나게 됩니다.

이런 경우 하나의 서비스를 처리하면서 데이터에 대한 일관적인 상태를 유지하고 문제가 없게 관리를 해야합니다.

 

트랜잭션

정보처리기사 공부를 하다보면 트랜잭션 개념을 만나게 되는데, 여기서 나왔던 설명이 괜찮게 느껴져서 인용해겠습니다.

 

1. A라는 사람이 B의 중고 물건이 마음에 들어서 거래를 진행하게 되었습니다.

2. A는 B에게 물건에 해당하는 금액을 어플을 통해 송금하였습니다.

3. 송금을 했기때문에 A계좌에서는 해당하는 금액만큼 돈이 빠져나갔습니다.

4. 그사이 B계좌로 돈이 입금되어야하지만 알 수 없는 오류가 발생합니다.

5. A는 계좌에서 금액이 빠져나갔지만 B는 돈을 못받는 현상을 막기 위해 트랙잭션이 발생하고, A의 계좌는 원래대로 돌아옵니다.


이런식으로 데이터를 처리하는데 오류나 다양한 상황에 대하여 안정성을 확보하고 성공한 경우에만 반영을 해주는 것을 트랜잭션이라고 합니다.

 

 

 

트랜잭션의 특징

트랜잭션은 4가지의 특징을 지닙니다.

-원자성, 일관성, 독립성, 지속성

 

1. 원자성(Atomicity)

DB에 모두 반영하거나 반영되지 않는 것을 말합니다. 즉, 모두 성공으로 처리하거나 모두 실패로 처리해야합니다.

 

2. 일관성(Consistency)

트랜잭션 작업 처리의 결과가 항상 일관되어야 함을 말합니다.(데이터 타입이 반환 후와 전이 동일해야 함)

 

3. 독립성(Isolation)

동시 발생하는 트랜잭션들이 서로에게 영향을 미치지 않아야합니다.

 

4. 영속성(Durability)

트랜잭션을 성공적으로 마치면 결과가 영구적으로 저장되어야 합니다.

 

 

스프링 프로젝트 트랜잭션 설정하기

1. 어노테이션을 통한 설정하기

트랜잭션 설정을 위해서 다양한 방법이 있지만 그 중 어노테이션을 통한 설정 방법을 알아보겠습니다.

먼저 컨텍스트부분에 아래의 한 줄을 추가해주면 간단하게 적용이 가능합니다.

<tx:annotation-driven transaction-manager="txManager"/>

 

 

context-transaction.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

	<tx:annotation-driven transaction-manager="txManager"/>
	
	<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
</beans>

이후 트랜잭션을 처리하고 싶은 메소드나 클래스, 인터페이스 등에 @Transactional 어노테이션을 걸어주면 된다.

 

 

XXXService.java

@Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE)
public HashMap<Object, Object> insertUser(HashMap<Object, Object> params) {
	int result = loginMapper.insertUser(params);
	params.clear();
	params.put("result", result);
	return params;
}

inserUser라는 매퍼를 통해 insert쿼리를 수행하는 도중 오류가 발생하면 트랜잭션이 발생한다.

 

반응형
반응형

잘 납품되었던 프로젝트 뼈대를 가져와서 다른 프로젝트를 또 만들고 만들고... 이렇게 하다보니 이전에 배웠던 스프링 개념도 많이 흐릿해지고 헷갈리게 되는것 같습니다.

시간이 지나면서 기존 개념도 많이 잊어먹었고, 요구사항에 맞게 스프링 설정을 하면서 어려움을 겪는 느낌이 들어 다시한번 공부를 하고 정리를 해보고자 합니다.(기초지만 역시 주기적으로 다시 봐주고 정리할 필요가 있는 것 같습니다.😎)

 

구동순서

1. was(톰캣 등)를 통해 프로젝트를 구동을 하게되면 해당 프로젝트 내부의 web.xml을 로드합니다.

web.xml은 서블릿 배포 기술자로 DD(Deployment Descriptor)라고도 불립니다. WEB-INF 디렉토리에 존재하며 웹 어플리케이션의 설정을 구성하고 있습니다.

webapp-WEB-INF에 위치합니다.

 

 

2. web.xml 파일을 로드하면서 Servlet Container가 구동됩니다.

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:egovframework/spring/context-*.xml</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>action</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>action</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

 

3. Servlet Container가 구동되면서 ContextLoaderListener클래스가 자동으로 메모리에 생성됩니다. 

ContextLoaderListener는 서블릿 이전에 서블릿을 초기화 시켜주며 contextConfigLocation을 설정파일들의 위치를 지정시켜줍니다.

 

4. contextConfigLocation는 공통으로 사용할 의존성 설정파일들을 지정하며, <param-value>부분에 파일 경로를 입력해주면 됩니다.

저는 전자정부프레임워크를 사용하면서 기본 위치가 'egovframework/springmvc/'으로 되어있고, dispatcher-servlet.xml읽도록 설정했습니다.

 

5. dispatcher-servlet.xml을 읽어서 새로운 Spring Container를 생성하고, Controller 객체를 메모리에 올립니다.

 

6. dispatcher-servlet.xml(servlet-context.xml) 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:task="http://www.springframework.org/schema/task"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
                http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
                http://www.springframework.org/schema/task
                http://www.springframework.org/schema/task/spring-task-3.0.xsd">
                
    <task:annotation-driven></task:annotation-driven>

    <mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <context:component-scan base-package="egovframework"/>

    <!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
    <beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <beans:property name="prefix" value="/WEB-INF/jsp/" />
        <beans:property name="suffix" value=".jsp" />
    </beans:bean>
</beans>

- annotation-driven: xml이 길고 복잡해지면서 대안으로 나타났습니다. 클래스, 메소드 등에 @를 달아 기능을 수행할 수 있도록 동작하기 위해 설정합니다. (xml Bean 등록이 더 우선순위가 높습니다.)

- mvc:annotation-driven: @Controller @RequestMapping 등 컨트롤러에서 해당하는 기능을 설정할 수 있게 해줍니다. 

- task:annotation-driven: @Scheduled 어노테이션을 사용을 위해 처리합니다.(스케줄러 관련)

- org.springframework.web.servlet.view.InternalResourceViewResolver: 컨트롤러가 모델을 리턴하고 DisapatcherServlet이 해당하는 파일을 처리할 때 필요한 정보를 기술하는 태그 접미사가 'WEB-INF/jsp'이면서 '.jsp'로 끝나는 파일들을 찾습니다. 

WEB-INF/jsp/login/login.jsp

- context:component-scan: 특정 패키지의 클래스들을 스캔하여 어노테이션을 확인하고 bean 등록을 한다. @Component @Controller @Service @Repository등이 클래스에 설정해야 등록된다.

 

 

 

 

 

웹 요청 동작순서

1. 사용자가 브라우저를 통해 주소를 입력합니다. - ( http://localhost/login.do )

web.xml에서 설정했던 정보에 맞는 요청일 경우 DispatcherServlet이 해당 요청을 먼저 가로채서 적합한 Controller에 매핑을 해줍니다.

 

2. <servlet-mapping/>부분이 있는데, 설정된 <servlet-name/>에 해당하는 매핑 설정을 할 수 있습니다.

예를들어 <url-pattern/>부분이 '/'으로 처리되어 있다면 모든 요청을 가로챕니다. 하지만 설정부분은 '*.do'로 되어있어서 'login.do'와 같은 형태만 적용이 됩니다.

 

3. 가로챈 매핑정보를 통해 처리할 Controller를 찾은 후, 적용된 코드에 따라 기능이 처리된다.

   3-1. Controller(mapping) -> View

   3-2. Controller(mapping) -> Service -> DAO -> mapper -> DB -> DAO -> Service -> Controller -> Return

 

4. 3-1과 같은 처리가 수행되면 ViewResolver에 의해 해당하는 view를 반환한다.

<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/jsp/" />
    <beans:property name="suffix" value=".jsp" />
</beans:bean>

dispatcher-servlet.xml에 설정된 ViewResolver부분에 맞는 prefix, suffix의 정보를 토대로 view페이지를 제공합니다.

(저는 tiles3를 적용해서 다르게 설정이 되어있습니다.)

@RequestMapping(value = "/login.do")
public ModelAndView login(ModelAndView mv) {
    mv.setViewName("login/login");
    return mv;
}

http://localhost/login.do -> '/WEB-INF/jsp/login/login.jsp'

 

5. 해당하는 viewDispatcherServlet에 보내면 DispatcherServlet은 클라이언트에게 데이터를 전송한다.

이때, 모델의 속성값이 있으면 같이 전송된다. (해당하는 값은 .jsp파일에서 ${변수명}을 통해 사용이 가능하다)

 

 

 

반응형
반응형

적용은 차근차근 따라오면 크게 어렵지 않게 적용이 가능합니다. maven을 통해 적용합니다.

 

프로젝트에 lucy적용하기

pom.xml

<!-- https://mvnrepository.com/artifact/com.navercorp.lucy/lucy-xss-servlet -->
<dependency>
    <groupId>com.navercorp.lucy</groupId>
    <artifactId>lucy-xss-servlet</artifactId>
    <version>2.0.1</version>
</dependency>

다음은 필터를 프로젝트에 설정해주어야 합니다.

 

 

 

web.xml

<!-- 멀티파트 필터링을 위한 설정 -->
<filter>
    <filter-name>multipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>multipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<!-- lucy 설정 -->
<filter>
    <filter-name>xssEscapeServletFilter</filter-name>
    <filter-class>com.navercorp.lucy.security.xss.servletfilter.XssEscapeServletFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>xssEscapeServletFilter</filter-name>
    <!-- <url-pattern>/*</url-pattern> -->
    <url-pattern>*.do</url-pattern>
</filter-mapping>

멀티파트필터 없이 경우에는 루시필터만 적용하게되면 멀티파트의 행위에 대해서는 감시가 이루어지지 않기 때문에 해당 필터를 적용해주셔야 합니다!

 

 

 

lucy-xss-servlet-filter-rule.xml

- resources/ 하위에 해당 파일을 생성하고 위치시킵니다.

<?xml version="1.0" encoding="UTF-8"?>
 
<config xmlns="http://www.navercorp.com/lucy-xss-servlet">
    <defenders>
        <!-- XssPreventer 등록 -->
        <defender>
            <name>xssPreventerDefender</name>
            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssPreventerDefender</class>
        </defender>

        <!-- XssSaxFilter 등록 -->
        <defender>
            <name>xssSaxFilterDefender</name>
            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssSaxFilterDefender</class>
            <init-param>
                <param-value>lucy-xss-sax.xml</param-value>   <!-- lucy-xss-filter의 sax용 설정파일 -->
                <param-value>false</param-value>        <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->
            </init-param>
        </defender>

        <!-- XssFilter 등록 -->
        <defender>
            <name>xssFilterDefender</name>
            <class>com.navercorp.lucy.security.xss.servletfilter.defender.XssFilterDefender</class>
            <init-param>
                <param-value>lucy-xss.xml</param-value>    <!-- lucy-xss-filter의 dom용 설정파일 -->
                <param-value>false</param-value>         <!-- 필터링된 코멘트를 남길지 여부, 성능 효율상 false 추천 -->
            </init-param>
        </defender>
    </defenders>

    <!-- default defender 선언, 필터링 시 지정한 defender가 없으면 여기 정의된 default defender를 사용해 필터링 한다. -->
    <default>
        <defender>xssPreventerDefender</defender>
    </default>

    <!-- global 필터링 룰 선언 -->
    <global>
        <!-- 모든 url에서 들어오는 globalParameter 파라메터는 필터링 되지 않으며
                또한 globalPrefixParameter1로 시작하는 파라메터도 필터링 되지 않는다.
                globalPrefixParameter2는 필터링 되며 globalPrefixParameter3은 필터링 되지 않지만
                더 정확한 표현이 가능하므로 globalPrefixParameter2, globalPrefixParameter3과 같은 불분명한 표현은 사용하지 않는 것이 좋다. -->
        <params>
            <param name="globalParameter" useDefender="false" />
            <param name="globalPrefixParameter1" usePrefix="true" useDefender="false" />
            <param name="globalPrefixParameter2" usePrefix="true" />
            <param name="globalPrefixParameter3" usePrefix="false" useDefender="false" />
        </params>
    </global>

    <!-- url 별 필터링 룰 선언 -->
    <url-rule-set>

        <!-- url disable이 true이면 지정한 url 내의 모든 파라메터는 필터링 되지 않는다. -->
        <url-rule>
            <url disable="true">/disableUrl1.do</url>
        </url-rule>

        <!-- url disable이 false인 설정은 기본이기 때문에 불필요하다. 아래와 같은 불필요한 설정은 하지 않는다.-->
        <url-rule>
            <url disable="false">/disableUrl2.do</url>
        </url-rule>

        <!-- url disable이 true이면 지정한 url 내의 모든 파라메터가 필터링 되지 않기 때문에 <params> 로 선언한 설정은 적용되지 않는다. 
               아래와 같은 불필요한 설정은 하지 않는다. -->
        <url-rule>
            <url disable="true">/disableUrl3.do</url>
            <params>
                <param name="query" useDefender="false" />
                <param name="prefix1" usePrefix="true" />
                <param name="prefix2" usePrefix="false" useDefender="false" />
                <param name="prefix3" usePrefix="true" useDefender="true" />
                <param name="prefix4" usePrefix="true" useDefender="false" />
                <param name="prefix5" usePrefix="false" useDefender="true" />
            </params>
        </url-rule>

        <!-- url disable이 false인 설정은 기본이기 때문에 불필요하다. <params> 선언한 설정은 적용이 된다.-->
        <url-rule>
            <url disable="false">/disableUrl4.do</url>
            <params>
                <!-- disableUrl4.do 의 query 파라메터와 prefix4로 시작하는 파라메터들은 필터링 되지 않는다. 
                        usePrefix가 false, useDefender가 true인 설정은 기본이기 때문에 불필요하다. -->
                <param name="query" useDefender="false" />   
                <param name="prefix1" usePrefix="true" />
                <param name="prefix2" usePrefix="false" useDefender="false" />
                <param name="prefix3" usePrefix="true" useDefender="true" />
                <param name="prefix4" usePrefix="true" useDefender="false" />
                <param name="prefix5" usePrefix="false" useDefender="true" />
            </params>
        </url-rule>

        <!-- url1 내의 url1Parameter는 필터링 되지 않으며 또한 url1PrefixParameter로 시작하는 파라메터도 필터링 되지 않는다. -->
        <url-rule>
            <url>/url1.do</url>
            <params>
                <param name="url1Parameter" useDefender="false" />
                <param name="url1PrefixParameter" usePrefix="true" useDefender="false" />
            </params>
        </url-rule>

        <!-- url2 내의 url2Parameter1만 필터링 되지 않으며 url2Parameter2는 xssSaxFilterDefender를 사용해 필터링 한다.  -->
        <url-rule>
            <url>/url2.do</url>
            <params>
                <param name="url2Parameter1" useDefender="false" />
                <param name="url2Parameter2">
                    <defender>xssSaxFilterDefender</defender>
                </param>
            </params>
        </url-rule>
    </url-rule-set>
</config>

네이버 제공 샘플을 참고하여 자기 프로젝트에 맞게 설정을 변경해주세요.

(작성하다보니 XssFilter, XssSaxFilter 부분에 lucy-xss-sax.xml, lucy-xss.xml를 적용하는 부분이 있는데 별도로 생성하지 않아도 문제없이 잘 동작했습니다.)

 

중요한 부분은 필터링을 제외처리할 부분과 특정 파라미터만 제외할 부분인데, 에디터등을 사용한 프로젝트라면 당연히 html코드로 넘어오기 때문에 제외처리를 잘 해주셔야합니다.

lucy필터의 특징은 넘어오는 파라미터를 필터링(치환)을 처리해주는거지 필터에서 컨트롤러접근을 막아주는 필터는 아닌점만 인지하고 적용하시면 될 것 같습니다.

필터링된 모습

 

 

 

* 멀티파트(Multipart)에서도 필터링이 되어야하는분들은 추가 작업이 있습니다

이후 구동하는 톰캣의 config디렉토리의 context.xml을 열어줍니다.

기존 소스가 아래와 같은 형태로 되어 있을텐데,

<Context>
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>

 

Context 태그부분에 allowCasualMultipartParsing="true" path="/"를 추가해줍니다.

<Context allowCasualMultipartParsing="true" path="/">
    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
    <CookieProcessor className="org.apache.tomcat.util.http.LegacyCookieProcessor" />
    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
</Context>

* 이클립스에서는 Package Explorer에 Server라는게 보이는데 구동하고 계신 톰캣의 conf들이 모여있습니다. 여기서 변경하시면 됩니다.

 

 

이것으로 lucy filter 적용 및 설정은 끝났습니다. xss공격으로부터 한층 부담을 덜고 개발을 진행하실 수 있습니다.

반응형
반응형

웹 개발을 진행하다보면 수많은 취약점공격을 대비하면서 개발을 진행해야 합니다.

개인정보를 탈취하거나 해킹, 계정 도용, 잘못된 수정이나 악의적인 페이지로 강제 이동하는 현상 등등 많은 이슈들을 사용자가 겪을 수 있거나 고객사쪽 데이터에도 큰 문제를 일으킬 수 있기 때문입니다.😱

 

이를 방어하기 위해 회사 동료분들과 공통으로 사용할 필터나 인터셉터등을 작성하여 공격을 방어해보았지만, 새로운 기술이나 방법을 통해 다양한 방식의 공격에서 취약해지는 현상을 발견했고, 이를 보완하고자 추가 개발을 해야할지 다른 라이브러리르 적용해볼지 찾아보다가 시간상의 어려움으로 네이버의 lucy필터라는걸 알게되어 이번에 적용을 하게 되었습니다. 네이버는 기존에 lucy-xss-filter라는 라이브러리를 제공하였는데, 해당 라이브러리도 취약한 부분이 발생하여 해결책으로 만든 라이브러리가 lucy-xss-servlet-filter입니다.

 

특징으로는 모든 xss공격으로 의심되는 패턴을 제거하는게 아니라 필터링(치환)이되어 컨트롤러에 도착했을때는, 다른값으로 이미 변경이되어 있습니다.

 

네이버측에서도 이러한 문제가 발생하여 기존에 잘 동작하던 소스가 문제가 생길수 있으므로, 새로운 프로젝트에 적용하는걸 추천하고 있습니다.

 

또한 직접 적용해보니 json형태의 문제와 multipart는 필터링이 안되어 전송되는 현상등이 발생하여 이러한 부분들을 해결한 포스팅은 추후 작성되면 하단에 링크를 걸어두도록 하겠습니다.

 

▼▼▼아래 글은 spring에서 lucy-xss-servlet-filter적용하는 방법을 포스팅했습니다.

https://myhappyman.tistory.com/253

 

XSS - Spring lucy servlet filter 적용하기

적용은 차근차근 따라오면 크게 어렵지 않게 적용이 가능합니다. maven을 통해 적용합니다. 프로젝트에 lucy적용하기 pom.xml com.navercorp.lucy lucy-xss-servlet 2.0.1 다음은 필터를 프로젝트에 설정해주어

myhappyman.tistory.com

 

▼▼▼아래 링크는 네이버 lucy 깃허브 url입니다.

https://github.com/naver/lucy-xss-servlet-filter

 

GitHub - naver/lucy-xss-servlet-filter

Contribute to naver/lucy-xss-servlet-filter development by creating an account on GitHub.

github.com

 

반응형
반응형

개발 도중이나 실운영시에 문제가 발생하면 항상 제일 먼저 확인하는것이 로그파일부터 찾게 됩니다. 오류에 대한 흔적이나 로직상 개발자가 남겨둔 정보가 있기 때문인데, Log4j2 설정에 대해 정리를 해봅니다.

 

XML 위치

먼저 log4j2.xml 파일의 위치는 WEB-INF/classes하위에 위치시킵니다.

(개발 구조에서는 resources 밑에 위치합니다.)

 

파일 내부 구조

xml내부에는 <Configration> 최상위에 위치하고 <Logger>, <Appender>가 존재합니다.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

 

Logger 설정

Logger부분에서는 어플리케이션의 단위별, 수행 단계를 설정합니다.

name, level, additivity 속성들로 이루어져 있습니다.

<Logger name="egovframework" level="DEBUG" additivity="false">
    <AppenderRef ref="console" />
</Logger>

🟧name: 로거의 이름(java.sql, jdbc.sqltiming...)

🟧level: 로그의 레벨(DEBUG, INFO, ERROR, OFF...)

🟧additivity: 중복로깅여부 (true, false)

 

Appender 설정

로그가 출력되는 위치를 설정합니다.

이클립스등에서 콘솔창에 로그가 출력되는 양식이라거나 로그를 파일로 출력하는 위치, 구조등을 설정합니다.

<Console>, <File>, <RollingFile> 등이 주로 사용됩니다.

구조는 아래와 같이 작성됩니다.

 <Appenders>
   <Console name="console" target="SYSTEM_OUT">
	<PatternLayout pattern="%d %5p [%c] %m%n" />
   </Console>
   <RollingFile name="file" fileName="./logs/${date:yyyy}/${date:MM}/dailyLog.log">
   </RollingFile>
 </Appenders>

RollingFile의 경우 FileAppender의 개선된 형태로 특정 크기이상의 파일로 커지면 기존 파일을 백업파일로 변경하고 다시 로깅을 시작합니다.

 

실제로 나중에 파일을 생성하는 RollingFile쪽을 좀 더 살펴 보겠습니다.

🟧name: 로거의 이름입니다. 추후 AddenderRef와 같은 태그에서 참조를 할때 해당 name을 사용합니다.

🟧fileName: 로그 파일의 생성 경로 및 파일 이름을 지정합니다.

(C:/test/dailyout.log로 지정하면 c:/text 디렉토리 내부에 dailyout.log형태로 생성됩니다.)

🟧filePattern: 파일의 생성 패턴입니다. 서버 일자가 변경되거나 특정 크기가 커지는 등 변화가 필요할때 사용되는 옵션입니다. 이를통해 로그 파일들을 구분합니다.

     🔸${date:yyyy}: 금일 년도만 가져옵니다 (ex) 2019, 2020, 2021)

     🔸${date:MM}: 금일 월을 가져옵니다. (ex) 01, 02, 03, 04 ... 11, 12)

     🔸%d{yyyyMMdd}: 금일 일자 조합

 

 

 

 

 

✅아래는 실제로 사용한 Log4j2.xml 구조입니다.

<RollingFile>의 fileNamefilePattern부분에 로그 위치만 지정하시고 각 로거별 레벨을 수정해서 사용하면 됩니다.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
		<Console name="console" target="SYSTEM_OUT">
		    <PatternLayout pattern="%d %5p [%c] %m%n" />
		</Console>
		<RollingFile name="file" fileName="로그 디렉토리 위치/${date:yyyy}/${date:MM}/dailyLog.log"
								filePattern="로그 디렉토리 위치/${date:yyyy}/${date:MM}/dailyLog_%d{yyyyMMdd}.log">
			<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
			<Policies>
				<TimeBasedTriggeringPolicy />
			</Policies>
		</RollingFile>
    </Appenders>
    <Loggers>
		<Logger name="java.sql" level="OFF" additivity="false">  <!--OFF    DEBUG   ERROR   INFO  -->
			<AppenderRef ref="console" />
		</Logger>
		<Logger name="egovframework" level="DEBUG" additivity="false">
			<AppenderRef ref="console" />
		</Logger>
		<Logger name="jdbc.sqltiming" level="OFF" additivity="false">
			<AppenderRef ref="console" />
		</Logger>
		<Logger name="org.springframework" level="INFO" additivity="false">
			<AppenderRef ref="console" />
		</Logger>
		<Root level="ERROR">
			<AppenderRef ref="console" />
			<AppenderRef ref="file"/>
		</Root>
    </Loggers>
</Configuration>

 

반응형
반응형

5+@ 년전쯤 개발된 소스를 추가 개발하게 되었는데, 레거시 버전들로 이루어져 있었고 고객사에서도 버전업이 가능한지에 대한 문의가 와서 버전업을 진행해보았습니다.

하나씩 버전을 변경하고 구동하다보니 아래와 같은 에러들이 발생했는데🤣, pom.xml부분을 차근차근 수정해서 구동하는데 성공하였습니다.

 

ASM ClassReader failed to parse class file - probably ~....

 

버전업을 하면서 발생한 오류들...2

 

구성 버전

 

먼저 pom.xml을 열어서 수정을 진행합니다.

- 스프링 버전을 4.3.22.RELEASE로 올려줍니다.

<properties>
	<spring.maven.artifact.version>4.3.22.RELEASE</spring.maven.artifact.version>
	<egovframework.rte.version>3.9.0</egovframework.rte.version>
	<spring.security.version>3.2.4.RELEASE</spring.security.version>
	<poi.version>3.12</poi.version>
</properties>

비교를 위한 기존 버전

(스프링 시큐리티부분은 딱히 사용하고 있지 않아 그대로 두었다.)

 

 

- Java11로 올리면서 의존성 오류가 발생하여 maven을 추가하였습니다.

<!-- 자바11 이슈 -->
<dependency>
	<groupId>javax.xml.bind</groupId>
	<artifactId>jaxb-api</artifactId>
	<version>2.3.1</version>
</dependency>
<dependency>
	<groupId>com.sun.xml.bind</groupId>
	<artifactId>jaxb-core</artifactId>
	<version>2.3.0.1</version>
</dependency>
<dependency>
	<groupId>com.sun.xml.bind</groupId>
	<artifactId>jaxb-impl</artifactId>
	<version>2.3.1</version>
</dependency>
<!-- 자바11 이슈 -->

 

- 자바와 톰캣 버전을 변경합니다.

<pluginManagement>
	<plugins>
		<plugin>
			<groupId>org.apache.tomcat.maven</groupId>
			<artifactId>tomcat8.5-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.11</source>
				<target>1.11</target>
				<encoding>UTF-8</encoding>
			</configuration>
		</plugin>
	</plugins>
</pluginManagement>

톰캣 : tomcat7.0-maven-plugin -> tomcat8.5-maven-plugin

자바 : 1.7 -> 1.11

 

이후 maven update -> clean 이후 구동해봅니다.

 

 

 

반응형
반응형

구동중인 프로젝트의 특정 경로에서 데이터를 가져와서 추가 처리가 필요한 상태였는데, 서버의 구동중인 절대 경로를 가져오기 위해 아래의 구문을 사용해보니 deprecated처리가 되어있습니다.🙄

@RequestMapping(value = "/report.do",method = RequestMethod.POST)
public @ResponseBody HashMap<Object, Object> report(@RequestParam HashMap<Object, Object> param,
													HttpServletRequest request) {
	String absolutePath = request.getRealPath(request.getContextPath()); //deprecated
	return param;
}

 

문서를 찾아가보니 ServletContext.getRealPath로 대체한다고 되어있습니다.😃

 

request.getSession().getServletContext().getRealPath("/");

 

아래처럼 변경된 문법을 통해 절대 경로를 처리할 수 있습니다.

@RequestMapping(value = "/report.do",method = RequestMethod.POST)
public @ResponseBody HashMap<Object, Object> report(@RequestParam HashMap<Object, Object> param,
														HttpServletRequest request) {
	String absolutePath = request.getSession().getServletContext().getRealPath("/");
	return param;
}
반응형