2024. 10. 9. 17:44ㆍSpring Framework/Web on Servlet Stack
@ExceptionHandler
는 스프링 MVC에서 발생하는 예외를 처리하는 메서드를 정의할 수 있도록 해줍니다. 이 어노테이션을 사용하면 특정 예외가 발생했을 때 해당 예외를 처리하는 메서드를 지정할 수 있으며, 예외를 처리한 후 적절한 HTTP 응답을 반환할 수 있습니다.
@Controller
또는 @ControllerAdvice
클래스에서 사용되며, 예외가 발생하면 지정된 메서드가 호출됩니다.
기본 개념
- 예외 처리:
@ExceptionHandler
가 적용된 메서드는 컨트롤러에서 발생한 예외를 처리할 수 있습니다. 이 메서드는 발생한 예외 타입을 아규먼트로 받아 처리할 수 있으며, HTTP 응답을 리턴할 수 있습니다. - 예외 매칭: 예외 처리는 발생한 예외의 상위 클래스나, 중첩된 원인 예외(cause exception)에도 매칭될 수 있습니다.
- 우선 순위: 여러
@ExceptionHandler
메서드가 있을 때, 더 구체적인 예외가 먼저 처리됩니다. 기본적으로 최상위 예외가 아닌 구체적인 예외- 예외 클래스의 상속 계층에서 더 하위에 있는 예외가 먼저 처리된다는 의미 -가 우선적으로 처리됩니다. - 전역 예외 처리:
@ControllerAdvice
는 여러 컨트롤러에 걸쳐 전역적으로 예외를 처리할 수 있도록 도와줍니다.
예시 1: 기본 예외 처리
다음 예시는 IOException
이 발생했을 때 이를 처리하는 방법을 보여줍니다.
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.Controller;
import java.io.IOException;
@Controller
public class SimpleController {
@ExceptionHandler(IOException.class)
public ResponseEntity<String> handleIOException(IOException ex) {
// 예외 처리 로직
return ResponseEntity.status(500).body("IOException occurred: " + ex.getMessage());
}
}
코드 설명:
@ExceptionHandler(IOException.class)
:IOException
이 발생했을 때 이 메서드가 호출됩니다.ResponseEntity
: HTTP 응답을 리턴하는 객체로, 여기서는 500 Internal Server Error 상태 코드와 함께 오류 메시지를 리턴합니다.
예시 2: 여러 예외 처리
여러 예외 타입을 한 번에 처리하고 싶을 때, 예외 타입을 배열로 지정할 수 있습니다.
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import java.io.IOException;
import java.rmi.RemoteException;
import java.nio.file.FileSystemException;
@Controller
public class MultiExceptionController {
@ExceptionHandler({FileSystemException.class, RemoteException.class})
public ResponseEntity<String> handleFileAndRemoteExceptions(IOException ex) {
// 여러 예외 처리
return ResponseEntity.status(500).body("Error: " + ex.getMessage());
}
}
코드 설명:
@ExceptionHandler({FileSystemException.class, RemoteException.class})
: 두 가지 예외인FileSystemException
과RemoteException
을 한 번에 처리합니다.- 예외가 발생하면
IOException
을 인자로 받아 처리하며, 예외 타입에 맞는 오류 메시지를 반환합니다.
예시 3: 상위 예외 처리
모든 예외를 처리하고 싶을 때, Exception
을 아규먼트로 받아 처리할 수 있습니다. 이 경우, 모든 예외가 처리되며, 보다 구체적인 예외보다 낮은 우선순위를 가집니다.
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
@Controller
public class GlobalExceptionController {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAllExceptions(Exception ex) {
return ResponseEntity.status(500).body("An error occurred: " + ex.getMessage());
}
}
코드 설명:
@ExceptionHandler(Exception.class)
: 모든 예외를 처리하는 메서드입니다. 구체적인 예외가 없다면, 이 메서드가 호출됩니다.
예시 4: 전역 예외 처리 (ControllerAdvice)
@ControllerAdvice
는 전역적으로 예외를 처리하는 데 사용됩니다. 이를 사용하면 여러 컨트롤러에 걸쳐 동일한 방식으로 예외를 처리할 수 있습니다.
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ControllerAdvice;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(IOException.class)
public ResponseEntity<String> handleIOException(IOException ex) {
return ResponseEntity.status(500).body("Global IOException: " + ex.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneralException(Exception ex) {
return ResponseEntity.status(500).body("General error occurred: " + ex.getMessage());
}
}
코드 설명:
@ControllerAdvice
: 이 클래스는 모든 컨트롤러에 적용되어 전역적으로 예외를 처리합니다.- 두 가지
@ExceptionHandler
메서드가 각각IOException
과 모든Exception
을 처리합니다.
추가 기능: 메서드 아규먼트
@ExceptionHandler
메서드는 다양한 추가 아규먼트를 받을 수 있습니다. 이러한 인자들은 예외 처리 시 더 많은 정보를 제공합니다.
사용할 수 있는 아규먼트:
- Exception: 발생한 예외 객체를 인자로 받아 처리할 수 있습니다.
- HandlerMethod: 예외가 발생한 컨트롤러 메서드에 접근할 수 있습니다.
- WebRequest 또는 NativeWebRequest: 요청 파라미터나 세션 속성 등에 접근할 수 있습니다.
- HttpServletRequest, HttpServletResponse: 직접적인 서블릿 요청 또는 응답 객체를 사용할 수 있습니다.
- Principal: 현재 인증된 사용자에 접근할 수 있습니다.
예시 5: 추가 아규먼트 사용
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import jakarta.servlet.http.HttpServletRequest;
@Controller
public class CustomExceptionHandler {
@ExceptionHandler(IOException.class)
public ResponseEntity<String> handleIOException(IOException ex, WebRequest request, HttpServletRequest servletRequest) {
String requestUrl = servletRequest.getRequestURL().toString();
String message = "IOException at " + requestUrl + ": " + ex.getMessage();
return ResponseEntity.status(500).body(message);
}
}
코드 설명:
- WebRequest: 요청 파라미터나 세션에 접근할 수 있습니다.
- HttpServletRequest: 요청 URL 같은 서블릿 관련 데이터를 가져올 수 있습니다.
리턴값 처리
@ExceptionHandler
메서드는 다양한 형태의 리턴값을 가질 수 있습니다.
- ResponseEntity: HTTP 상태 코드와 함께 응답을 리턴합니다.
- String: 뷰 이름을 리턴할 수 있으며, ViewResolver에 의해 해석됩니다.
- ModelAndView: 뷰와 모델을 함께 리턴할 수 있습니다.
- void: 리턴값이 없을 경우, 메서드가 응답을 처리했다고 간주됩니다.
요약
@ExceptionHandler
는 특정 예외가 발생했을 때 이를 처리하는 메서드를 정의할 수 있습니다.- 여러 예외를 처리할 수 있으며, 구체적인 예외가 우선적으로 처리됩니다.
- 전역 예외 처리는
@ControllerAdvice
를 통해 모든 컨트롤러에 적용될 수 있습니다. - 다양한 인자를 사용하여 예외 처리 시 추가 정보를 받을 수 있으며, 리턴값로 다양한 형태의 응답을 생성할 수 있습니다.
이 방식은 애플리케이션에서 발생하는 예외를 효과적으로 관리하고, 사용자에게 적절한 오류 응답을 제공하는 데 매우 유용합니다.
'Spring Framework > Web on Servlet Stack' 카테고리의 다른 글
@RequestParam (0) | 2024.10.09 |
---|---|
Controller Advice (0) | 2024.10.09 |
Validation (0) | 2024.10.09 |
@InitBinder (0) | 2024.10.09 |
Model (0) | 2024.10.09 |