스터디 노트/잡것

Exception

webmaster 2021. 12. 26. 16:08
728x90

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Exception.html

 

Exception (Java SE 17 & JDK 17)

All Implemented Interfaces: Serializable Direct Known Subclasses: AbsentInformationException, AgentInitializationException, AgentLoadException, AlreadyBoundException, AttachNotSupportedException, AWTException, BackingStoreException, BadAttributeValueExpExc

docs.oracle.com

https://www.nextree.co.kr/p3239/ 참고 

  • 모든 예외 클래스는 Throwable 클래스를 상속받고 있다.
  • Throwable을 상속받는 클래스는 Error와 Exception이 있습니다.
    • Error = 응용 프로그램이 포착하려고 해서는 안 되는 심각한 문제를 나타내는 하위 클래스입니다
      • 해당 에러는 try-catch, throws Exception을 하여도 해결되지 않기에 해당 문법을 사용하지 않는다.
    • Exception = 클래스 Exception 및 해당 하위 클래스는 Throwable합리적인 응용 프로그램에서 포착할 수 있는 조건을 나타내는 형식입니다
    • Exception 같은 경우 수많은 하위 클래스가 존재하지만 이 중, RuntimeException과 그 외 예외로 나뉜다.

CheckedException VS UnCheckedException

  • RuntimeException의 UnCheckedException, 그 외 Exception을  CheckedException이라고 한다.
  • CheckedException 같은 경우 컴파일 단계에서 반드시 예외를 처리하여야 한다.
    • throws Exception과 try-catch를 해주어야지만 컴파일 오류를 해결할 수 있다.
  • UnCheckedException 같은 경우 실행단계에서 명시적 처리를 강제하지 않는다.
    • NullPointException, IllegalArgmentException 같은 경우 충분히 피해갈 수 있지만 개발자의 부주의에 의해서 발생한 것이므로, 런타임 예외이다.
  • 트랜잭션 같은 경우 checkedException 같은 경우 rollback을 하지 않지만, uncheckedException 같은 경우 rollback을 진행해준다.

Spring에서의 Exception 처리과정

Spring 구조

  • 그렇다면 Spring에서는 예외가 어떻게 발생되고 어떻게 처리를 해주어야 할까?
  • Spring에서의 예외가 발생하는 부분은 크게 두 가지로 나눌 수 있다
    • Dispatcher Servlet내에서 발생하는 예외 (Controller, Service, Repository 등등)
    • Dispatcher Servlet전의 서블릿 (Filter)에서 발생하는 예외
  • 스프링 MVC 에러 중 99프로는 DispatcherServlet에서 발생하기 때문에 DispatcherServlet내에서 발생하는 예외를 내부에서 자체적으로 해결할 수 있다

