Hướng dẫn sử dụng Spring Boot và Mustache

Xem thêm các chuyên mục:

1- Mustache là gì?

Mustache là một hệ thống Web Template (mẫu web), nó được sử dụng kết hợp với dữ liệu của tầng Model để tạo ra các tập tin HTML. Nó được hỗ trợ bởi nhiều ngôn ngữ như Java, ActionScript, C++, Clojure, CoffeeScript, ColdFusion, PHP, ....
Mustache được mô tả như là một hệ thống phi logic (logic-less), vì nó không có câu lệnh điều khiển dòng chảy của chương trình một cách rõ ràng, chẳng hạn như nó không có lệnh if/else (if/else statement), và cũng không có lệnh vòng lặp, thay vào đó nó sử dụng biểu thức lambdamustache tags (Thẻ mustache).
Giả sử "employees" là một danh sách, trong ngữ cảnh này cặp thẻ mở & đóng: {{#employees}} & {{/employees}} sẽ tương đương với một vòng lặp trên danh sách "employees".
Sở dĩ nó được đặt tên là "Mustache" (Râu mép) vì cú pháp của Mustache thường xuyên sử dụng cặp dấu ngặc nhọn { }, giống như cặp ria mép.

2- Một vài ví dụ với Mustache

Có thể bạn sẽ gặp một số rắc rối và khó hiểu với Mustache trong lần đầu tiên tiếp xúc với nó. Dưới đây là một vài ví dụ, nó cho thấy sự kỳ quặc của hệ thống này.

if/else?

Mustache đơn giản là không có câu lệnh điều kiện if/else, vì vậy bạn phải tự tạo ra logic cho nó.
Java Code:
boolean kiss = true;

boolean hug = true;

boolean slap = false;
Mustache Template:
{{#kiss}}
  Kiss ...
{{/kiss}}

{{#hug}}
  Hug ...
{{/hug}}


{{#slap}}
  Hic Hic ...
{{/slap}}
Kết quả:
Kiss ...
Hug ...

{{.}}

Trong Mustache, {{.}} là một thẻ (tag) đặc biệt, hãy xem một ví dụ:
Nếu bạn có dữ liệu như sau:
int[] numbers = new int[] {1, 2, 3, 4, 5};

String string =  "Wheee!";
 
Mustache Template:
{{# numbers }}
* {{ . }}
{{/ numbers }}

-----

{{# string }}
   {{ . }}
{{/ string }}
Kết quả nhận được:
* 1
* 2
* 3
* 4
* 5

----

Wheee!

3- Tạo dự án Spring Boot

Trên Eclipse tạo một dự án Spring Boot:
Để có thể sử dụng Mustache cho tầng View bạn cần khai báo phụ thuộc spring-boot-starter-mustache trong tập tin pom.xml:
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
Nội dung đầy đủ của tập tin pom.xml:
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.o7planning</groupId>
    <artifactId>SpringBootMustache</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>SpringBootMustache</name>
    <description>Spring Boot + Groovy</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mustache</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
SpringBootMustacheApplication.java
package org.o7planning.sbmustache;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootMustacheApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootMustacheApplication.class, args);
    }
    
}

4- Model, DAO

Employee.java
package org.o7planning.sbmustache.model;

import java.util.Date;

public class Employee {

    private Long empId;
    private String empNo;
    private String empName;
    private Date hireDate;

    public Employee() {

    }

    public Employee(Long empId, String empNo,
            String empName, Date hireDate) {
        this.empId = empId;
        this.empNo = empNo;
        this.empName = empName;
        this.hireDate = hireDate;
    }

    public Long getEmpId() {
        return empId;
    }

    public void setEmpId(Long empId) {
        this.empId = empId;
    }

    public String getEmpNo() {
        return empNo;
    }

    public void setEmpNo(String empNo) {
        this.empNo = empNo;
    }

    public String getEmpName() {
        return empName;
    }

    public void setEmpName(String empName) {
        this.empName = empName;
    }

    public Date getHireDate() {
        return hireDate;
    }

    public void setHireDate(Date hireDate) {
        this.hireDate = hireDate;
    }
    
}
 
EmployeeDAO.java
package org.o7planning.sbmustache.dao;

import java.sql.Date;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import org.o7planning.sbmustache.model.Employee;
import org.springframework.stereotype.Repository;

@Repository
public class EmployeeDAO {

    public List<Employee> getEmployees()  {
        
        Date hireDate1= Date.valueOf(LocalDate.parse("2000-12-11"));
        Employee e1= new Employee(1L, "E01", "Tom", hireDate1);
        
        Date hireDate2= Date.valueOf(LocalDate.parse("2001-12-21"));
        Employee e2= new Employee(2L, "E02", "Jerry", hireDate2);
        
        List<Employee> list= new ArrayList<Employee>();
        list.add(e1);
        list.add(e2);
        return list;        
    }    
    
}

5- Controller, Mustache Template

MainController.java
package org.o7planning.sbmustache.controller;

import java.util.List;

import org.o7planning.sbmustache.dao.EmployeeDAO;
import org.o7planning.sbmustache.model.Employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MainController {

    @Autowired
    private EmployeeDAO employeeDAO;

    
    @RequestMapping("/")
    public String handleRequest(Model model) {

        List<Employee> employees = employeeDAO.getEmployees();
        model.addAttribute("employees", employees);
        return "employee";
    }

}
Tạo tập tin employee.mustache nằm trong thư mục resources/templates của project.
Chú ý: Nếu bạn sử dụng Spring Boot < 2.x thì các tập tin Mustache Template phải có đuôi là html, như vậy bạn cần tạo tập tin employee.html.
employee.mustache
<html>
<head>
<title>Spring Boot Mustache</title>
<style>
table {
    border-collapse: collapse;
}

table, td, th {
    border: 1px solid #999;
    padding: 5px;
}
</style>
</head>
<body>
    <h2>Employees</h2>
    <table>
        <tr>
            <th>Emp Id</th>
            <th>Emp No</th>
            <th>Emp Name</th>
            <th>Hire Date</th>
        </tr>

        {{#employees}}
        <tr>
            <td>{{empId}}</td>
            <td>{{empNo}}</td>
            <td>{{empName}}</td>
            <td>{{hireDate}}</td>
        </tr>
        {{/employees}}

    </table>
</body>
</html>
Spring Boot 2.x tự động cấu hình Mustache với các thuộc tính mặc định sau đây:
application.properties (Default by Spring Boot)
spring.mustache.prefix=classpath:/templates/
spring.mustache.suffix=.mustache
Hình vẽ mô tả luồng đi của ứng dụng và mối liên hệ giữa ControllerMustache View:

6- Chạy ứng dụng

Nhấn phải chuột vào Project chọn:
  • Run As/Spring Boot App
Sau đó truy cập vào địa chỉ:

Xem thêm các chuyên mục: