[Spring] View Resolver

배창민·2025년 10월 15일
post-thumbnail

View Resolver

요청을 처리한 컨트롤러가 논리 뷰 이름을 반환하면 DispatcherServletViewResolverView 순서로 화면 렌더링이 진행된다. 스프링은 전략 패턴으로 다양한 뷰 리졸버를 제공한다.


1) ViewResolver 개요

  • InternalResourceViewResolver

    • JSP/서블릿 같은 내부 리소스RequestDispatcher#forward로 렌더링
    • prefix + viewName + suffix
  • ThymeleafViewResolver

    • 타임리프 템플릿 렌더링
    • 기본 관례: prefix=resources/templates/, suffix=.html

리졸버는 여러 개 등록 가능하며 Order에 따라 순차 시도한다.


2) String 타입으로 반환

2-1) 뷰 이름 반환 (forward)

@GetMapping("string")
public String stringReturning(Model model) {
    model.addAttribute("forwardMessage", "문자열로 뷰 이름 반환함...");
    return "result"; // -> templates/result.html
}
<!-- templates/result.html -->
<h1 th:text="${forwardMessage}"></h1>

2-2) 리다이렉트

@GetMapping("string-redirect")
public String stringRedirect() {
    return "redirect:/"; // 302 응답 후 재요청
}

2-3) RedirectAttributes로 flash 저장

@GetMapping("string-redirect-attr")
public String stringRedirectFlashAttribute(RedirectAttributes rttr) {
    rttr.addFlashAttribute("flashMessage1", "리다이렉트 attr 사용하여 redirect..");
    return "redirect:/";
}
<script>
  const msg = '[[${flashMessage1}]]';
  if (msg) alert(msg); // 1회성 메시지
</script>

포인트

  • 리다이렉트는 request 범위가 초기화됨 → 임시 상태는 flash attribute로 전달
  • flash는 내부적으로 세션을 잠깐 사용 후 소멸

3) ModelAndView로 반환

모델과 뷰를 한 객체에 담아 반환한다. forward/redirect 모두 동일하게 활용 가능.

3-1) 뷰 이름 반환 (forward)

@GetMapping("modelandview")
public ModelAndView modelAndViewReturning(ModelAndView mv) {
    mv.addObject("forwardMessage", "ModelAndView를 이용한 모델과 뷰 반환");
    mv.setViewName("result");
    return mv;
}

3-2) 리다이렉트

@GetMapping("modelandview-redirect")
public ModelAndView modelAndViewRedirect(ModelAndView mv) {
    mv.setViewName("redirect:/");
    return mv;
}

3-3) 리다이렉트 + flash

@GetMapping("modelandview-redirect-attr")
public ModelAndView modelAndViewRedirectAttr(ModelAndView mv, RedirectAttributes rttr) {
    rttr.addFlashAttribute("flashMessage2", "ModelAndView를 이용한 redirect attr");
    mv.setViewName("redirect:/");
    return mv;
}
<script>
  const msg = '[[${flashMessage2}]]';
  if (msg) alert(msg);
</script>

4) 체크리스트

  • forward vs redirect

    • forward: 서버 내부 이동, request 유지, URL 불변 → 조회 화면에 적합
    • redirect: 새 요청, PRG(Post/Redirect/Get) 패턴에 적합 (중복 제출 방지)
  • flash attribute

    • 경고/성공 메시지, 1회성 폼 값 전달에 활용
    • 동일 키의 세션 값이 있으면 충돌 가능 → 키 네이밍 주의
  • 템플릿 경로

    • 타임리프: templates/ 기준 상대 경로 + .html 생략 관례
  • 리졸버 다중 등록

    • JSON/프리마커/JSP 혼용 시 Order를 낮은 수부터 우선

핵심 요약

  • 컨트롤러 반환값은 뷰 이름(String) 또는 ModelAndView로 표현
  • forward는 동일 요청 컨텍스트에서 렌더링, redirect는 새 요청
  • redirect 시 데이터는 RedirectAttributes#addFlashAttribute로 전달
  • 타임리프는 ThymeleafViewResolverprefix/suffix 규칙을 따른다
profile
개발자 희망자

0개의 댓글