DispatcherServlet에서 발생한 예외 처리

    • DispatcherServlet 내에서의 에러를 처리하는 방식에는 크게 3가지가 존재한다.
      1. Controller 레벨에서 처리
      2. Global 레벨에서 처리
      3. HandlerExceptionResolver를 이용한 처리
    •  Controller 레벨에서의 처리
      • Controller에서 발생한 예외에 대해 Common 하게 처리할 수 있는 기능을 제공
      • @ExceptionHandler 어노테이션을 통해 Controller의 메서드에서 throw된 Exception에 대한 공통적인 처리를 할 수 있도록 지원
      • 예시
      • DemoController내에서 발생한 DemoException에 대해서는 handleDemoException 메소드에서 모두 처리를 해준다
        • Controller 메소드 내의 하위 서비스에서 Checked Exception이 발생하더라도, Controller 메소드 상위까지 예외를 throw 시키면@ExceptionHandler 어노테이션을 사용하여 Controller 전역적으로 예외처리가 가능하다
        • Controller 메소드 내의 하위 서비스에서 Runtime Exception이 발생하면, 서비스를 호출한 최상위 Controller에서 해당 예외를 처리해준다.
    • Global 레벨에서 처리
      • 만약 여러 Controller에서 같은 Exception이 발생하는 경우엔 어떻게 해야 할까?
      • 위의 방식처럼 Controller 별로 @ExceptionHandler 어노테이션이 붙은 메서드를 만들게 된다(유지보수성 증가, 중복 코드 양산)
      • Spring에서는 이를 방지하기 위해 Web Application 전역적으로 @ExceptionHandler를 사용할 수 있도록 지원한다.
        • @ControllerAdvice - Exception 처리 후 Error Page 등을 통해 처리가 가능하다
          • ControllerAdvice를 사용하여 Exception 처리를 한 곳으로 모으는 경우, ResponseEntityExceptionHandler를 상속받도록 하여 Spring MVC에서 기본으로 제공되는 Exception들의 처리를 간단하게 등록할 수 있다. 각 Exception 처리를 위한 메서드들은 모두 protected로 선언되어 있으며, 하위 클래스에서 필요에 따라 Override 할 수 있다.
        • @RestControllerAdvice
          • REST API에 대한 Exception 처리 등에 용이. (Default 데이터를 리턴해 줄 수 있다.)
          • @RestControllerAdvice = @ControllerAdvice + @ResponseBody
      • @ExceptionHandler, @ControllerAdvice 클래스 내의 @ExceptionHandler 둘 중 뭐가 먼저 실행될까? 그리고 둘 다 실행 될까?
        • @Controller내의 @ExceptionHandler로 예외처리를 하게 되면 거기서 예외처리가 끝난다. 더 상위로 Exception을 throw 하더라도@ControllerAdvice의 @ExceptionHandler에서 예외처리를 하지 않는다
    • HandlerExceptionResolver를 이용한 처리
      • Controller의 작업 중에 발생한 예외를 어떻게 처리할 지에 대한 전략이다
      • DispatcherServlet내에서 예외 발생 시, resolverException 메서드를 구현한 HandlerExceptionResolver들이 실행 계획에 따라 처리되며 예외를 처리하게 된다.
      • 사실 위에서 본 2가지 방식의 예외처리도 HandlerExceptionResolver를 이용한 예외 처리 방법이다
      • Dispatcher Servlet에 기본적으로 3개의 HandlerExceptionResolver가 등록되어있다.
        1. ExceptionHandlerExceptionResolver
        2. ResponseStatusExceptionResolver
        3. DefaultHandlerExceptionResolver
      • ExceptionHandlerExceptionResolver
        • Spring 3.2 때 AnnotationMethodHandlerExceptionResolver라는 이름으로 등장하였다.
        • 현재는 Deprecated처리되어 ExceptionHandlerExceptionResolver 클래스를 사용하고 있다. 위에서 사용한@ExceptionHandler어노테이션에 대한 Resolver 클래스이다.
      • ResponseStatusExceptionResolver
        • ResponseStatusExceptionResolver는 예외에 대한 Http 응답을 설정해 줄 수 있다.
        • 특정 예외가 발생하였을 때 , 단순히 500 (internal-server-error) 대신 더 구체적인 응답 상태 값을 전달해 줄 수 있다.
      • DefaultHandlerExceptionResolver
        • DispatcherServlet에 디폴트로 등록된 3가지 HandlerExceptionResolver에서 예외처리를 하지 못하는 경우, 마지막으로 DefaultHandlerExceptionResolver에서 예외처리를 해준다.
        • DefaultHandlerExceptionResolver에서는 내부적으로 Spring 표준 예외처리를 해준다. 각 상황에 걸맞은 응답 코드를 리턴해 주는 역할을 한다.
          • Request URL에 맞는 Controller를 못 찾는 경우 ==> 404 Not Found
          • Controller 메서드 실행 중 예외가 발생하는 경우 ==> 500 Internal Server error
          • Controller의 파라미터 형식이 잘못된 경우 ==> 400 Bad Request

Filter에서 발생한 예외 처리

    • Web Application 레벨에서 처리를 해줘야 한다.
    • filter에서 예외가 발생하면 여태까지 말한 예외처리 방법이 적용되지 않는다. 왜냐? 실제 Dispatcher Servlet에서 처리하기도 전에 예외가 발생되기 때문이다.
    • web.xml에 error-page를 잘 등록해줘서 에러를 사용자에게 표현
    • Filter 내부에서 try-catch 구문을 통해 예외 발생 시, request.getRequestDispatcher(String)를 통해 어떻게든 Controller까지 예외를 보내서 처리하게 한다.

 

 

 

참고 : https://jaehun2841.github.io/2018/08/30/2018-08-25-spring-mvc-handle-exception/#responsestatusexceptionresolver

 

Spring Handle Exception | Carrey`s 기술블로그

들어가며 Spring에서 제공하는 예외처리 방법에는 유용한 방법들이 몇가지 있다. Dispatcher Servlet내에서는 몇 가지 HandleExceptionResolver를 제공하여 예외 처리를 할 수 있도록 돕고 있다. 또한 @Controller

jaehun2841.github.io

 

참고 : https://exhibitlove.tistory.com/276

 

[spring boot] error 처리

출처 : velog.io/@leyuri/springboot-blog-project-72 @ControllerAdvice //어디에서 발생하던 간에 이쪽으로 오게 하기 위해서, 전역적으로 예외 처리 @RestController public class GlobalExceptionHandler { //..

exhibitlove.tistory.com

 

728x90

'스터디 노트 > 잡것' 카테고리의 다른 글

채널  (0) 2022.12.12
Patch Null 체크  (0) 2022.06.29
트러블 슈팅  (0) 2022.05.11
프로젝트에 도움이 되는 URL  (0) 2022.05.02
Null Object pattern  (0) 2022.01.17