핸들러 메소드가 요청을 처리하고 논리 뷰 이름을 반환하면
DispatcherServlet은 화면에서 데이터를 표시하도록 뷰 템플릿에 제어권을 넘긴다.
스프링 MVC에서는 뷰를 해석할 수 있는 ViewResolver 구현체 몇 가지가 있는데,
그 중 MVC 기본 설정에는 InternalResourceViewResolver를 기본으로 사용하고 있다.
InternalResourceViewResolver는 사용이 간단해서 편하지만,
RequestDispatcher가 forward 할 수 있는 내부 리소스(jsp/서블릿)만 해석이 가능하기 때문에
다른 뷰 템플릿(Thymeleaf )을 사용하는 경우에는 다른 viewResolver를 사용해야 한다.
Thymeleaf와 같은 뷰 템플릿을 사용하는 경우에는 ThymeleafViewResolver를 사용한다.
prefix를 뷰 이름의 앞 부분에 붙여 파일의 경로를 만들고, suffix를 끝 부분에 붙여서 파일의 확장자를 지정한다.
String 타입으로 반환
1. String으로 view name 반환(forward)
GET 방식의 /string 요청을 전달한다.
<!--/resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<h1>view resolver 테스트</h1>
<h3>문자열로 뷰 이름 반환하기</h3>
<button onclick="location.href='string'">문자열로 뷰 이름 반환</button>
</body>
</html>
발생하는 요청을 매핑할 Controller의 handler method이다.
문자열로 view 이름을 반환한다는 것은
반환 후 ViewResolver에게 resources/templates/를 prefix로,
.html을 suffix로 하여 resources/templates/result.html 파일을 응답 뷰로 설정하라는 의미이다.
package org.example.viewresolver;
@Controller
public class ResolverController {
@GetMapping("/string")
public String stringReturning(Model model) {
// Model : View에서 표현 되어야 하는 동적인 데이터를 담는 용도로 사용하는 객체
model.addAttribute("forwardMessage", "문자열로 뷰 이름 반환함...");
return "result";
}
}
응답할 뷰에서는 model에 추가된 forwardMessage를 화면에 출력하도록 한다.
<!--resources/templates/result.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>result</title>
</head>
<body>
<h1 th:text="${forwardMessage}"></h1>
</body>
</html>
2. redirect
GET 방식의 /string-redirect 요청을 전달한다.
<!--/resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<!-- ... 위에서 작성한 내용 생략 -->
<h3>문자열로 redirect하기</h3>
<button onclick="location.href='string-redirect'">문자열로 redirect</button>
</body>
</html>
발생하는 요청을 매핑할 Controller의 핸들러 메소드이다.
동일하게 String 반환 값을 사용하지만 접두사로 redirect:를 붙이면 forward 되지 않고 redirect 된다.
package com.ohgiraffers.viewresolver;
@Controller
public class ResolverController {
@GetMapping("/string-redirect")
public String stringRedirect() {
// redirect: 을 붙인 뒤 redirect 할 주소 값을 작성한다.
return "redirect:/";
}
}
button을 클릭하면 / 경로로 redirect 되는 것을 확인할 수 있다.
3. RedirectAttributes
GET 방식의 /string-redirect-attr 요청을 전달한다.
<!--/resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<!--.. 앞에서 작성한 내용 생략-->
<h3>문자열로 redirect & flash Attribute 하기</h3>
<button onclick="location.href='string-redirect-attr'">문자열로 redirect & flash Attribute</button>
</body>
</html>
기본적으로 redirect를 하면 재요청이 발생하므로 request scope는 소멸된다.
하지만 Spring에서는 RedirectAttributes 타입을 통해 redirect 시 속성 값을 저장할 수 있도록 한다.
Redirect 시 flash 영역에 담아서 redirect 할 수 있다.
자동으로 model에 추가되므로 requestScope에서 값을 꺼내면 된다.
Session에 임시로 값을 담고 소멸하는 방식이기 때문에 session에 동일한 키 값이 존재하면 안된다.
package org.example.viewresolver;
@Controller
public class ResolverController {
// ... 앞에서 작성한 내용 생략
@GetMapping("/string-redirect-attr")
public String stringRedirectFlashAttribute(RedirectAttributes rttr) {
rttr.addFlashAttribute("flashMessage1", "리다이렉트 attr 사용하여 redirect...");
return "redirect:/";
}
}
응답 시 requestScope에 보존된 flashMessage1을 꺼내 alert 창에 띄울 수 있다.
<!--/resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<!--... 위에서 작성한 코드 생략-->
<script>
const flashMessage1 = `[[${flashMessage1}]]`;
if(flashMessage1) alert(flashMessage1);
</script>
</body>
</html>
실행해보면 redirect 했지만 메세지가 잘 보존됨을 alert 창을 통해 확인할 수 있다.
ModelAndView 타입으로 반환
ModelAndView 타입으로 반환하는 경우 model과 view 정보를 한 번에 담아서 반환한다.String 타입으로 반환하는 것과 마찬가지로 forward와 redirect를 모두 사용할 수 있으며, RedirectAttribute 사용도 가능하다.
1. view name 반환(forward)
GET 방식의 /modelandview 요청을 전달한다.
<!--/resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<!--... 위에서 작성한 내용 생략-->
<h3>ModelAndView로 뷰 이름 반환하기</h3>
<button onclick="location.href='modelandview'">ModelAndView로 뷰 이름 반환</button>
</body>
</html>
발생하는 요청을 매핑할 Controller의 핸들러 메소드이다.
핸들러 어댑터가 핸들러 메소드를 호출하고 반환받은 문자열을 ModelAndView로 만들어 dispatcherServlet에 반환한다.
이 때 문자열을 반환해도 되지만 ModelAndView를 미리 만들어 반환할 수도 있다.
package com.ohgiraffers.viewresolver;
@Controller
public class ResolverController {
@GetMapping("/modelandview")
public ModelAndView modelAndViewReturning(ModelAndView mv) {
// Model 객체에 attribute 저장
mv.addObject("forwardMessage", "ModelAndView를 이용한 모델과 뷰 반환");
// View 객체에 논리적 뷰 이름 설정
mv.setViewName("result");
return mv;
}
}
view resolver가 올바르게 동작하였음을 응답 화면을 통해 확인할 수 있다.
2. redirect
<!--/resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<!--... 위에서 작성한 내용은 생략-->
<h3>ModelAndView로 redirect하기</h3>
<button onclick="location.href='modelandview-redirect'">ModelAndView로 redirect</button>
</body>
</html>
발생하는 요청을 매핑할 Controller의 핸들러 메소드이다.
ModelAndView 객체에서도 접두사로 redirect: 를 붙이면 forward 되지 않고 redirect 된다.
package com.ohgiraffers.viewresolver;
@Controller
public class ResolverController {
@GetMapping("/modelandview-redirect")
public ModelAndView modelAndViewRedirect(ModelAndView mv) {
mv.setViewName("redirect:/");
return mv;
}
}
button 클릭 시 / 경로로 redirect 된다.
3. RedirectAttributes
GET 방식의 /modelandview-redirect-attr 요청을 전달한다.
<!--resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<h3>ModelAndView로 redirect & flashAttibute 추가하기</h3>
<button onclick="location.href='modelandview-redirect-attr'">ModelAndView로 redirect & flashAttibute</button>
</body>
</html>
발생하는 요청을 매핑할 Controller의 핸들러 메소드이다.
ModelAndView 사용 시에도 동일하게 RedirectAttributes 타입을 통해 redirect 시 속성 값을 지정할 수 있다.
package com.ohgiraffers.viewresolver;
@Controller
public class ResolverController {
// ... 위에서 작성한 내용 생략
@GetMapping("/modelandview-redirect-attr")
public ModelAndView modelAndViewRedirectFlashAttribute(ModelAndView mv, RedirectAttributes rttr) {
rttr.addFlashAttribute("flashMessage2", "리다이렉트 attr 사용하여 redirect...");
mv.setViewName("redirect:/");
return mv;
}
}
응답 시 requestScope에 보존된 flashMessage2을 꺼내 alert 창에 띄운다.
<!--resources/templates/main.html-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>main</title>
</head>
<body>
<!--앞에서 작성된 부분 생략-->
<script>
const flashMessage2 = `[[${ flashMessage2 }]]`;
if(flashMessage2) alert(flashMessage2);
</script>
</body>
</html>
'Spring Framework > Spring Boot' 카테고리의 다른 글
[Spring Boot] 6. Interceptor (1) | 2024.09.10 |
---|---|
[Spring Boot] 5. Exception Handler (0) | 2024.09.09 |
[Spring Boot] 3. Handler Method (2) | 2024.09.09 |
[Spring Boot] 2. Request Mapping (0) | 2024.09.08 |
[Spring Boot] 1. Spring Boot 개요 및 개발환경 구축 (1) | 2024.09.07 |