springboot-thymeleaf

1,简介

Thymeleaf是用于Web和独立环境的服务器端Java模板引擎。它能够处理HTML、XML、JavaScript、CSS甚至纯文本。

Thymeleaf的主要目标是提供一种简洁的,具有更好可维护性的创建模板的方法。为了实现这一点,它基于自然的模板概念,在不影响被当做设计原型的模板的前提下,将它的逻辑注入到模板文件中。这样既改善了设计上的沟通,也弥合了设计与开发团队间的分歧。

Thymeleaf从一开始设计时就考虑到了Web标准--尤其是HTML5--如果需要的话,可以创建完全校验的模板。

Thymeleaf可以处理6种模板,每种模板都称为模板模式:

HTML,XML,TEXT,JAVASCRIPT,CSS,RAW。

有两种标记模板模式(HTML和XML),三种文本模板模式(TEXT,JAVASCRIPT和CSS)和一种无操作模板模式(RAW),每种类型都被称为一种模板模式。

  1. HTML模板模式可以是任何类型的HTML,包括HTML5,HTML4和XHTML。这种模式不会做内容验证或格式检查,并且模板代码/结构在输出时尽可能保持原样。
  2. XML模板模式允许XML格式的输入。这样,代码格式必须是完整的--不允许未闭标签和未加引号的属性,如果格式错误,解析器会抛出异常。注意,不会对DTD或XML Schema验证。
  3. TEXT模板模式可对非标记性质的模板使用特殊语法。例如,文本电子邮件或模板化文档。注意,HTML或XML模板也可作为TEXT处理,在这种情况下,它们不会被解析为标记,而每个tag,DOCTYPE,注释等都被视为纯文本。
  4. JAVASCRIPT模板模式允许处理Thymeleaf应用程序中的JS文件。这意味着能像在HTML文件中那样在JS文件中使用模型数据,但要使用JS特有的集成方式,比如特殊转义(specialized escaping)或自然脚本(natural scripting)。JAVASCRIPT模板模式被看成是文本模式,因此使用与文本模板模式相同的特定语法。
  5. CSS模板模式允许处理Thymeleaf应用程序中涉及的CSS文件。类似于JAVASCRIPT模式,CSS模板模式也是文本模式,并使用TEXT模板模式中的特殊处理语法。
  6. RAW模板模式根本不会处理模板。它的作用是将未处理的资源(文件、URL响应等)插入正在处理的模板中。例如,可将HTML格式外部的、不受控制的资源包含到应用程序模板中,并且尽可能地让这些资源包含的任何Thymeleaf代码都不会被执行。

Thymeleaf是一个极具扩展性的模板引擎(实际上,它可以被称为模板引擎框架),它允许定义和定制模板处理的方式,以使其细节更加完善。

把某些逻辑用来标记工件(标记、文本、注释或占位符)的对象称为处理器,而一组这样的处理器(可能还有一些额外的工件)通常由方言组成(方言是指包含以th开头的属性,如<span th:text="...">)。Thymeleaf的核心库开箱即用地提供了一种称为标准方言的方言,对大多数用户来说这就足够了。

注意,方言实际上可以没有处理器,并且完全由其它类型的工件组成,但是处理器绝对是最常见的用例。

当然,如果想在利用库的高级特性的同时,定义自己的处理逻辑,那么,可以创建自己的方言(甚至扩展标准方言)。Thymeleaf还可以配置为一次使用几种方言。

标准方言的大多数处理器是属性处理器。这允许浏览器在处理HTML模板文件之前就正确地显示它们,因为它们会忽略额外的属性。例如,虽然使用标记库的JSP可能包含一些代码片段,但浏览器不能直接显示这些代码片段,比如:

<form:inputText name="userName" value="${user.name}" />

用标准方言实现相同的功能。

<input type="text" name="userName" value="James Carrot" th:value="${user.name}" />

这段代码不仅可以准确显示,而且还可以指定一个属性值(本例为James Carrot),当在浏览器中静态打开,这个属性值就能显示出来。而这将在处理模板时,由${user.name}的值替代。

2,示例

2.1,pom-引入thymeleaf

直接使用了webjars。

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- 前端资源 webjars begin -->

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>0.34</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.1.3</version>
        </dependency>

        <!-- 前端资源 webjars end -->

