Thymeleaf 

SpringBoot는 JSP를 대체할 수 있는 다양한 뷰 템플릿 엔진을 지원한다. Thymeleaf, FreeMarker, Groovy, Mustache 등이 있으며 이러한 엔진들은 SpringBoot의 자동 구성 기능과 통합되어 개발의 편의성과 어플리케이션의 유지보수성을 높일 수 있다.
* 템플릿 엔진은 지정된 템플릿 양식과 데이터가 합쳐져 HTML 문서를 출력하는 소프트웨어이다.

 

하나의 예시로 회원의 정보를 화면에 나타내고 싶을 때 "이름: 홍길동, 나이: 19" 이와 같이 기재한다면 회원 정보가 변경될 때마다 수정해줘야한다. 이때, 태그에 text라는 속성과 값을 할당해주고 서버에서 이름과 나이라는 key를 이용하여 데이터를 템플릿에 넘겨준다. 템플릿 엔진은 이를 받아 HTML에 값을 저장한다. 즉, 화면에 보이는 데이터를 동적으로 관리할 수 있다.

As-Is
<h1>홍길동</h1>
<p >19</p>

To-Be
<h1 text=${이름}></h1>
<p text=${나이}></p>

 

SpringBoot에서는 Thymeleaf를 사용하자.

SpringBoot에서는 Thymeleaf를 권장한다. Thymeleaf 공식문서에 JSP와 비교하는 글을 보면 알 수 있다. JSP를 사용했을 때 소요되는 노력과 시간에 비해 Thymeleaf는 정말 간단하게 적용할 수 있다는 내용이다. SpringBoot는 JSP에 대한 자동구성 기능을 제공하지 않으며 독립적이고 이식성이 좋은 어플리케이션을 지향하기 때문에 JSP를 권장하지 않는다.

Thymeleaf vs JSP

 

Thymeleaf 사용방법

1. 의존성 주입 (build.gradle.kts)

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

 

2. 외부옵션 설정 (application.properties)

# view
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true
spring.thymeleaf.prefix=classpath:/templates/thymeleaf/
spring.thymeleaf.suffix=.html

 

3. html 파일 생성 및 코드 작성 (/src/main/resources/templates/thymeleaf/index.html)

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Hello thymeleaf</title>
</head>
<body>
    <h1>Hello thymeleaf</h1>

    <!-- Thymeleaf 사용 -->
    <div th:if="true">
        <div th:text="${result}">${result}</div>
    </div>

</body>
</html>

 

4. DB에 있는 데이터 조회해서 출력하는 코드 작성 

package kr.co.vibevillage.database.controller;

import kr.co.vibevillage.database.service.TestServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class TestController {

    private final TestServiceImpl testService;

    @Autowired
    public TestController(TestServiceImpl testService) {
        this.testService = testService;
    }

    @GetMapping("/test")
    public String databaseConnectionTest(Model model) {
        String result = testService.testXML();

        model.addAttribute("result", result);

        return "index";
    }
}
package kr.co.vibevillage.database.mapper;

import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface TestMapper {
    public String testXML();
}
package kr.co.vibevillage.database.service;

public interface TestService {
    public String testXML();
}
package kr.co.vibevillage.database.service;

import kr.co.vibevillage.database.mapper.TestMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import kr.co.vibevillage.env.Env;

@Service
public class TestServiceImpl implements TestService {

    // maper 객체 생성
    @Autowired
    TestMapper testMapper;

    // TestService 인터페이스에 선언한 추상 메소드 구현
    @Override
    public String testXML() {
        System.out.println("---------------------Database Connect---------------------");
        String text = testMapper.testXML();
        // USER 테이블에 있는 U_NICKNAME 데이터 가져와서 Controller로 전달
        return text;
    }
}

Thymeleaf 적용 성공

실행 순서를 좀 설명해보자면...

1. localhost:8080/test 이동

2. TestController 클래스의 GetMapping("/test") 어노테이션으로 인해 컨트롤러와 매핑되어 databaseConnection 메소드 호출

3. databaseConnection 메소드 내부에 작성된 서비스와 testXML메소드 호출 

4. Mapper 인터페이스가 호출되고.. select 태그의 id에 메소드명을 일치시켜 쿼리문을 실행시킨다.

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="kr.co.vibevillage.database.mapper.TestMapper">

    <select id="testXML" resultType="String">
		SELECT QUERY 작성
    </select>

</mapper>

 

5. 쿼리 실행 결과가 result에 담기고... Model 클래스의 객체를 이용하여 뷰로 데이터바인딩 해준다.

//TestController 의 일부

@GetMapping("/test")
public String databaseConnectionTest(Model model) {
    String result = testService.testXML();

    model.addAttribute("result", result);

    return "index";
}

 

이렇게 Thymeleaf 설정까지 완료하였다. 개발에 필요한 설정이 완료된 프로젝트를 팀원들과 공유해 보겠다.

 

프로젝트 공유

Git Repository를 생성한 뒤, 멤버들을 초대하여 하나의 레파지토리로 형상관리를 시작한다. 팀원들과 함께하는 팀 프로젝트인 만큼, GitHub Repository 관리를 위해 2명 이상의 승인이 있을 때 Pull Request가 가능하도록 설정해 준다. Repository > Settings > Branches > Branch name pattern 경로에 master 브랜치명을 기입해 준다.

 

아직 Git 사용에 어려움을 겪고 있는 팀원들의 의견을 수렴하여 GitFlow 전략은 사용하지 않고.. 팀원의 이름 이니셜로 브랜치를 생성해서 마스터 브랜치와 분리하여 관리하기로 했다.

나의 HJ 브랜치...

HJ 브랜치에 프로젝트를 커밋한다. 그리고 Pull Request 요청을 보내 팀원들의 승인을 기다린다... 커밋을 할 때에는 메세지 규칙을 반드시 지키자고 팀원들과 꼭 꼭 약속하였다. 코드 리뷰도 확실하게 해 주고 어중이떠중이 프로젝트가 될 수는 없다....

팀 프로젝트의 첫번째 커밋
팀원들의 승인...
master branch

master 브랜치에 프로젝트가 업로드되었다. 팀원들은 이 자료를 내려받아 구현하고자 하는 기능을 구현하면 된다! 

김현중 (keemhing)