Files
spring-boot-examples/docs/05_템플릿 엔진.md
2025-04-08 19:56:24 +09:00

5.3 KiB

Spring Boot의 뷰 렌더링과 Thymeleaf 템플릿

Spring Boot에서는 Thymeleaf를 사용하여 HTML 기반의 동적 웹 페이지를 렌더링할 수 있습니다.

뷰(View) 렌더링이란?

  • 클라이언트가 요청을 보내면, 컨트롤러가 요청을 처리하고 데이터를 모델(Model)에 담아 뷰(View)로 전달합니다.
  • 뷰(View)는 HTML 페이지로, Thymeleaf 같은 템플릿 엔진을 사용하면 서버에서 동적으로 HTML을 생성할 수 있습니다.
  • Spring Boot에서 대표적인 뷰 템플릿 엔진: Thymeleaf, JSP, FreeMarker 등이 있지만, Thymeleaf가 가장 많이 사용됨.

Thymeleaf 설정

다음과 같이 Thymeleaf 의존성을 추가합니다.

implementation("org.springframework.boot:spring-boot-starter-thymeleaf")

Spring Boot는 기본적으로 src/main/resources/templates/ 경로에서 Thymeleaf 템플릿을 찾습니다.

src/
 ├── main/
 │   ├── java/com.example.demo/
 │   ├── resources/
 │   │   ├── templates/   → Thymeleaf HTML 파일 위치
 │   │   │   ├── index.html
 │   │   │   ├── user.html
 │   │   ├── application.properties

기본 컨트롤러와 템플릿 렌더링

컨트롤러 작성

@Controller
public class HomeController {

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("message", "Welcome to Thymeleaf!");
        return "index"; // templates/index.html 파일을 렌더링
    }
}

설명:

  • @Controller → HTML을 반환하는 컨트롤러.
  • Model뷰로 데이터를 전달하는 객체.
  • model.addAttribute("message", "Welcome to Thymeleaf!")message라는 데이터를 전달.
  • return "index";templates/index.html 파일을 렌더링.

Thymeleaf 템플릿 (index.html)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Thymeleaf Example</title>
</head>
<body>
    <h1 th:text="${message}">Default Message</h1>
</body>
</html>

실행 결과 (http://localhost:8080/ 요청)

<h1>Welcome to Thymeleaf!</h1>

설명:

  • th:text="${message}"message 값이 "Welcome to Thymeleaf!"로 변경됨.
  • 템플릿 엔진이 동적으로 HTML을 생성하여 클라이언트에 응답.

변수 출력 및 표현식

기본 표현식 (th:text)

<p th:text="${username}">Default Name</p>
  • ${변수명}Model에서 전달된 변수를 표시.

객체의 필드 출력 (th:text)

class User {
    private String name;
    private int age;

    public User(String name, int age) { this.name = name; this.age = age; }
    public String getName() { return name; }
    public int getAge() { return age; }
}
@GetMapping("/user")
public String userProfile(Model model) {
    model.addAttribute("user", new User("Alice", 25));
    return "user";
}
<p th:text="${user.name}">Default Name</p>
<p th:text="${user.age}">Default Age</p>

실행 결과 (/user 요청):

<p>Alice</p>
<p>25</p>

반복문 (th:each)

리스트 반복 (th:each)

@GetMapping("/users")
public String users(Model model) {
    List<User> userList = Arrays.asList(
        new User("Alice", 25),
        new User("Bob", 30),
        new User("Charlie", 22)
    );
    model.addAttribute("users", userList);
    return "users";
}
<ul>
    <li th:each="user : ${users}">
        <span th:text="${user.name}"></span> - <span th:text="${user.age}"></span>
    </li>
</ul>

실행 결과 (/users 요청):

<ul>
    <li>Alice - 25</li>
    <li>Bob - 30</li>
    <li>Charlie - 22</li>
</ul>

조건문 (th:if, th:unless)

값이 있을 때만 표시 (th:if)

<p th:if="${user.age >= 18}">Adult</p>

값이 없을 때 표시 (th:unless)

<p th:unless="${user.age >= 18}">Minor</p>

폼 처리 (@PostMapping)

컨트롤러에서 폼 데이터 받기

@Controller
@RequestMapping("/form")
public class FormController {

    @GetMapping
    public String showForm(Model model) {
        model.addAttribute("user", new User("", 0));
        return "form";
    }

    @PostMapping
    public String submitForm(@ModelAttribute User user, Model model) {
        model.addAttribute("submittedUser", user);
        return "result";
    }
}

Thymeleaf 폼 (form.html)

<form action="#" th:action="@{/form}" th:object="${user}" method="post">
    Name: <input type="text" th:field="*{name}" />
    Age: <input type="number" th:field="*{age}" />
    <button type="submit">Submit</button>
</form>

결과 페이지 (result.html):

<p>Name: <span th:text="${submittedUser.name}"></span></p>
<p>Age: <span th:text="${submittedUser.age}"></span></p>

정리

기능 Thymeleaf 문법 설명
텍스트 출력 th:text="${변수}" 변수 값을 출력
객체 속성 출력 th:text="${객체.필드}" 객체의 필드 값을 출력
반복문 th:each="item : ${리스트}" 리스트 반복 출력
조건문 th:if, th:unless 조건부 렌더링
폼 바인딩 th:object + th:field HTML 폼과 객체 바인딩
URL 매핑 th:action="@{경로}" 폼 요청 경로 설정