티스토리 뷰

DEV/Java

예외처리 with Spring

berom 2023. 5. 26. 14:22

Spring 예외 처리

Spring 프레임워크에서는 @ExceptionHandler, @ControllerAdvice, @ResponseStatus 등의 애노테이션을 사용하여 예외 처리를 합니다.

@ExceptionHandler

@ExceptionHandler@Controller 클래스 내에서 발생하는 예외를 처리하는 데 사용되는 애노테이션입니다.
이는 예외를 처리하는 메서드 내부에서 사용되어야 합니다.

@Controller
public class ExceptionController {
    @ExceptionHandler({NullPointerException.class, FileNotFoundException.class})
    public String handleException(Exception ex, Model m) {
        m.addAttribute("ex", ex);
        return "error";
    }
}

이 경우, ExceptionController 클래스의 메서드에서 NullPointerException 또는 FileNotFoundException이 발생하면 handleException 메서드가 호출됩니다.

위처럼 하나의 메소드에서 여러 예외를 한 번에 처리 할 때는 배열을 사용하는 것이 좋다

이 때 주의 해야 할 점이 하나있다.

@Controller
public class ExceptionController {
    @ExceptionHandler(Exception.class)
    public String handleException(Exception ex, Model m) {
        m.addAttribute("ex", ex);
        return "error";
    }
    @RequestMapping("/ex")
    public String main(Model m) throws Exception{
	    ~~~ Code ~~~~
    }
}

예외 핸들러와 main 메소드의 모델 m은 서로 다른 객체이다
둘 다 m이라고 해도 handleException 메서드와 main 메서드의 Model 인스턴스는 서로 다른 개체이다

요청을 처리하기 위한 것과 요청 처리 중 예외를 처리하기 위한 별도의 요청 수명 주기 내에 존재하기 때문이다

@ControllerAdvice

@ControllerAdvice는 전체 애플리케이션에서 예외를 처리하는 하나의 전역 처리 컴포넌트로 사용되는 애노테이션이다.
이는 @RequestMapping으로 주석 처리된 메서드에서 발생하는 예외의 인터셉터로 생각할 수 있습니다.

//@ControllerAdvice("com.campus.ch2") 지정된 패키지에만 적용
@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    public String defaultErrorHandler(Exception e, Model model) {
        model.addAttribute("exception", e);
        return "error";
    }
}

이 경우, 애플리케이션에서 처리되지 않은 예외는 모두 defaultErrorHandler 메서드에서 잡아 처리됩니다.

@ResponseStatus

@ResponseStatus는 응답 메시지의 HTTP 상태를 변경하는 데 사용되는 애노테이션입니다.
이는 예외 클래스에 추가하거나 @ExceptionHandler로 주석 처리된 메서드에 추가할 수 있습니다.

@Controller
public class ExceptionController {

    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 200 -> 500 (status code change)
    public String handleAllExceptions(Exception ex, Model m) {
        m.addAttribute("ex", ex);
        return "error";
    }
}

이 경우, 일반 Exception이 발생할 때마다 서버는 500 (Internal Server Error) HTTP 상태 코드로 응답합니다.

이는 오류가 발생했지만 요청이 성공적으로 처리되었다는 표시를 하고 싶지 않은 상황에서 유용합니다.

예외 처리 우선 순위 및 Scopde

예외 처리는 인접성 규칙을 따릅니다. 만약 예외를 처리하는 메서드가 가까운 컨트롤러에 이미 있다면, 그 메서드가 먼저 예외를 처리합니다.

즉, 컨트롤러 내의 @ExceptionHandler와 전역 @ControllerAdvice가 동일한 예외를 처리하는 경우, 컨트롤러 내의 핸들러가 우선적으로 적용됩니다.

부족한 점이나 잘못 된 점을 알려주시면 시정하겠습니다 :>

728x90