Computer Science/Troubleshooting

[Spring] ExceptionHandler

_혀니 2024. 10. 24. 13:31
728x90
반응형

이 문제는 @ExceptionHandler를 구현 중에 직면한 사건이었다.

기존에 핸들링을 위해 작성한 코드:

@ExceptionHandler({Exception.class})
	public ModelAndView exceptionHandler(Exception ex, ModelAndView mv) {
		System.out.println("Exception");
		mv.setViewName("error/error");
		mv.addObject("msg", "에러~");
		return mv;
	}

 

그런데 막상 실행해보니 Exception을 그대로 WAS가 뱉어내고, Handler가 작동하지 않았다.

하지만 이런 식으로 바꾸었을 때에는 정상 작동되었다.

	@ExceptionHandler({Exception.class})
	public String exceptionHandler(Exception ex, Model m) {
		System.out.println("Exception");
		m.addAttribute("msg", "에러~");
		return "error/error";
	}

 

정상적으로 핸들링했다...

사유는 Spring Docs에서 찾을 수 있었는데

Docs에서는 ExceptionHandler가 사용할 수 있는 parameter type, return type을 정의하고 있었고

그곳에 ModelAndView는 Parameter type으로 사용할 수 없었다.

그래서 Spring은 내가 만든 메소드를 ExceptionHandler로 인식하지 않아 throw한 에러를 그대로 뱉어내고 있었다.

 

메소드 내부에서 ModelAndView를 만드는 것은 리턴 타입으로 ModelAndView타입을 사용할 수 있기에 가능하다.

@ExceptionHandler({Exception.class})
	public ModelAndView exceptionHandler(Exception ex) {
		System.out.println("Exception");
		ModelAndView mv = new ModelAndView();
		mv.setViewName("error/error");
		mv.addObject("msg", "에러~");
		return mv;
	}

 

이 방식도 잘 된다.

 

다만 Return은 ModelAndView, Model 모두 가능한데 Parameter로는 Model만 가능하고 View는 함께 받아올 수 없다.

 

1.

Model은 인터페이스 타입이고 구현 클래스가 다양하다. 이 중에 ExtendModelMap이라는 클래스가 Model을 implement하고, ModelMap을 상속받는다.

 

2.

ModelAndView클래스에서 사용하는 Model이 바로 ModelMap으로, 이 ModelMap도 LinkedHashMap<>을 사용해서 구현했다. 구현 클래스가 여러 개 있어서 ModelAndView타입으로 날아오지 않고, Docs에서도 Model타입을 "therefore always empty, as a convenience for preparing the model for an exception-specific view." 로 묘사하고 있는 것을 보면 사용자의 에러 핸들링을 돕기 위해 넣어준 것으로 보인다.

728x90
반응형