Spring 애플리케이션으로 뷰 반환하기
Spring 애플리케이션은 다양한 방식으로 뷰(view)를 노출시킬 수 있다. 정적 페이지가 호스팅되도록 설정하거나, 컨트롤러에서 뷰를 응답하도록 구현할 수 있다. 또한 템플릿 엔진이라는 툴을 사용할 수도 있다.
웰컴 페이지 자동 응답
Spring Boot는 resources/static 디렉토리에 저장돼있는 정적 페이지를 웹페이지로 띄울 수 있도록 지원한다. 이 중 웰컴 페이지는 우리가 별도의 작업을 하지 않아도 Spring Boot가 기본적으로 띄워주는 페이지를 말한다.
애플리케이션 가동 시 resources/static에 index.html 파일이 있으면 루트 경로(e.g. http://localhost:8080/)에 접근했을 때 index.html이 웰컴 페이지로 뜬다.
웰컴 페이지의 파일명은 index여야 하며, 만약 다른 이름이라면 http://localhost:8080/hello.html과 같이 정적으로 호스팅된 파일의 URL을 입력해 직접적으로 접근할 수 있다.
컨트롤러로 뷰 반환
Spring 컨트롤러는 문자열이나 HTML 파일을 뷰로 반환하여, 클라이언트의 요청에 HTML 문서를 응답할 수 있다. 이때, @ResponseBody 애노테이션의 유무에 따라 컨트롤러가 뷰를 응답하는 방식이 달라진다.
먼저 resources/static 디렉토리에 있는 HTML 파일을 그대로 응답하려면 @ResponseBody 애노테이션 없이 파일명을 반환하면 된다. Thymeleaf와 같은 템플릿 엔진에 대한 의존성이 없다면 파일의 확장자까지 포함시킨다.
// resources/static 파일 응답
@GetMapping("/")
public String getPage() {
return "index.html"; // 또는 "./index.html"
}
// resources/static 하위 폴더의 파일 응답
@GetMapping("/")
public String getPage() {
return "nested-folder/another-folder/index.html";
}
* 참고로 상태 경로는 허용되지만, "./src/main/resources/static/index.html"처럼 static 폴더의 상위 경로까지 인식되진 않는다.
@ResponseBody는 ViewResolver 대신 HttpMessageConverter가 동작하도록 하는 애노테이션이다. 따라서 @ResponseBody로 뷰를 반환하고자 한다면 resources/static 내 파일이 아닌, 아래처럼 HTML 문법을 직접적으로 반환해야 한다.
// 응답 값으로 페이지에 띄울 text/html Content-Type을 반환하는 메서드
// @ResponseBody annotation으로 인해 text/html Content-Type인 것으로 인식됨
// HTML syntax 사용 가능
@GetMapping("/")
@ResponseBody
public String getPage() {
return "<p>Opens a page with this text as its <strong>only content</strong></p>";
}
Template engine
템플릿 엔진은 동적으로 페이지를 처리해주는 기술이다. 템플릿 엔진을 활용해 런타임에 HTML 문서에 내가 원하는 값을 넣어 뷰를 완성시킬 수 있다.
템플릿 엔진마다 설정하는 방식이나 사용하는 문법이 다르다. 아래는 Thymeleaf 엔진에 대한 사용법이다.
Thymeleaf를 활용한 동적 뷰 렌더링에 필요한 것은 별도의 HTML 설정과 컨트롤러 매개변수로 들어오는 Model 객체다.
1. 컨트롤러에서 Model 객체를 통해 값 주입
@GetMapping("/")
public String getPage(Model model) {
model.addAttribute("name", "Bob");
return "index";
}
- 컨트롤러 메서드는 Model 객체를 인자로 받을 수 있다.
- model.addAttribute() 메서드로 HTML 파일에 주입할 변수명과 값을 입력한다.
2. HTML에 템플릿 엔진 문법 추가
<html xmlns:th="http://www.thymeleaf.org">
<body>
<p th:text="'Hello, ' + ${name} + '!'" />
</body>
</html>
- <html> 태그에 `xmlns:th="http://www.thymeleaf.org"` 요소를 추가해준다
- Model이 주입한 값을 사용하기 위해 HTML 태그 내 `th:text=””` 요소에 컨텐츠를 입력한다. 이때 주입 받은 변수명을 `${ }` 안에 전달한다
템플릿 엔진 사용 시 주의할 점은 템플릿 엔진에 의존성이 있을 경우, 컨트롤러에서 뷰를 반환할 때 resources/static이 아닌 resources/templates 디렉토리에 있는 파일만 확인한다는 점이다. 기존에 resources/static에 있던 파일들은 전체 URL을 입력해 접근해야 한다.
다만 Spring Boot가 띄우는 웰컴 페이지는 resources/static을 먼저 확인하고, static 폴더에 index.html 문서가 없으면 후순위로 resources/templates를 확인한다.
템플릿 엔진을 사용하면 파일 확장자를 포함시킬 필요가 없다는 장점도 있다.
@GetMapping("/")
public String getPage() {
return "index"; // "index.html"이나 "./index.html"도 됨
}