티스토리 뷰
안녕하세요. 오늘은 대선날입니다. 다들 투표는 잘하셨는지요? 저는 사전 투표를 하지 못해서 오늘 할까 합니다. 오전에는 잠깐 볼일이 있어서 잠깐 보느라 못하고.. 나가기 전에 포스트를 작성하려고 정리해뒀던 게 생각나서 지금 이 포스트를 마무리 지은 후 점심을 간단하게 챙겨 먹고 저도 투표를 하러 가야겠습니다. 과연 현재 대통령이 없는 무정부(?) 상태에서 새정부가 오늘 바로 출범한다고 생각하니 매우 기대가 됩니다.
자 그럼, 나가기 전에 정리해뒀던 포스트 내용이 무엇이냐 함은... 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 들을 추가하여 처리하면 될 것 같습니다.
그럼 포스트는 이만 마치도록 하고 어서 투표를 하러가보도록 하겠습니다! 다들 즐거운 하루 되시길 바랍니다.
'프로그래밍' 카테고리의 다른 글
MongoDB 간략한 정리. (0) | 2017.06.06 |
---|---|
자바스크립트 클로저, JavaScript Closure (0) | 2017.05.14 |
[Javascript] PC, MOBILE 구분하기 (Navigator 사용) (3) | 2017.04.09 |
Javascript 생년월일로 나이 구하기. (+Oracle 추가) (0) | 2017.04.03 |
Unsupported major.minor version 51.0 오류 (0) | 2017.03.28 |
- Total
- Today
- Yesterday
- 빈트후크
- Oracle
- 볼리비아
- Cusco
- 빅토리아폴스
- 쿠스코
- 후마리
- 애드센스
- 우유니
- aguas calientes
- 족발
- 푸에르토 나탈레스
- 성스러운 계곡
- Cambodia
- 남미 저가항공
- 칠레
- 남미
- 아구아스 칼리엔테스
- Namibia
- 나미비아
- 마추피추
- 캄보디아
- 킹덤 호텔
- Uyuni
- calama
- 성계 투어
- 칼라마
- 햄버거
- jQuery
- 토레스 델 파이네
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |