@ExceptionHandler는 스프링 MVC에서 컨트롤러 내부에서 발생하는 예외를 처리하기 위해 사용되는 어노테이션입니다.
기본적인 사용 방법은 다음과 같습니다:
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
// 컨트롤러의 다른 메서드들...
}
여러 예외를 한 메서드에서 처리할 수 있습니다:
@ExceptionHandler({UserNotFoundException.class, UserNotAuthorizedException.class})
public ResponseEntity<String> handleUserExceptions(Exception ex) {
if (ex instanceof UserNotFoundException) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
} else if (ex instanceof UserNotAuthorizedException) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.FORBIDDEN);
}
return new ResponseEntity<>("An unexpected error occurred", HttpStatus.INTERNAL_SERVER_ERROR);
}
예외의 계층 구조를 활용하여 처리할 수 있습니다:
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> handleRuntimeExceptions(RuntimeException ex) {
// RuntimeException과 그 하위 예외들을 모두 처리
return new ResponseEntity<>("A runtime error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
예외 발생 시 반환할 응답 본문을 커스터마이즈할 수 있습니다:
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
ErrorResponse error = new ErrorResponse("USER_NOT_FOUND", ex.getMessage());
return new ResponseEntity<>(error, HttpStatus.NOT_FOUND);
}
@ExceptionHandler를 @ControllerAdvice와 함께 사용하면 전역 예외 처리가 가능합니다:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(UserNotFoundException.class)
public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleAllExceptions(Exception ex) {
return new ResponseEntity<>("An error occurred: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@ExceptionHandler@ControllerAdvice 클래스 내부의 @ExceptionHandler@ExceptionHandler가 적용된 컨트롤러를 테스트할 때:
@WebMvcTest(UserController.class)
class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void testHandleUserNotFound() throws Exception {
mockMvc.perform(get("/users/999"))
.andExpect(status().isNotFound())
.andExpect(content().string("User not found with id: 999"));
}
}
@ExceptionHandler는 해당 컨트롤러 내에서만 동작합니다. 전역 처리가 필요하면 @ControllerAdvice를 사용하세요.@ExceptionHandler는 스프링 MVC에서 예외를 우아하게 처리할 수 있게 해주는 강력한 도구입니다. 이를 통해 개발자는 예외 상황에 대해 세밀하게 대응할 수 있으며, 사용자에게 더 나은 경험을 제공할 수 있습니다. @ControllerAdvice와 결합하여 사용하면 애플리케이션 전반의 일관된 예외 처리 전략을 구현할 수 있습니다. 적절한 예외 처리는 애플리케이션의 안정성과 사용자 경험을 크게 향상시킬 수 있으므로, 이 기능을 효과적으로 활용하는 것이 중요합니다.
@ControllerAdvice
@RestController
@ResponseStatus
@ResponseBody
@RequestMapping