대빵's Blog

Spring MVC 에서 Exception 처리 설계 - 2부 본문

개발관련

Spring MVC 에서 Exception 처리 설계 - 2부

bigzero 2016. 12. 7. 10:06

난, Exception 을 Valid/Application/System 세가지로 나눴다. 그럼 이것을 Spring 에 적용해 보자. 

Spring MVC 환경 에서는 Exception 을 처리할 수 있는 방법이 크게 세가지 정도 있는 것 같다. 

ControllerAdvice, Context, web.xml 이 정도 있는 것 같다. 

물론 try-catch 로 잡으면 한도 끝도 없고, web.xml 는 spring 범위가 아니지만 웹어플리케이션 환경에서 Exception 을 방만하게 관리하면 차후 버그나 에러가 발생했을때 헬을 맛볼 수도 있기 때문에 이 세가지 에러처리방법에 Exception 처리를 집중시키기로 했다.


1. web.xml 

. 뭐....사용법은 인터넷에 나온 그대로 이고 문제는 어떤방식으로 Exception 을 잡아서 처리하느냐 인것 같다. 404, 500 에러등은 내가 예상은 했지만 어떻게 할 수 없는 에러. 즉, Application Exception 에 포함된다. 그래서 별도의 에러처리 화면은 보여주던지....Ajax 계열 사용환경이면 Message 를 사용자에게 Response 할 수 있는 별도의 Exception Handler 를 구현해서 View 에 Text로 전달하는 방식등을 사용하면 될 것 같다. 

또다른 한가지는 java.lang.Throwable 을 잡아서 System Exception 으로 처리하는 방안이다. 일단 서버로 들어온 Request 는 서버에서 Exception 을 잡아낼 수 있고 이것의 최후의 보루가 web.xml 이므로 이에 대한 처리를 추가한다.


예를 들면

<!-- Application Exception -->

 <error-page>
     <error-code>404</error-code>
     <location>/error/ajaxErrorResponseFlush.do</location>

</error-page>
<error-page>
    <error-code>500</error-code>
    <location>/error/500용에러페이지.jsp</location>
</error-page>

<!-- System Exception -->
<error-page>
    <exception-type>java.lang.Throwable</exception-type>
    <location>/너도500용에러페이지로가라.jsp</location>
</error-page>


web.xml 에 Valid Exception 처리를 추가할 수 도 있겠지만 내가 처리가능한 에러를 여기에 나열하는 건 일단 지저분하고 error-tag 를 한 없이 들려야 하기 때문에 당연히 지양해야 한다. 또한, log.error 를 분석해서 500/Throwable 에러들중 사전에 체크 가능한 것들은 Valid Exception 으로 처리하도록 Refactoring 해야 한다.


2. Context Exception 처리

보통 Spring MVC 에서 어플리케이션 컨텍스트(주로 application-context.xml) 하위에 웹 컨텍스트(servlet-context.xml)를 별도로 구성하는데 여기에 Exception Handler를 구성해서 Exception 을 구성한다.

만일, Controller Layer 뒤에 있는 Service, DAO Layer 에서 throws Exception 해서 무조건 Controller Layer로 Exception 이 모이는 환경을 구성하는 경우 컨텍스트에는 사실 Exception 을 구성할게 없다. 주로 Spring 환경설정이나 장애 등으로 나오는 Exception 들만 들어올 것이다.

그렇지 않고 어플리케이션 컨텍스트에서 별도로 Exception 을 던지는 환경(예:myBatis-context.xml). 즉, Service/DAO Layer에서 throws Exception 하지 않고 Runtime Exception 들이 발생되는 환경이라면 Exception Handler 를 어플리케이션 컨텍스트에 구성하던지 AOP 로 구성해야 된다.


간단한 Spring SimpleMappingExceptionResolver 예제는 아래와 같다.


<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">

<!-- Application Exception -->

        <property name="mappedHandlers">
            <map>
                <entry key="BizProcessLayerException" value="error/bizProcessError" />
                <entry key="WebServiceLayerException" value="error/webServiceError" />
                <entry key="DBServiceLayerException" value="error/dbServiceError" />
                <entry key="DAOLayerException" value="error/daoError" />
            </map>
        </property>

<!-- System Exception -->

        <property name="defaultErrorView" value="error/defaultError" />
    </bean>


여기서도 Application/System Exception 두가지 종류가 발생한다. 각 Layer 별로 내가 Exception 이 발생될 것이다 예상(사실 예상이라기 보다는 그냥 에러지만 어쨌든 최소한 발생 Layer 라도 알 수 있으니 Application Exception 이라고 했다) 가능한 Exception 처리를 구성한다. 그외 default 는 아몰랑 이다.....ㅡㅡ;


3. ControllerAdvice

ControllerAdvice 에 Exception Handler 를 구성해서 처리하는 경우는 좀 복잡하다. 이 녀석이 각각의 Controller 에 Exception Handler 를 별도로 구성해서 작동하는 것처럼 작동해 주는데 그러다 보니 ControllerAdvice에 모든 Controller에서 발생되는 Exception 이 집중된다. 

만일 Controller Layer 이외에 Service/DAO 에서도 throws Exception 하는 환경이라면 처리해야 될 에러의 양이 엄청 많아진다.     - 3부계속.......