본 시리즈는 인프런 학습 사이트의 김영한 강사님의 java spring mvc - 백엔드 웹 개발 핵심 기술 편을 학습한 내용을 바탕으로 정리하였습니다.
저번 시간에 Spring의 frontController
인 Dispatcher Servlet
을 통해 핸들러 매핑과 핸들러 어댑터 기능을 구현해보았다. 결국은 어떠한 컨트롤러를 호출하기 위해선 Dispatcher Servlet
이 1) 핸들러를 조회해서 매핑
하고 찾은 핸들러를 2) 어댑터를 통해 실행
하는 순서를 거쳐야한다.
이제 다시 구조를 한 번 살펴보자.
핸들러 어댑터가 핸들러(컨트롤러)를 호출하고 어댑터는 컨트롤러로부터 Model에 View를 담아오게 될 것이다. 이 때, Dispatcher Servlet
은 ViewResolver
를 호출하게 되고 컨트롤러에서는 View를 반환하는 과정을 거친다.
뷰 리졸버에 대해 자세히 알아보자.
OldController
@Component("/springmvc/old-controller")
public class OldController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("OldController.handleRequest");
return new ModelAndView("new-form");
}
}
OldController
라고 하는 컨트롤러가 있다고 가정하자.
이 때, DispatcherSevlet
이 View를 받을 수 있도록 반환시켜주는 부분이
return new ModelAndView("new-form");
이다.
핸들러 어댑터 호출
Dispatcher Servlet
은 핸들러 어댑터의 return new ModelAndView("new-form");
이 부분을 통해 new-form
이라는 논리 뷰 이름을 획득하게 된다.
ViewResolver 호출
new-form
이라는 뷰 이름이 있기 때문에 viewResolver를 순서대로 호출하여 BeanNameViewResolver
를 호출하는 것이 맞다. 그러나,
BeanNameViewResolver
는 말 그대로 빈 이름으로 등록된 뷰를 찾는 리졸버이다. 따라서new-form
이라는 이름의 스프링 빈으로 등록된 뷰를 찾아야 하는데 위 코드를 보면 스프링 빈으로 등록하지 않았기 때문에 존재하지 않는다. 이 때문에 그 다음 순위인InternalResourceViewResolver
가 호출된다.
View - InternalResourceView
JSP처럼 포워드 forward()
를 호출해서 처리할 수 있는 경우는 이와 같이 InternalResourceView
로 뷰를 처리한다. 참고로 다른 뷰는 실제 뷰를 렌더링하지만 JSP의 경우, forward()
를 통해서 해당 JSP로 이동해야 렌더링이 된다. JSP를 제외한 나머지 뷰 템플릿들은 forward()
과정 없이 바로 렌더링 된다.
view.render()
view.render()
가 호출되고 InternalResourceView
는 forward()
를 사용해서 JSP를 실행한다.
💡 참고
InternalResourceViewResolver
는 만약 JSTL 라이브러리가 있으면InternalResourceView
를 상속받은JstlView
를 반환한다.JstlView
는 JSTL 태그 사용시 약간의 부가 기능이 추가된다. 또한 Thymeleaf 뷰 템플릿을 사용하기 위해선ThymeleafViewResolver
를 등록해야 한다. 최근에는 라이브러리만 추가하면 스프링 부트가 이런 작업도 모두 자동화해준다.
1 순위 = BeanNameViewResolver : 빈 이름으로 뷰를 찾아서 반환한다. (예: 엑셀 파일 생성 기능에 사용)
2 순위 = InternalResourceViewResolver : JSP를 처리할 수 있는 뷰를 반환한다.
실제로는 더 많지만 중요한 부분 위주로 설명하기 위해 일부 생략했다.