====== Exception Handling 서비스 ======
===== 개요 ======
전자정부 표준프레임워크 기반의 시스템 개발시 Exception 처리, 정확히는 Exception 별 특정 로직(후처리 로직이라고 부르기도 함)을 흐를 수 있도록 하여
Exception 에 따른 적절한 대응이 가능도록 하고자 하는데 목적이 있다.\\
AOP 의 도움을 받아 비즈니스 POJO와 분리되어 After throwing advice 로 정의하였다.\\
AOP 관련한 내용은 [[egovframework:rte:fdl:aop|AOP 모듈]]을 참조하길 바란다.\\
Exception 에 대해 이야기 하겠다.\\
Exception 이 발생시 Exception 발생 클래스 정보와 Exception 종류가 중요하다. \\
Exception 발생 클래스 정보와 Exception 종류는 모두 후처리 로직의 대상일지 아닐지를 결정하는데 사용된다.\\
public CategoryVO selectCategory(CategoryVO vo) throws Exception {
CategoryVO resultVO = categoryDAO.selectCategory(vo);
try {
....
// 넘어온 resultVO 가 null 인경우 EgovBizException 발생 (result.nodata.msg 는 메세지 키에 해당됨)
if (resultVO == null)
throw processException("result.nodata.msg");
// 또는 throw processException("result.nodata.msg", 발생한 Excpetion );
return resultVO;
}
===== 설명 =====
우리는 앞에서 언급했던 Exception 후처리 방식과 Exception 이 아니지만 후처리 로직(leavaTrace)을 실행할 하는 방식에 대해 설명하도록 하겠다. \\
간략하게 보면 \\
Exception 후처리 방식은 ** AOP(pointCut => after-throw) => ExceptionTransfer.transfer() => ExceptionHandlerService => Handler ** 순으로 실행된다. \\
LeavaTrace 는 AOP를 이용하는 구조는 아니고 Exception 을 발생하지도 않는다. 단지 후처리 로직을 실행하도록 하고자 함에 목적이 있다.\\
실행 순서는 ** LeavaTrace => TraceHandlerService => Handler ** 순으로 실행한다. \\
먼저 Exception Handling 에 대해 알아보도록 하자.
==== Aop Config, ExceptionTransfer 설정 및 설명 ====
----
=== Bean 설정 ===
Exception 후처리와 leaveaTrace 설정을 위해서 샘플에서는 두개의 xml 파일을 이용한다. (context-aspect.xml, context-common.xml)
먼저 Exception 후처리를 위한 부분을 보겠다.\\
Exception Handling 을 위한 AOP 설정은 아래와 같다. \\
비즈니스 개발시 패키지 구조는 바뀌기 때문에 Pointcut은 egov.sample.service.*Impl.*(..)) 을 수정하여 적용할 수 있다.\\
ExceptionTransfer 의 property 로 존재하는 exceptionHandlerService 는 다수의 HandleManager 를 등록 가능하도록 되어 있다.\\
여기서는 defaultExceptionHandleManager을 등록한 것을 볼 수 있다. \\
**context-aspect.xml**
...
**service.*Impl
...
defaultExceptionHandleManager는 setPatters() , setHandlers() 메소드를 가지고 있어 상단과 같이 \\
등록된 pattern 정보를 이용하여 Exception 발생 클래스와의 비교하여 ture 인 경우 handlers 에 등록된 handler를 실행한다.\\
패턴 검사시 사용되는 pathMatcher 는 AntPathMatcher 를 이용하고 있다. \\
특정 pattern 그룹군을 만든후 patterns 에 등록하고 그에 해당하는 후처리 로직을 정의하여 등록할 수 있는 구조이다. \\
=== Handler 구현체 ===
먼저 클래스에 대한 이해가 필요하다. 앞단에서 간단하게 설명을 했지만 다시 정리 하자면\\
Exception 발생시 AOP pointcut "After-throwing" 걸려 ExceptionTransfer 클래스의 transfer 가 실행된다.\\
transfer 메소드는 ExceptionHandlerManager 의 run 메소드를 실행한다. 아래는 구현예로 DefaultExceptionHandleManager 코드이다.\\
**(구현시 필수사항) 상위클래스는 AbsExceptionHandleManager 이고 인터페이스는 ExceptionHandlerService 이다.** \\
구현되는 메소드는 run(Exception exception) 인 것을 확인할 수 있다. \\
** DefaultExceptionHandleManager.java**
public class DefaultExceptionHandleManager extends AbsExceptionHandleManager implements ExceptionHandlerService {
@Override
public boolean run(Exception exception) throws Exception {
log.debug(" DefaultExceptionHandleManager.run() ");
// 매칭조건이 false 인 경우
if (!enableMatcher())
return false;
for (String pattern : patterns) {
log.debug("pattern = " + pattern + ", thisPackageName = " + thisPackageName);
log.debug("pm.match(pattern, thisPackageName) =" + pm.match(pattern, thisPackageName));
if (pm.match(pattern, thisPackageName)) {
for (ExceptionHandler eh : handlers) {
eh.occur(exception, getPackageName());
}
break;
}
}
return true;
}
}
=== Customizable Handler 등록 ===
시나리오 : CustomizableHandler 클래스를 만들어 보고 sample 패키지에 있는 Helloworld 클래스 Exception 시에 CustomizableHandler 를 실행한다.\\
먼저 CustomHandler 클래스를 아래와 같이 만든다.\\
ExceptionHandleManager 에서는 occur 메소드를 실행한다. \\
**Handler 구현체는 반드시 (필수사항) ExceptionHandler Interface를 갖는다. **
**CustomizableHandler.java**
public class CustomizableHandler implements ExceptionHandler {
protected Log log = LogFactory.getLog(this.getClass());
public void occur(Exception ex, String packageName) {
log.debug(" CustomHandler run...............");
try {
log.debug(" CustomHandler 실행 ... ");
} catch (Exception e) {
e.printStackTrace();
}
}
}
CustomizableHandler 의 등록을 해보도록 하겠다.\\
역시서 주의해야 하는 부분은 patterns 에 sample 패키지에 있는 Helloworld 클래스 를 지정해주어야 한다. \\
**sample.Helloworld
이런식으로 여러개의 Handler를 등록해줄 수 있다.
==== leaveaTrace 설정 및 설명=====
----
Exception 이거나 Exception 이 아닌 경우에 Trace 후처리 로직을 실행 시키고자 할 때 사용한다.\\
설정하는 기본적인 구조는 Exception 후처리 하는 방식과 같다. 설정파일이 context-common.xml 이다.\\
DefaultTraceHandleManager 에 TraceHandler를 등록하는 형태로 설정된다.\\
=== Bean 설정 ===
...
*
...
=== TraceHandler 확장 개발 Sample ===
** Interface TraceHandler를 아래와 같이 implements 한다. **
package egovframework.rte.fdl.cmmn.trace.handler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class DefaultTraceHandler implements TraceHandler {
public void todo(Class clazz, String message) {
//수행하고자 하는 처리로직을 넣는 부분...
System.out.println(" log ==> DefaultTraceHandler run...............");
}
}
=== leaveaTrace 코드상 발생 Sample ===
사용방법을 다시 상기 해보면 아래와 같다. \\
메세지키(message.trace.msg) 를 이용하여 메세지 정보를 넘겨 Handler 를 실행한다. \\
public CategoryVO selectCategory(CategoryVO vo) throws Exception {
CategoryVO resultVO = categoryDAO.selectCategory(vo);
try {
//강제로 발생한 ArithmeticException
int i = 1 / 0;
} catch (ArithmeticException athex) {
//Exception 을 발생하지 않고 후처리 로직 실행.
leaveaTrace("message.trace.msg");
}
return resultVO;
}
===== 참고자료 =====
* [[http://www.onjava.com/pub/a/onjava/2006/01/11/exception-handling-framework-for-j2ee.html?page=1|exception-handling-framework-for-j2ee]]
* Effective Java (Joshua Bloch) : Chapter 8 예외처리