스프링 MVC | 예외 처리

Faithful Dev·2025년 2월 25일

스프링 프레임워크

목록 보기
13/20

스프링 MVC에서 예외 처리는 애플리케이션에서 발생할 수 있는 오류를 효과적으로 처리하고, 사용자에게 명확한 에러 메시지를 제공하거나, 로깅을 통해 문제를 진단할 수 있도록 돕는 중요한 기능이다. 스프링에서는 다양한 방식으로 예외 처리를 지원하며, 주로 다음과 같은 방법들이 사용된다:


@ExceptionHandler 어노테이션 사용 (Controller) 수준

  • 특정 컨트롤러에서 발생하는 예외를 처리할 수 있다.
  • 해당 메서드는 처리할 예외 유형을 명시하며, 반환 값으로 뷰 이름, 응답 객체 등을 반환할 수 있다.
@Controller
public class SampleController {
	
    @GetMapping("/example")
    public String example() {
    	if (true) {
        	throw new IllegalArgumentException("잘못된 입력입니다.");
		}
        return "example";
	}
    
    @ExceptionHandler(IllegalArgumentException.class)
    public ResponseEntity<String> handleIllegalArgumentException(IllegalArgumentException ex) {
    	return new ResponseEntity<>("에러 발생: " + ex.getMessage(), HttpStatus.BAD_REQUEST);
	}
}
  • 위의 예제에서는 IllegalArgumentException이 발생하면 HTTP 400 상태 코드와 함께 메시지를 반환한다.

@ControllerAdvice 어노테이션 사용 (전역 예외 처리)

  • 모든 컨트롤러에서 발생하는 예외를 공통적으로 처리할 수 있다.
  • 여러 예외를 중앙에서 관리하기에 유지보수가 용이하다.
@ControllerAdvice
public class GlobalExceptionController {
	
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleAllExceptions(Exception ex) {
    	return new ResponseEntity<>("예기치 못한 에러가 발생했습니다: " + ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
	}
    
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
    	return new ResponseEntity<>("리소스를 찾을 수 없습니다.", HttpStatus.NOT_FOUND);
	}
}
  • 이 방식은 모든 컨트롤러에 대해 적용되므로, 코드의 재사용성과 일관성을 높인다.

ResponseEntityExceptionHandler 상속 (고급 예외 처리)

  • 스프링에서 기본 제공하는 예외 처리를 커스터마이징할 때 사용한다.
  • REST API 개발 시 주로 활용된다.
@RestControllerAdvice
public class CustomRestExceptionHandler extends ResponseEntityExceptionHandler {

	@Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex,
    															  HttpHeaders headers,
                                                                  HttpStatus status,
                                                                  WebRequest request) {
		Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getFieldErrors().forEach(error ->
        	errors.put(error.getField(), error.getDefaultMessage())
		);
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
	}
}
  • 주로 입력값 유효성 검사(Validation) 오류를 처리할 때 사용된다.

SimpleMappingExceptionResolver (뷰 기반 예외 처리)

  • 예외 발생 시 특정 뷰로 리다이렉트할 때 유용하다 (주로 JSP 기반 앱에서 사용).
@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
	SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
    Properties mappings = new Properties();
    mappings.setProperty("java.lang.Exception", "error/error");
    mappings.setProperty("java.lang.RuntimeException", "error/runtime-error");
    resolver.setExceptionMappings(mappings);
    return resolver;
}
  • 예외에 따라 다른 에러 페이지로 이동할 수 있다.

언제 어떤 방식을 써야 할까?

  • 단일 컨트롤러 내에서만 처리: @ExceptionHandler
  • 전역적인 예외 처리 필요: @ControllerAdvice
  • REST API 전용 고급 처리: ResponseEntityExceptionHandler
  • 전통적인 뷰 기반 처리 (JSP 등): SimpleMappingExceptionResolver

필요에 따라 위 방식을 조합해서 사용하는 것도 가능하다.

profile
Turning Vision into Reality.

0개의 댓글