본문 바로가기
Spring MVC

[MVC] 스프링 MVC - 구조 이해(2)

by 개발 Blog 2025. 2. 20.

공부 내용을 정리하고 앞으로의 학습에 이해를 돕기 위해 작성합니다.

 

뷰 리졸버

스프링 MVC에서 뷰(View)를 찾고 렌더링하는 역할을 하는 뷰 리졸버(View Resolver) 에 대해 알아보자.

 

OldController - View 조회 가능하도록 변경

package hello.servlet.web.springmvc.old;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@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");
    }
}

위 코드에서 return new ModelAndView("new-form");을 추가하여 뷰(View)를 반환하도록 설정했다.

 

실행 결과

브라우저에서 다음 URL로 접근하면 Whitelabel Error Page가 나타나지만, 콘솔에는 OldController.handleRequest가 출력될 것이다.

이는 컨트롤러는 정상적으로 호출되지만, 뷰를 찾을 수 없어서 발생하는 오류다.

 

뷰 리졸버 설정 추가

application.properties에 다음 설정을 추가하여 뷰를 찾을 수 있도록 한다.

spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

이 설정을 추가하면 new-form이라는 논리적인 뷰 이름을 WEB-INF/views/new-form.jsp로 변환하여 찾을 수 있게 된다.

 

뷰 리졸버 - InternalResourceViewResolver

스프링 부트는 기본적으로 InternalResourceViewResolver를 자동 등록하는데, 이때 위에서 설정한 spring.mvc.view.prefix, spring.mvc.view.suffix 값을 사용하여 뷰 경로를 결정한다.

설정 없이 전체 경로를 직접 명시할 수도 있다.

return new ModelAndView("/WEB-INF/views/new-form.jsp");

하지만 위 방식은 유지보수가 어렵기 때문에 권장되지 않는다.

 

실행 결과

정상적으로 등록 폼이 출력될 것이다. 하지만 저장 기능을 구현하지 않았으므로 폼만 출력되며 이후 단계에서 오류가 발생할 수 있다.

 

뷰 리졸버의 동작 방식

 

스프링 부트가 자동 등록하는 뷰 리졸버

(실제로 더 많은 뷰 리졸버가 존재하지만, 중요한 부분만 다룬다.)

1 = BeanNameViewResolver : 빈 이름으로 뷰를 찾아 반환한다. (예: 엑셀 파일 생성 기능에 사용)
2 = InternalResourceViewResolver : JSP를 처리할 수 있는 뷰를 반환한다.

 

뷰 리졸버의 처리 과정

1. 핸들러 어댑터 호출
핸들러 어댑터를 통해 new-form이라는 논리 뷰 이름을 획득한다.

 

2. ViewResolver 호출

new-form이라는 뷰 이름으로 viewResolver들을 순서대로 호출한다.

BeanNameViewResolver는 new-form이라는 이름의 스프링 빈을 찾으려 하지만, 해당 뷰가 존재하지 않는다.

InternalResourceViewResolver가 호출된다.

 

3. InternalResourceViewResolver
InternalResourceView를 반환한다.

 

4. InternalResourceView 동작
InternalResourceView는 JSP처럼 forward()를 호출하여 내부에서 처리를 수행할 수 있는 경우 사용된다.

 

5. view.render() 호출
view.render()가 호출되며, InternalResourceViewforward()를 사용하여 JSP를 실행한다.

 

참고 사항

  • InternalResourceViewResolver는 JSTL 라이브러리가 있으면 JstlView를 반환한다. JstlView는 JSTL 태그 사용 시 추가적인 기능을 제공한다.
  • JSP를 제외한 대부분의 뷰 템플릿 엔진(예: Thymeleaf, FreeMarker)은 forward() 없이 직접 렌더링된다.
  • Thymeleaf 뷰 템플릿을 사용할 경우 ThymeleafViewResolver를 등록해야 하지만, 스프링 부트에서는 라이브러리를 추가하는 것만으로 자동 설정된다.

이제 본격적으로 스프링 MVC를 학습해보자.