Spring Boot에서 HTML을 화면에 출력하려면 Thymeleaf를 사용한다.
Thymeleaf는 서버에서 데이터를 HTML에 렌더링해주는 템플릿 엔진이다.
의존성 추가
build.gradle.kts
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect")
thymeleaf-layout-dialect는 레이아웃(공통 Header, Footer 등)을 사용할 때 필요한 라이브러리이다.
HTML 파일 위치
HTML 파일은 아래 경로에 생성한다.
src
└─ main
└─ resources
└─ templates
└─ question_list.html
Spring Boot는 기본적으로 resources/templates 폴더를 HTML 템플릿 위치로 인식한다.
Controller 수정
@ResponseBody
@GetMapping("/question/list")
public String list() {
return "Hello";
}
기존에는 문자열 자체를 브라우저에 출력했다.
하지만 HTML을 반환하려면 @ResponseBody를 제거하고 파일 이름을 반환하면 된다.
@GetMapping("/question/list")
public String list(Model model) {
List<Question> questionList = questionRepository.findAll();
model.addAttribute("questionList", questionList);
return "question_list";
}
Model을 이용해 데이터 전달
Controller에서 HTML로 데이터를 전달할 때는 Model을 사용한다.
model.addAttribute("questionList", questionList);
- 첫 번째 인자 : HTML에서 사용할 이름
- 두 번째 인자 : 전달할 데이터
${questionList}
HTML에서는 위처럼 사용할 수 있다.
HTML에서 데이터 출력
<tbody>
<tr th:each="question : ${questionList}">
<td th:text="${question.id}"></td>
<td th:text="${question.subject}"></td>
</tr>
</tbody>
여기서 사용하는 Thymeleaf 문법은 다음과 같다.
| 문법 | 설명 |
| th:each | 반복문(for문) |
| th:text | 데이터 출력 |
| ${} | Model에 저장된 데이터 참조 |
위 코드는 자바의 다음 코드와 비슷한 의미이다.
for (Question question : questionList) {
System.out.println(question.getId());
System.out.println(question.getSubject());
}
개발 중 캐시 비활성화
템플릿 수정 후 서버를 재시작하지 않아도 바로 적용되도록 설정한다.
application.yml
spring:
thymeleaf:
cache: false
prefix: file:src/main/resources/templates/
cache: false
HTML을 수정할 때마다 즉시 반영된다.
prefix
파일 시스템에서 HTML을 다시 읽기 때문에 서버를 재시작하지 않아도 변경 사항을 바로 확인할 수 있다.
개발 중에는 매우 편리하지만, 운영 환경에서는 보통 기본 설정을 사용한다.
'BackEnd > Spring' 카테고리의 다른 글
| [Spring] Proxy란? @Transactional과 @Lazy가 동작하는 원리 (0) | 2026.08.06 |
|---|---|
| [Spring] Bean 심화 - @Bean, @Qualifier, @Order 정리 (0) | 2026.08.06 |
| [Spring] Lazy Loading vs Eager Loading (0) | 2026.08.05 |
| [Spring] JPA CascadeType과 Flush (0) | 2026.08.05 |
| [Spring] @OneToMany와 @ManyToOne (0) | 2026.08.05 |
댓글