사용하는 이유
- 에러들을 묶어서 처리 할 수 있다.
@GetMapping({"/customers"}) public String customersPage(Model model) { try { var customers = customerService.getAll(); model.addAttribute("customers", customers); return "customer/customer-list"; } catch (RuntimeException e) { model.addAttribute("errMsg", e.getMessage()); return "error/runtime"; } }
코드가 위와 같이 모든 메서드 마다 try-catch로 에러를 핸들링 한다면 엄청나게 많은 중복코드들이 산재 할 것이다.
@ExceptionHandler(RuntimeException.class) public String runtimeException(Exception e, Model model) { model.addAttribute("errMsg", e.getMessage()); return "error/runtime"; }
하지만 ControllerAdvice 어노테이션과 함께라면 위와 같은 메서드 하나로 모든 RuntimeException 에러를 핸들링 할 수 있다.
- 패키지를 지정하여 해당 패키지 컨트롤러에서 일어나는 에러들을 처리 할 수 있다.
@ControllerAdvice("org.prgms.management.controller.view") public class ViewAdviceController {
위 코드와 같이 키지 범위를 입력하면 된다.
- 가령 JDBC에서 queryForObject 메서드를 사용하여 데이터를 찾을 때, 반환되는 row 수가 0일 때, DataNotFoundException이 발생한다. 이럴 때, 적절한 http 상태 메시지를 반환 할 수 있다. ( 일환님 코드 감사해요 👍😎 )
@ResponseStatus(HttpStatus.NOT_FOUND) @ExceptionHandler public String handleNotFoundException(EmptyResultDataAccessException e) { return "404"; }
또 다른 대안
- @ExceptionHandler만 해당 클래스 내에서 사용하기
@Controller public class VoucherController { ... @ExceptionHandler(RuntimeException.class) public String runtimeException(Exception e, Model model) { model.addAttribute("errMsg", e.getMessage()); return "error/runtime"; } ... }
위와 같이 컨트롤러 내에서도 @ExceptionHandler 어노테이션을 통해 에러 핸들링이 가능하다.
활용 방안
- 커스텀 익셉션 클래스를 작성 후 핸들링 할 수 있다.