在 Spring Boot Mustache 教程中,我们将使用 Mustache 模板引擎和 HSQLDB 数据库创建一个简单的 Spring Boot Web 应用。
Spring 是流行的 Java 应用框架。 Spring Boot 致力于创建独立的,基于生产级别的基于 Spring 的应用,而无任何麻烦。
HSQLDB 是完全用 Java 创建的开源关系数据库管理系统。 它提供了一个小型,快速的多线程事务型数据库引擎,具有基于内存和基于磁盘的表,并支持嵌入式和服务器模式。 它包括一个功能强大的命令行 SQL 工具和简单的 GUI 查询工具。
Moustache
Moustache 是一个简单的 Web 模板系统。 它可用于许多编程语言,包括 Java。 由于没有任何显式的控制流语句(例如 if 和 else 条件语句或 for 循环),因此,Mustache 被描述为无逻辑的。 可以使用节标记处理列表和 lambda 来实现循环和条件评估。
Spring Boot Moustache 示例
以下示例是使用 Mustache 模板引擎的 Spring Boot Web 应用。 应用的数据位于 HSQLDB 数据库中。
$ tree.├── pom.xml└── src ├── main │ ├── java │ │ └── com │ │ └── zetcode │ │ ├── Application.java │ │ ├── bean │ │ │ └── Car.java │ │ ├── controller │ │ │ └── MyController.java │ │ └── service │ │ ├── CarService.java │ │ └── ICarService.java │ └── resources │ ├── application.yml │ ├── data-hsqldb.sql │ ├── schema-hsqldb.sql │ ├── static │ │ └── css │ │ └── style.css │ └── templates │ ├── index.html │ └── showCars.html └── test └── java
这是项目结构。 模板文件的后缀为.html。 它们默认位于src/main/resources/template目录中。 当在 Maven POM 文件中找到依赖项时,Spring Boot 会自动配置 Mustache。
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>com.zetcode</groupId> <artifactId>SpringBootMustache</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mustache</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
这是 Maven 构建文件。 spring-boot-devtools启用热插拔,禁用模板缓存并启用实时重新加载。 spring-boot-starter-mustache是用于使用 Mustache 构建 Spring MVC 应用的入门程序。 hsqldb是 HSQLDB 的驱动程序。 spring-boot-starter-jdbc是在 Spring Boot 中使用 JDBC 的入门工具。
Car.java
package com.zetcode.bean;public class Car { private Long id; private String name; private int price; public Car() {} public Car(Long id, String name, int price) { this.id = id; this.name = name; this.price = price; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPrice() { return price; } public void setPrice(int price) { this.price = price; } @Override public String toString() { return "Car{" + "id=" + id + ", name=" + name + ", price=" + price + '}'; }}这是Car bean 类。 它包含汽车 ID,名称和价格字段。
application.yml
server: context-path: /myappspring: main: banner-mode: "off" datasource: platform: hsqldblogging: level: org: springframework: ERROR
application.yml是主要的 Spring Boot 配置文件。 context-path定义 Web 应用的名称。 我们通过localhost:8080/myapp/ URL 访问我们的应用。 使用banner-mode属性,我们可以关闭 Spring 标语。 该平台值用于 SQL 初始化脚本:schema-${platform}.sql和data-${platform}.sql中。 另外,我们将 spring 框架的日志记录级别设置为 ERROR。
注意,我们没有配置数据源。 如果没有配置数据,Spring 会以内存模式自动配置 HSQLDB。 我们希望有一个内存数据库,因此我们让 Spring 进行自动配置。
schema-hsqldb.sql
CREATE TABLE CARS(ID BIGINT IDENTITY PRIMARY KEY, NAME VARCHAR(30), PRICE INT);
该 SQL 脚本创建CARS表。 HSQLDB 使用IDENTITY子句创建自动增加的列。 默认情况下,id 从零开始。
data-hsqldb.sql
INSERT INTO CARS(NAME, PRICE) VALUES('Audi', 52642);INSERT INTO CARS(NAME, PRICE) VALUES('Mercedes', 57127);INSERT INTO CARS(NAME, PRICE) VALUES('Skoda', 9000);INSERT INTO CARS(NAME, PRICE) VALUES('Volvo', 29000);INSERT INTO CARS(NAME, PRICE) VALUES('Bentley', 350000);INSERT INTO CARS(NAME, PRICE) VALUES('Citroen', 21000);INSERT INTO CARS(NAME, PRICE) VALUES('Hummer', 41400);INSERT INTO CARS(NAME, PRICE) VALUES('Volkswagen', 21600);该脚本用数据填充表。 这两个脚本都位于类路径的根目录中。
ICarService.java
package com.zetcode.service;import com.zetcode.bean.Car;import java.util.List;public interface ICarService { public List<Car> findAll();}ICarService提供了一种从数据源获取所有城市的合同方法。
CarService.java
package com.zetcode.service;import com.zetcode.bean.Car;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.BeanPropertyRowMapper;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Service;@Servicepublic class CarService implements ICarService { @Autowired private JdbcTemplate jtm; @Override public List<Car> findAll() { String sql = "SELECT * FROM CARS"; List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class)); return cars; }}CarService包含findAll()方法的实现。 我们借助JdbcTemplate从CARS表中检索所有汽车。
@Autowiredprivate JdbcTemplate jtm;
注入JdbcTemplate。
String sql = "SELECT * FROM CARS";
这是要执行的 SQL。 我们从CARS表中选择所有汽车。
List<Car> cars = jtm.query(sql, new BeanPropertyRowMapper(Car.class));
BeanPropertyRowMapper将一行转换为指定映射目标类的新实例。
MyController.java
package com.zetcode.controller;import com.zetcode.bean.Car;import com.zetcode.service.ICarService;import java.util.HashMap;import java.util.List;import java.util.Map;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;@Controllerpublic class MyController { @Autowired private ICarService carService; @RequestMapping("/") public String index(Model model) { return "index"; } @RequestMapping("/showCars") public ModelAndView showCars() { List<Car> cars = carService.findAll(); Map<String, Object> params = new HashMap<>(); params.put("cars", cars); return new ModelAndView("showCars", params); }}这是 Spring Boot Web 应用的控制器类。 控制器被饰以@Controller注解。 控制器具有两个映射:一个用于主页的映射,一个用于列出所有汽车的映射。 当 Spring Boot 在 Maven POM 文件中检测到 Mustache 启动程序时,它会自动配置 Mustache 视图。
@Autowiredprivate ICarService carService;
我们将ICarService注入到带有@Autowired注解的字段中。
@RequestMapping("/")public String index(Model model) { return "index";} "index"是位于预定义template目录中的视图的名称。
@RequestMapping("/showCars")public ModelAndView showCars() { List<Car> cars = carService.findAll(); Map<String, Object> params = new HashMap<>(); params.put("cars", cars); return new ModelAndView("showCars", params);}该控制器方法可提供汽车清单。 我们从汽车服务中找到所有汽车对象,并将结果列表放入参数中。 Spring 将找到名为showCars的 Mustache 视图,并让引擎将模板与数据结合在一起。
style.css
h2 {color: blue}td:nth-child(3) { text-align: right;}style.css是位于src/main/resources/static/css目录中的静态文件。 它将 h2 标签设置为蓝色,并右对齐第三列的数据。
index.html
<!DOCTYPE html><html> <head> <title>Home page</title> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> </head> <body> <a href="showCars">Show cars</a> </body></html>
index.html模板文件是应用的主页。 它包含一个检索所有汽车对象的链接。
showCars.html
<!DOCTYPE html><html> <head> <title>Cars</title> <link rel="stylesheet" href="css/style.css" /> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> </head> <body> <h2>List of cars</h2> <table> <tr> <th>Id</th> <th>Name</th> <th>Price</th> </tr> {{#cars}} <tr> <td>{{id}}</td> <td>{{name}}</td> <td>{{price}}</td> </tr> {{/cars}} </table> </body></html>showCars.html是 Moustache 模板文件,其中包含要用来自模型的数据填充的占位符。 小 Moustache 使用{{}}语法。
<link rel="stylesheet" href="css/style.css" />
我们包括静态 CSS 文件。
{{#cars}}<tr> <td>{{id}}</td> <td>{{name}}</td> <td>{{price}}</td></tr>{{/cars}}{{#cars}}语法称为段。 部分根据当前上下文中键的值,将文本块渲染一次或多次。 一节以{{#name}}开头,以{{/name}}结束。 如果该值是非空列表,则该部分将显示多次。 在每种情况下,该节的上下文都将设置为列表中的元素。
Application.java
package com.zetcode;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); }}我们设置了 Spring Boot 应用。 @SpringBootApplication注解启用自动配置和组件扫描。

Figure: Listing cars
该应用部署在内置的 Tomcat 服务器上,该服务器侦听端口 8080。
在本教程中,我们使用 Mustache 和 HSQLDB 创建了一个 Spring Boot Web 应用。
