티스토리 뷰

안녕하세요. 오늘은 대선날입니다. 다들 투표는 잘하셨는지요? 저는 사전 투표를 하지 못해서 오늘 할까 합니다. 오전에는 잠깐 볼일이 있어서 잠깐 보느라 못하고.. 나가기 전에 포스트를 작성하려고 정리해뒀던 게 생각나서 지금 이 포스트를 마무리 지은 후 점심을 간단하게 챙겨 먹고 저도 투표를 하러 가야겠습니다. 과연 현재 대통령이 없는 무정부(?) 상태에서 새정부가 오늘 바로 출범한다고 생각하니 매우 기대가 됩니다. 


자 그럼, 나가기 전에 정리해뒀던 포스트 내용이 무엇이냐 함은... SpringFramework 의 오류처리에 관련된 Resolver 에 관한 내용입니다. 보통 SpringFramework 를 사용하면서 Exception 발생 시 사용자 브라우저에 지저분한 소스코드와 함께 오류페이지를 보여주지 않기 위해 에러 페이지 대한 처리를 web.xml 에 정의하여 왔습니다. 이런식으로 말이죠.


<error-page>

<error-code>404</error-code>

<location>/exception_404.jsp</location>

</error-page>

<error-page>

<error-code>500</error-code>

<location>/exception_500.jsp</location>

</error-page>

</error-page>


그런데 HandlerExceptionResolver 를 사용하면 Exception 발생 시 에러 페이지 처리에 대해 좀 더 유연하게 대처 할 수 있다는 것을 알게 되었습니다. 아... 최근 HttpServletRequest 의 Parameter 값을 변경하는 것도 그렇고 이런 Exception 관련 처리도 그렇고 .. 전 지금까지 대체 무엇을 알고 개발을 해왔던 것인지.. 정말 다시 되돌아 보게 되네요. -_-;;


아무튼 Controller, Service, Dao 를 거치면서 업무 프로세스를 처리 시에 발생된 예외는 DispatcherServlet 이 가장 먼저 전달 받아 예외 처리에 대한 Resolver 가 없다면 ServletContainer 에게로 전달되어 브라우저에는 404, 500 등 오류 메시지가 그대로 노출이 됩니다. 만약 HandlerExceptionResolver 에 대한 처리가 구현되어 있다면 DispatcherServlet 은 해당 HandlerExceptionResolver 에게 발생된 예외 처리에 대한 구현이 되어 있는 지 확인하여 처리가 되어 있다면 해당 HandlerExceptionResolver 에게 처리를 위임을 합니다. 그리고 이 HandlerExceptionResolver 에서는 ModelAndView 를 리턴하여 처리 하는 등 Controller 처럼 처리가 가능하게 해줍니다. HandlerExceptionResolver 를 살짝 살펴보자면 ModelAndView 를 리턴하는 아래 메소드 하나로 정의되어 있는걸 볼 수 있습니다.


package org.springframework.web.servlet;


import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


public abstract interface HandlerExceptionResolver {

public abstract ModelAndView resolveException(HttpServletRequest paramHttpServletRequest, HttpServletResponse paramHttpServletResponse, Object paramObject, Exception paramException);

}


그러므로 오류 처리에 관한 로직을 구현하려 한다면 이 resolveException 을 Override 하여 구현하면 되겠습니다. 현재 사용중인 부분을 살짝 바꾼 간단한 예제를 보도록 하겠습니다.


아래의 ServiceException 은 현재 진행중인 프로젝트에서 MessageException 을 상속받아 별도 구현한 ServiceException 입니다. 보통 SpringFramework 를 사용하실 때, 아 MVC 패턴을 사용할 때라고 해야 할까요? 아무튼. Service 는 ServiceException, Dao 는 DaoException 으로 별도 구현해서 많이 쓰시고 계신걸로 알고 있습니다. (아닌가요? -_-;; 저만 지금까지 그래왔나요? -_-;;) 아무튼 별도로 구성한 ServiceException 이라는 것을 참고하시고 보시면 되겠습니다.


1. xml 에 resolver 정의.

<bean name="exceptionResolver" class="customer.common.CustomerBaseExceptionResolver" />


2. CustomerBaseExceptionResolver 클래스 구현

public class CustomerBaseExceptionResolver implements HandlerExceptionResolver {

private static final Log logger = LogFactory.getLog(getClass());

@Override

public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object params, Exception ex) {

Configuration configuration = ConfigService.getInstance().getConfiguration();

ModelAndView mav = null;

// 아래 부분은 ADMIN, FRONT 에 대한 구분으로 개개인의 필요에 따라 없어도 상관없습니다.

        String workServer = configuration.getString(ServerUtil.getServerName(request));

if ("ADMIN".equals(workServer)) {

mav = adminException(request, response, params, ex);

} else {

mav = frontException(request, response, params, ex);

}

        

        return mav;

}

/**

     * ADMIN EXCEPTION

     * @param   HttpServletRequest _request, HttpServletResponse _response, Object params, Exception ex

     * @return  ModelAndView

     */

    public ModelAndView adminException(HttpServletRequest _request, HttpServletResponse _response, Object params, Exception ex){

String errorMsg = "";

        

        if(ex instanceof ServiceException){

            ServiceException se = (ServiceException)ex;

// 로그 추적을 위해 해당 오류 관련 내용을 서버에 한번 출력합니다..

            se.printStackTrace();

errorMsg = "ADMIN ServierException";

        }else{

         ex.printStackTrace();

            errorMsg = "ADMIN Exception";

        }

        

        _request.setAttribute("errMsg", errMsg);

        return new ModelAndView("/views/admin/exception/exception"); // /view/admin/exception/exception.jsp 호출

    }


    /**

     * FRONT EXCEPTION

     * @param   HttpServletRequest _request, HttpServletResponse _response, Object params, Exception ex

     * @return  ModelAndView

     */

    public ModelAndView frontException(HttpServletRequest _request, HttpServletResponse _response, Object params, Exception ex){

String errorMsg = "";

        

        if(ex instanceof ServiceException){

            ServiceException se = (ServiceException)ex;

// 로그 추적을 위해 해당 오류 관련 내용을 서버에 한번 출력합니다.

            se.printStackTrace();

errorMsg = "FRONT ServierException";

        }else{

         ex.printStackTrace();

            errorMsg = "FRONT Exception";

        }

        

        _request.setAttribute("errMsg", errMsg);

        return new ModelAndView("/views/front/exception/exception"); // /view/front/exception/exception.jsp 호출

    }

}



이렇게 위에 먼저 말씀드렸던 resolveException 을 Override 하여 로직을 구현하였습니다. 위의 예제에는 ServiceException 외에는 모두 Exception 으로 처리하였지만 SQLException, IOException 등 원하는 Exception 들을 추가하여 처리하면 될 것 같습니다.


그럼 포스트는 이만 마치도록 하고 어서 투표를 하러가보도록 하겠습니다! 다들 즐거운 하루 되시길 바랍니다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함