pom的完整内容在后面。

2.2,建立index.html文件

在resources/templates下,创建index.html。
thymeleaf模板页面默认放在/templates下。如无特殊说明,所有html都在这里。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css">

<title>主页</title>
</head>
<body>
    <div class="container">
        <h2>来自Thymeleaf模板的内容</h2>
        <h3>Hello Thymeleaf~</h3>
        <h3>Location: templates/index.html</h3>
    </div>
</body>
</html>

2.3,创建controller

不加任何内容的controller,访问index。

package com.thm.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {
    @RequestMapping("/index")
    public String index() {
        return "index";
    }
}

2.4,application文件

也可不加,基本都是默认配置。

# 可改变模板文件的位置

#spring.thymeleaf.prefix=/WEB-INF/page/

spring.thymeleaf.encoding=UTF-8

# 开发时关闭缓存,不然没法看到实时页面

spring.thymeleaf.cache=false

2.5,主程序

package com;

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

@SpringBootApplication
public class ThymeApplication {

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

运行,访问http://localhost:8080/,看下效果。

2.6,创建新index.html文件

在main里创建目录webapp/WEB-INF/page,创建文件index.html。

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" type="text/css" href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css">

<title>index</title>
</head>
<body>
    <div class="container">
        <h2>Thymeleaf首页</h2>
        <h3>这是个例子</h3>
        <h3>Location: webapp/WEB-INF/page/index.html</h3>
    </div>
</body>
</html>

2.7,更改模板位置

# 改变模板文件的位置
spring.thymeleaf.prefix=/WEB-INF/page/

运行,访问http://localhost:8080/index,对比变化的地方。

可见到访问的位置已经发生了变化。

2.8,创建show.html

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" type="text/css" media="all"
    href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css">

<script type="text/javascript" src="/webjars/jquery/3.3.1/jquery.min.js/"></script>
<script type="text/javascript" src="/webjars/bootstrap/4.1.3/js/bootstrap.min.js"></script>

<title>多语言内容</title>

</head>
<body>

    <div class="container">
        <div class="row">
            <div class="col-md-4">
                <div class="panel panel-primary">
                    <div class="panel-heading text-center">
                        <span class="panel-title card text-white bg-primary mb-1">个人信息</span>
                    </div>
                    <div class="panel-body card text-white bg-secondary mb-3">
                        编号:<span th:text="#{student.id}" class="card text-white bg-success mb-1">3</span><br />
                        姓名:<span th:text="#{student.name}" class="card text-white bg-success mb-1">这是姓名</span><br />
                        性别:<span th:text="#{student.gender}" class="card text-white bg-success mb-1">男</span><br />
                        年龄:<span th:text="#{student.age}" class="card text-white bg-success mb-1">22</span><br />
                        电话:<span th:text="#{student.phone}" class="card text-white bg-success mb-1">15812341111</span><br />
                    </div>
                </div>
            </div>
        </div>
    </div>

</body>
</html>

其中的显示的字段会被资源文件中的字符串替换掉。

2.9,创建资源文件

多语言资源文件默认放在/static/下,可在这里建独立目录i18n,放以特定文件名开头的不同语言的文件。

1、中文,messages_zh_CN.properties,需要用unicode编码,通过native2ascii a.txt转换出来。

student.id=1
student.name=\u4f4f\u5bbf\u8d39
student.gender=\u5e74\u6ee1
student.age=882
student.phone=13111112222

2、英文,默认的,messages.properties,不需要转换

student.id=1
student.name=住宿费
student.gender=年满
student.age=882
student.phone=13111112222

3、修改application.properties,设置资源文件位置

spring.messages.basename=static/i18n/messages
#缓存刷新时间
spring.messages.cache-seconds=2
spring.messages.encoding=UTF-8

2.10,更新controller

加上新的映射。

    @RequestMapping("/sst")
    public String showStudent() {
        return "show";
    }

运行,看看效果,http://localhost:8080/show。

2.11,创建model

访问数据库,用mongodb。数据库-test,用户名/密码-test/test,表名(集合)是userInfo。

@Document(collection = "userInfo")
public class User implements Serializable {

    private static final long serialVersionUID = -1L;

    @Id
    private String            id;
    private long              uid;
    private String            userName;
    private String            userAddr;

    public User() {
        super();
    }

