2020-8-1 스프링 MVC(10) 예외처리핸들러와 전역컨트롤러
예외처리핸들러 @ExceptionHandler
특정 예외가 발생한 요청을 처리하는 핸들러
-
지원하는 메서드 아규먼트
-
지원하는 리턴 값
-
REST API의 경우 응답 본문에 에러 정보를 담아주고, 상태코드를 설정하려면 ResponseEntity를 이용하면 된다.
-
@Controller @SessionAttributes("event") public class EventController { @ExceptionHandler public String eventErrorHandler(EventException exception, Model model) { model.addAttribute("message", "event error"); return "error"; } @ExceptionHandler public String runTimeErrorHandler(RuntimeException exception, Model model) { model.addAttribute("message", "runtime error"); return "error"; } ... @GetMapping("events/form/name") public String eventFormName(Model model) { throw new EventException(); } }
- 가장 구체적인 에러를 처리한다. runtimeErrorHandler가 아닌 eventErrorHandler로 응답이 온다.
전역컨트롤러 : @(Rest)ControllerAdvice
-
예외처리, 바인딩 설정, 모델 객체를 모든 컨트롤러 전반에 걸쳐 적용하고 싶은 경우에 사용한다.
-
@ExceptionHandler
-
@InitBinder
-
@ModelAttributes
-
@ControllerAdvice public class BaseController { @ExceptionHandler public String eventErrorHandler(EventException exception, Model model) { model.addAttribute("message", "event error"); return "error"; } @ExceptionHandler public String runTimeErrorHandler(RuntimeException exception, Model model) { model.addAttribute("message", "runtime error"); return "error"; } @InitBinder public void initEventBinder(WebDataBinder webDataBinder) { webDataBinder.setDisallowedFields("id"); webDataBinder.addValidators(new EventValidator()); } @ModelAttribute("categories") public List<String> categories(Model model) { return Arrays.asList("study", "seminar"); } }
- 위의 코드는 모든 컨트롤러에 다 적용이 된다.
-
-
적용할 범위도 지정할 수 있다.(spring 4.0부터 적용됨)
-
특정 어노테이션을 가지고 있는 컨트롤러에만 적용하기
-
특정 패키지 이하의 컨트롤러에만 적용
-
@ControllerAdvice(assignableTypes = {EventController.class, EventApi.class}) public class BaseController { }
-
-
특정 클래스 타입에만 적용하기
-
매개변수를 이용한 테스트
-
JunitParams를 사용.
-
@RunWith(JUnitParamsRunner.class) public class EventTest { // case1 파라미터만 전달 @Test @Parameters({ "0, 0, true", "100, 0, false", "0, 100, false" }) public void testFree(int basePrice, int maxPrice, boolean isFree) { // Given Event event = Event.builder() .basePrice(basePrice) .maxPrice(maxPrice) .build(); // When event.update(); // Then assertThat(event.isFree()).isEqualTo(isFree); } // case2 메서드 이름으로 전달 @Test @Parameters(method = "parametersForOffline") public void offlineTest(String location, boolean isOffline) { // Given Event event = Event.builder() .location(location) .build(); // When event.update(); // Then System.out.println(event.getLocation()); assertThat(event.isOffLine()).isEqualTo(isOffline); } private Object[] parametersForOffline() { return new Object[] { new Object[] {"강남", true}, new Object[] {null, false}, new Object[] {" ", false} }; } }
- 테스트 메서드에 파라미터를 전달해서 각 테스트 경우에 대해서 중복을 제거할 수 있다.
-
Written on August 1, 2020