개발이군고구마

DispatcherServlet의 예외 처리 과정 본문

SERVER/Spring

DispatcherServlet의 예외 처리 과정

김구황 2025. 7. 11. 08:49
728x90
Problem
  • viewReolsver에 viewname이 null 값으로 들어가는 코드 존재하여 오류와 다른 화면이 사용자에게 노출되고 있음 

 

Cause 

 

개념

  1. model and view 응답처리 

    • DispatcherServler 에게   ModelAndView 객체 를 넘김 
      viewName엔 화면 페이지가 있는 경로
    • ViewResolver 체인 실행 & InternalResourceView 생성
      • DispatcherServlet의 render(ModelAndView, …) 내부에서, 등록된 ViewResolver 순서대로 resolveViewName("/good/detail" , locale)을 호출
      • 보통 마지막에 등록된 InternalResourceViewResolver가 동작하여 InternalResourceView 객체의 url 생성 
      • prefix 와 suffix는 설정에서 등록해줌 (jsp 파일이 있는 경로) 
        String url = prefix + viewName + suffix;
    • JSP 포워드 시도
      • DispatcherServlet이 InternalResourceView.doRender(model, request, response)를 호출
        RequestDispatcher rd = request.getRequestDispatcher(dispatcherPath); 
        if (rd == null) { throw new ServletException("Could not get RequestDispatcher for [" + getUrl() + "]"); }
  2. 에러가 발생할 때  
    • DispatcherServlet → HandlerExceptionResolver → WAS 전파
      • DispatcherServlet.processDispatchResult()의 processHandlerException()으로 넘어감
      • webApplicationContext에 등록된 HandlerExceptionResolver 빈 목록을 순서대로 조회 HandlerExceptionResolver(예: ExceptionHandlerExceptionResolver, ResponseStatusExceptionResolver 등) 중에 처리할 수 있는 핸들러 찾는다. 
      •  resolveException() method는 return type이 ModelAndView로, 예외 노출에 사용될 View와 그 안에 포함될 내용을 담은 Model 객체를 return 하게 됨 
      • 처리할 수 있는 핸들러가가 없으면, 예외는 그대로 최상위로(톰캣/제티 등 WAS) 전파
    • WAS의 에러 페이지 매핑 및 표시
      • 해당 위치의 JSP로 포워드하여 커스텀 에러 페이지를 렌더링
      • 별도의 매핑이 없으면, WAS(예: Tomcat)는 기본 HTTP 500 Internal Server Error 페이지

 

✅ 원인

  • JSP 포워드 시도 중 ServletException 발생
    • dispatcherPath가 null이어서 rd가 null이 되고, ServletException이 던져짐
  • 별도의 매핑이 없으면, WAS(예: Tomcat)는 기본 HTTP 500 Internal Server Error 페이지

 

Solution 
  1. 간단하게 에러페이지로 redirect
    • page not found로 처리 
  2. 정확하게 메세지 
    • new CustomException 객체에 메세지 담아서 보내기 => 런타임 익셉션
    • 정확한 메세지로 예외처리가 가능함 

 

 

✅ 해결책과 관련된 개념 정리 

ㄴ 같은 ExceptionHandlerExceptionResolver 체인의  반환 타입(뷰 vs. 데이터)

 

1) 뷰

  • 뷰 포워딩 : HandlerExceptionResolver 중 
    • ExceptionHandlerExceptionResolver ModelAndView를 만들어 JSP 뷰로  포워딩 또는 
    • DefaultHandlerExceptionResolver가 특정 예외에 매핑된 에러 뷰로 포워딩
  • 뷰 렌더링 : InternalResourceViewResolver → RequestDispatcher.forward("/WEB-INF/views/error.jsp")
  • 에러 상태 코드를 ServletException이나 sendError()로 설정 후 JSP 렌더링

2) 데이터 (메세지 처리) 

  • @RestControllerAdvice + @ExceptionHandler 예외 핸들러가 객체를 ResponseEntity<ErrorDto> 반환
  • ExceptionHandlerExceptionResolver가 이 반환값을 받아 HttpMessageConverter로 JSON 직렬화
  • HTTP 응답 스트림에 JSON 바디를 씀