    public User(Integer uid, String userName, String userAddr) {
        super();
        this.uid = uid;
        this.userName = userName;
        this.userAddr = userAddr;
    }

    public User(String id, Integer uid, String userName, String userAddr) {
        super();
        this.id = id;
        this.uid = uid;
        this.userName = userName;
        this.userAddr = userAddr;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public long getUid() {
        return uid;
    }

    public void setUid(long uid) {
        this.uid = uid;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserAddr() {
        return userAddr;
    }

    public void setUserAddr(String userAddr) {
        this.userAddr = userAddr;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", uid=" + uid + ", userName=" + userName + ", userAddr=" + userAddr + "]";
    }
}

2.12,创建dao

package com.thm.dao;

import java.util.List;

import org.springframework.data.mongodb.repository.MongoRepository;

import com.thm.model.User;

public interface UserRepository extends MongoRepository<User, String> {

    User findByUserName(String userName);

    List<User> findByUserNameStartingWith(String prefix);

    List<User> findByUserNameEndingWith(String suffix);

    void deleteByUid(long uid);

}

2.13,创建service

package com.thm.service;

import java.util.List;

import com.thm.model.User;

public interface UserService {

    void save(User user);

    void delByUid(long uid);

    void delById(String id);

    void update(User user);

    User findByUserName(String userName);

    List<User> findByNameStartingWith(String prefix);

    List<User> findByNameEndingWith(String suffix);

    List<User> findList();

    User findById(String id);

}

package com.thm.service;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.thm.dao.UserRepository;
import com.thm.model.User;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepo;

    @Override
    public void save(User user) {
        userRepo.save(user);
    }

    @Override
    public User findByUserName(String userName) {
        return userRepo.findByUserName(userName);
    }

    @Override
    public List<User> findByNameStartingWith(String prefix) {

        return userRepo.findByUserNameStartingWith(prefix);
    }

    @Override
    public List<User> findByNameEndingWith(String suffix) {

        return userRepo.findByUserNameEndingWith(suffix);
    }

    @Override
    public List<User> findList() {
        return userRepo.findAll();
    }

    @Override
    public User findById(String id) {
        Optional<User> opUser = userRepo.findById(id);
        return opUser.orElse(null);
    }

    @Override
    public void update(User user) {
        userRepo.save(user);
    }

    @Override
    public void delByUid(long uid) {
        userRepo.deleteByUid(uid);
    }

    @Override
    public void delById(String id) {
        userRepo.deleteById(id);
    }
}

图省事,写一起了。这一层也可以去掉,直接用dao。

2.14,创建controller

package com.thm.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.thm.model.User;
import com.thm.service.UserService;

@Controller
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserService         userService;

    private static final String RET_USER = "redirect:/user/";

    @RequestMapping(method = RequestMethod.GET)
    public String getUserList(ModelMap map) {
        map.addAttribute("users", userService.findList());

        return "userList";
    }

    // 显示创建用户的表单
    @RequestMapping(value = "/create", method = RequestMethod.GET)
    public String createUser(ModelMap map) {
        map.addAttribute("user", new User());
        map.addAttribute("action", "create");

        return "userForm";
    }

    /**
     * 创建用户
     * 处理"/user"的POST请求,用来获取用户列表
     * 通过@ModelAttribute绑定参数,也通过@RequestParam从页面中传递参数
     */
    @RequestMapping(value = "/create", method = RequestMethod.POST)
    public String postUser(@ModelAttribute User user) {
        userService.save(user);

        return RET_USER;
    }

    /**
     * 更新用户表单
     * 处理"/user/{id}"的GET请求,通过URL中的id值获取User信息
     */
    @RequestMapping(value = "/update/{id}", method = RequestMethod.GET)
    public String getUser(@PathVariable(name = "id") String id, ModelMap map) {
        map.addAttribute("user", userService.findById(id));
        map.addAttribute("action", "update");
        return "userForm";
    }

    /**
     * 处理"/user/{id}"的PUT请求,更新User
     */
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public String putUser(@ModelAttribute User user) {
        userService.update(user);
        return RET_USER;
    }

    /**
     * 处理"/user/{uid}"的GET请求,删除User
     */
    @RequestMapping(value = "/deletebyuid/{uid}", method = RequestMethod.GET)
    public String deleteUser(@PathVariable(name = "uid") long uid) {

        userService.delByUid(uid);
        return RET_USER;
    }

