Spring : Mustache

  • Mustache는 템플릿 엔진 중 하나이다.

템플릿 엔진

  • 지정된 템플릿 양식과 데이터가 합쳐져 HTML 문서를 출력하는 소프트웨어를 이야기한다.

서버 템플릿 엔진

  • JSP(Spring JSP), Freemarker
  • 서버 템플릿 엔진은 서버에서 구동된다.
    서버에서 Java 코드로 문자열을 만든 뒤 이 문자열을 HTML 로 변환하여 브라우저로 전달한다.
  • 이때 자바 스크립트 코드는 단순한 문자열이다.
  • 이게 브라우저에서 작동하게 되면 그때는 서버 템플릿 엔진의 손을 벗어나 제어할 수 없다.

클라이언트 템플릿 엔진

  • React, Vue
  • 서버에서 이미 코드가 벗어난 경우이다.
  • JSON, XML 형식의 데이터만 전달하고 클라이언트에서 조립한다.

그러면 Mustach는 무슨 템플릿 엔진인가?

  • 수많은 언어를 지원하는 가장 심플한 템플릿 엔진
  • 다른 엔진에 비해 문법이 심플하다.
  • 로직 코드를 사용할 수 없어 View의 역할과 서버의 역할이 명확하게 분리된다.
  • Mustache.js, Mustacje.java 2가지나 다 있어, 하나의 문법으로 클라이언트/서버 템플릿 모두 사용 가능

실습

  • 컨트롤러에서 반환되는 값을 경로가 되어 URL을 매핑한다.

index.mustache

{{>layout/header}}

<h1>스프링부트로 시작하는 웹 서비스 v1.0.5</h1>
<div class="col-md-12">
    <div class="row">
        <div class="col-md-6">
            <a href="/posts/save" role="button" class="btn btn-primary">글 등록</a>
            {{#userName}}
                Logged in as: <span id="user">{{userName}}</span>
                <a href="/logout" class="btn btn-info active" role="button">Logout</a>
            {{/userName}}
            {{^userName}}
                <a href="/oauth2/authorization/google" class="btn btn-success active" role="button">Google Login</a>
                <a href="/oauth2/authorization/naver" class="btn btn-secondary active" role="button">Naver Login</a>
            {{/userName}}
        </div>
    </div>
    <br>
    <!-- 목록 출력 영역 -->
    <table class="table table-horizontal table-bordered">
        <thead class="thead-strong">
        <tr>
            <th>게시글번호</th>
            <th>제목</th>
            <th>작성자</th>
            <th>최종수정일</th>
        </tr>
        </thead>
        <tbody id="tbody">
        {{#posts}}
            <tr>
                <td>{{id}}</td>
                <td><a href="/posts/update/{{id}}">{{title}}</a></td>
                <td>{{author}}</td>
                <td>{{modifiedDate}}</td>
            </tr>
        {{/posts}}
        </tbody>
    </table>
</div>

{{>layout/footer}}

header.mustache

<!DOCTYPE HTML>
<html>
<head>
    <title>스프링부트 웹서비스</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
</head>
<body>

footer.mustache

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>

<!--index.js 추가-->
<script src="/js/app/index.js"></script>
</body>
</html>

테스트 코드

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class IndexControllerTest {

  @Autowired
  private TestRestTemplate restTemplate;

  @Test
  public void 메인페이지_로딩() {
    //when
    String body = this.restTemplate.getForObject("/", String.class);

    //then
    assertThat(body).contains("스프링부트로 시작하는 웹 서비스");
  }
}

좋은 웹페이지 즐겨찾기