스프링 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);
}
}
@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);
}
}
SimpleMappingExceptionResolver (뷰 기반 예외 처리)@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@ControllerAdviceResponseEntityExceptionHandlerSimpleMappingExceptionResolver필요에 따라 위 방식을 조합해서 사용하는 것도 가능하다.