    @RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
    public String deleteUser(@PathVariable(name = "id") String id) {
        userService.delById(id);
        return RET_USER;
    }
}

更新application.properties

# 数据库连接

spring.data.mongodb.uri=mongodb://test:test@localhost:27017/test

2.15,创建新模板文件

1,新增userform.html

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" type="text/css" media="all"
    href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css">

<script type="text/javascript" src="/webjars/jquery/3.3.1/jquery.min.js/"></script>
<script type="text/javascript" src="/webjars/bootstrap/4.1.3/js/bootstrap.min.js"></script>

<title>userForm</title>

</head>
<body>

    <div class="container">
        <legend>
            <strong>用户信息</strong>
        </legend>
        <form th:action="@{/user/{action}(action=${action})}" method="post" class="card bg-light">
            <div class="form-group">
                <label for="id" class="col-sm-2 control-label">ID</label>
                <div class="col-xs-4">
                    <input type="text" class="form-control" id="id" name="id" th:value="${user.id}" />
                </div>
            </div>

            <div class="form-group">
                <label for="uid" class="col-sm-2 control-label">编号</label>
                <div class="col-xs-4">
                    <input type="text" class="form-control" id="uid" name="uid"
                        th:value="${user.uid}" />
                </div>
            </div>

            <div class="form-group">
                <label for="userName" class="col-sm-2 control-label">名称</label>
                <div class="col-xs-4">
                    <input type="text" class="form-control" id="userName" name="userName"
                        th:value="${user.userName}" />
                </div>
            </div>

            <div class="form-group">
                <label for="userAddr" class="col-sm-2 control-label">地址</label>
                <div class="col-xs-4">
                    <input type="text" class="form-control" id="userAddr" name="userAddr"
                        th:value="${user.userAddr}" />
                </div>
            </div>

            <div class="form-group">
                <div class="col-sm-offset-2 col-sm-10">
                    <input class="btn btn-primary" type="submit" value="提交" /> <input
                        class="btn btn-secondary" type="button" value="返回" onclick="history.back()" />
                </div>
            </div>
        </form>
    </div>

</body>
</html>

2,列表userlist.html

<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" type="text/css" media="all"
    href="/webjars/bootstrap/4.1.3/css/bootstrap.min.css">

<script type="text/javascript" src="/webjars/jquery/3.3.1/jquery.min.js/"></script>
<script type="text/javascript" src="/webjars/bootstrap/4.1.3/js/bootstrap.min.js"></script>

<title>userList</title>

</head>
<body>
    <div class="container">
        <table class="table table-bordered table-hover alert alert-success ">
            <legend>
                <strong>用户列表</strong>
            </legend>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>编号</th>
                    <th>名称</th>
                    <th>地址</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <tr th:each="user : ${users}">
                    <th scope="row"><a th:href="@{/user/update/{id}(id=${user.id})}"
                        th:text="${user.id}"></a></th>
                    <td th:text="${user.uid}"></td>
                    <td th:text="${user.userName}"></td>
                    <td th:text="${user.userAddr}"></td>
                    <td><a class="btn btn-success" th:href="@{/user/create}">新增</a> <a
                        class="btn btn-danger" th:href="@{/user/deletebyuid/{uid}(uid=${user.uid})}">删除</a></td>
                </tr>
            </tbody>
        </table>
    </div>
</body>
</html>

2.16,更新pom

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

运行,http://localhost:8080/user

<?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.sitech.billing.biop</groupId>
    <artifactId>webt</artifactId>
    <packaging>jar</packaging>
    <version>1.0.0</version>
    <name>Thymeleaf Exam</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath />
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud-task.version>2.0.0.RELEASE</spring-cloud-task.version>
        <spring-cloud.version>Finchley.RELEASE</spring-cloud.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-thymeleaf</artifactId>
        </dependency>

        <!-- 前端资源 webjars begin -->

        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator</artifactId>
            <version>0.34</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>bootstrap</artifactId>
            <version>4.1.3</version>
        </dependency>

        <!-- 前端资源 webjars end -->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
        </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>

猜你喜欢

转载自blog.csdn.net/casepk/article/details/82816964
今日推荐