本文将介绍Spring Boot + Thymeleaf + Maven的例子。我们将在此提供如何使用Spring Boot与Thymeleaf进行国际化(i18n)、表单验证和日志记录。如果Spring Boot在classpath中扫描到Thymeleaf库,它将自动配置Thymeleaf。我们可以使用application.properties
改变默认的Thymeleaf配置。Thymeleaf是一个服务器端的模板引擎,可以处理XML、HTML等。Thymeleaf可以从i18n消息文件中访问类字段和消息属性。我们可以使用Thymeleaf将我们的类字段与HTML表单元素绑定。我们可以使用Thymeleaf迭代我们的java集合。在我们的例子中,我们将使用Thymeleaf执行表单验证和解除i18n消息。如果Spring Boot启动器使用的是较低版本的Thymeleaf,我们还将提供如何使用Maven来使用Thymeleaf的高版本。我们还将在Thymeleaf视图中使用CSS文件。现在让我们一步一步地讨论这个完整的例子。
找到我们的应用程序中使用的技术。
为了将Thymeleaf与Spring Boot集成,我们需要在构建工具中使用以下Spring Boot启动器,如Maven和Gradle。假设我们使用的是Maven,那么我们将使用以下Maven依赖项。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
这就是在Spring Boot中配置Thymeleaf的全部内容。当Spring Boot在classpath中找到Thymeleaf库时,Spring Boot会自动为Thymeleaf进行必要的配置。
在写这篇文章时,Thymeleaf启动器的最新版本是1.5.3.RELEASE
,它使用Thymeleaf 2.1版本。如果我们想使用更高版本的Thymeleaf,例如Thymeleaf 3.0,那么我们需要在pom.xml
中配置以下属性。
1. thymeleaf.version
2. thymeleaf-layout-dialect.version
假设我们使用的是Maven,那么上述属性将被配置为如下。
<properties>
<thymeleaf.version>3.0.6.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
<java.version>1.8</java.version>
</properties>
现在Spring Boot将使用Thymeleaf版本3.0.6.RELEASE和Thymeleaf布局方言版本2.2.2和java版本1.8。
如果Spring Boot在其classpath中扫描了Thymeleaf库,那么我们就可以使用Thymeleaf了。Spring Boot为Thymeleaf提供了属性,将在application.properties
或application.yml
中进行配置,以改变Thymeleaf与Spring Boot的配置。我们在此列出其中一些。
spring.thymeleaf.mode: 模板模式,将应用于模板。默认是HTML 5
。
spring.thymeleaf.prefix。这是在视图名称前加上的值,用于建立URL。默认值是 classpath:/templates/
。
spring.thymeleaf.senix: 这是与视图名称相加的值,用于建立URL。默认值是.html
。
在默认的Spring Boot和Thymeleaf配置下,我们可以将带有html扩展名的Thymeleaf文件放在以下位置。
src\main\resources\templates
现在我们将讨论如何使用Thymeleaf创建表单元素。
使用Thymeleaf创建<form>。
假设我们在控制器类中有一个方法。
@Controller
@RequestMapping("app")
public class UserController {
@GetMapping("create-user")
public ModelAndView createUserView() {
ModelAndView mav = new ModelAndView();
mav.setViewName("user-creation");
mav.addObject("user", new User());
mav.addObject("allProfiles", getProfiles());
return mav;
}
---
}
当我们访问/app/create-user
URL时,名为user-creation.html
的Thymeleaf文件将会打开,在那里我们将创建一个表单来创建用户。现在看看下面的代码片段。
mav.addObject("user", new User());
属性名称user
将在<form>中与Thymeleaf th:object
属性一起使用。
<form action="#" th:action="@{/app/create-user}" th:object="${user}" method="POST">
th:action
被指定为行动URL,将在表单提交时被调用。在表单提交时,URL /app/create-user
将访问控制器类中的以下方法。
@Controller
@RequestMapping("app")
public class UserController {
---
@PostMapping("create-user")
public ModelAndView createUser(@Valid User user, BindingResult result) {
---
}
}
现在我们将创建一些表单元素。假设我们有一个类,它有对应表单元素的字段。
public class User {
private String userId;
private String userName;
private String gender;
private Boolean married;
private String profile;
}
与表单元素的数据绑定,如<input>和<select>是通过Thymeleaf th:field
属性实现的。假设我们想创建一个输入文本框来获取用户ID。User
类的字段userId
将使用Thymeleaf th:field
绑定到输入文本框,如下所示。
<input type="text" th:field="*{userId}" />
以同样的方式,其他表单元素也将与User
类字段绑定。找到User
类的userName
字段的输入框。
<input type="text" th:field="*{userName}" />
为User
类的gender
字段找到单选按钮。
<input type="radio" th:field="*{gender}" value="Male"/>
<input type="radio" th:field="*{gender}" value="Female"/>
找到married
类中User
字段的复选框。
<input type="checkbox" th:field="*{married}" />
为User
类的profile
字段找到选择元素。
<select th:field="*{profile}">
<option th:each="profile : ${allProfiles}" th:value="${profile}" th:text="${profile}">Profile</option>
</select>
Thymeleaf th:each
将遍历集合。Thymeleaf th:value
属性赋值。allProfiles
是属性名称,将在ModelAndView
中为每个请求添加。
mav.addObject("allProfiles", getProfiles());
getProfiles()
方法将返回所有配置文件的列表。
private List<String> getProfiles() {
List<String> list = new ArrayList<>();
list.add("Developer");
list.add("Manager");
list.add("Director");
return list;
}
Thymeleaf提供了th:text="${...}"
语法,可以用来访问java对象中的一个值。如果我们想显示一个表格中所有项目的报告,我们写代码如下。
<table>
<tr th:each="user : ${allUsers}">
<td th:text="${user.userId}">Id</td>
<td th:text="${user.userName}">Title</td>
</tr>
</table>
在Thymeleaf中,我们可以使用th:href="@{..}"
语法的href来加载CSS或者创建一个链接来重定向一个URL。
当我们使用Spring Boot启动器时,我们的Spring Boot应用程序就可以使用国际化(i18n)。我们需要在以下位置创建属性文件。
src\main\resources\messages.properties
src\main\resources\messages_en.properties
如果locale是en
,那么Spring应用程序将选择messages_en.properties
文件。默认的i18n文件将是messages.properties
。
我们可以使用application.properties
文件中的spring属性改变默认的spring消息配置。例如。
spring.messages.basename。它为消息文件配置了逗号分隔的基础名称。默认是messages
。
spring.messages.encoding: 它配置了消息包的编码。默认为UTF-8
为了显示i18n消息,我们需要使用Thymeleaf th:text="#{...}"
语法。假设我们想为我们的页面标题显示i18n消息,为此我们在消息属性文件中定义了一个键,如下所示。
app.title= Spring Boot + Thymeleaf
那么它将被Thymeleaf以如下方式显示。
<title th:text="#{app.title}"> Title </title>
Thymeleaf提供了#locale
的上下文,我们可以用它来显示语言、国家等特定地区的细节,如下所示。
<p th:text="${#locale.language}"> language</p>
<p th:text="${#locale.country}"> country</p>
为了验证一个字段,我们可以使用Hibernate验证器。当我们使用Spring Boot启动器时,Hibernate验证器库被自动配置在classpath中。现在我们将在我们的类中使用验证器注解,以绑定表单。验证器注解有@NotNull
、@Size
等,来自javax.validation
库。
public class User {
@NotNull
@Size(min=3, max=10)
private String userId;
@NotNull
@Size(min=5, max=20)
private String userName;
@NotNull
private String gender;
private Boolean married;
private String profile;
}
为了启用表单验证,我们需要在Spring控制器的方法参数中使用@Valid
注解,该注解将在表单提交时被调用。我们还需要Spring BindingResult
的实例来了解表单是否被验证。
@PostMapping("create-user")
public ModelAndView createUser(@Valid User user, BindingResult result) {
ModelAndView mav = new ModelAndView();
if(result.hasErrors()) {
logger.info("Validation errors while submitting form.");
mav.setViewName("user-creation");
mav.addObject("user", user);
mav.addObject("allProfiles", getProfiles());
return mav;
}
userService.addUser(user);
mav.addObject("allUsers", userService.getAllUserArticles());
mav.setViewName("user-info");
logger.info("Form submitted successfully.");
return mav;
}
如果表单有验证错误,那么result.hasErrors()
将返回true。如果表单中存在验证错误,那么我们应该再次调用同一个Thymeleaf视图,如果没有验证错误,则执行业务逻辑并重定向到成功视图。
现在在Thymeleaf视图中,我们需要显示验证错误信息。为了检查给定字段名是否存在验证错误,Thymeleaf提供了#fields.hasErrors(...)
,它返回布尔值。
<label th:if="${#fields.hasErrors('userId')}" th:errors="*{userId}" th:class="'error'">Id Error</label>
th:errors
将显示Spring的默认验证错误信息,其依据是我们在与表单元素绑定的类字段中使用的Hibernate验证器注释。如果我们想使用i18n消息来验证错误,那么就使用th:text="#{...}
。
<label th:if="${#fields.hasErrors('userId')}" th:text="#{error.user.id}" th:class="'error'">Id Error</label>
error.user.id
是messages_en.properties
文件中定义的i18n属性。
在Spring Boot应用程序中,Logback依赖性会自动解决。每个Spring Boot启动器都会自己解决spring-boot-starter-logging
。要改变日志的默认配置,我们需要在application.properties
文件中配置日志属性。找到其中的一些属性。
logging.level.*。它作为软件包名称的前缀,用于设置日志级别。
logging.file: 它配置了一个日志文件名来记录文件中的信息。
logging.path: 它只配置了日志文件的路径。Spring boot创建了一个名为spring.log
的日志文件。
假设我们的类包是com.concretepage
,那么可以用logging.level.*
在application.properties
文件中定义日志级别,如下所示。
logging.level.com.concretepage= INFO
现在在任何com.concretepage
包或其子包下的类中,日志级别INFO
将被应用。我们可以按以下方式使用org.slf4j.Logger
。
**1.**在类级别上实例化org.slf4j.Logger
。
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
2. 现在根据需要在类的任何地方使用记录器。
logger.info("Validation errors while submitting form.");
查看Spring boot与Thymeleaf的完整示例。我们将创建具有内部化(i18n)、表单验证和日志的应用程序。查找完整的代码。
找到使用eclipse的演示项目结构。
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.concretepage</groupId>
<artifactId>spring-boot-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-demo</name>
<description>Spring Boot Demo Project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.3.RELEASE</version>
</parent>
<properties>
<thymeleaf.version>3.0.6.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
<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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
找到我们例子中使用的Spring Boot启动器描述。
spring-boot-starter-parent。用于依赖性管理的父POM。
spring-boot-starter-web。用于构建Web、REST应用程序的启动器。它使用Tomcat服务器作为默认的嵌入式服务器。
spring-boot-starter-thymeleaf。用于Thymeleaf与Spring框架的集成。
spring-boot-devtools。它提供了开发者工具。这些工具在应用开发模式中很有帮助。开发者工具的一个特点是在代码有任何变化时自动重启服务器。
User.java
package com.concretepage.domain;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
public class User {
@NotNull
@Size(min=3, max=10)
private String userId;
@NotNull
@Size(min=5, max=20)
private String userName;
@NotNull
private String gender;
private Boolean married;
private String profile;
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Boolean getMarried() {
return married;
}
public void setMarried(Boolean married) {
this.married = married;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
}
我们在上面的类中使用Hibernate验证器进行表单验证。现在找到服务类。
UserService.java
package com.concretepage.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.concretepage.domain.User;
@Service
public class UserService {
private List<User> allUsers = new ArrayList<>();
public List<User> getAllUserArticles(){
return allUsers;
}
public void addUser(User user) {
allUsers.add(user);
}
}
UserController.java。
package com.concretepage.controller;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.concretepage.domain.User;
import com.concretepage.service.UserService;
@Controller
@RequestMapping("app")
public class UserController {
private static final Logger logger = LoggerFactory.getLogger(UserController.class);
@Autowired
private UserService userService;
@GetMapping("create-user")
public ModelAndView createUserView() {
ModelAndView mav = new ModelAndView();
mav.setViewName("user-creation");
mav.addObject("user", new User());
mav.addObject("allProfiles", getProfiles());
return mav;
}
@PostMapping("create-user")
public ModelAndView createUser(@Valid User user, BindingResult result) {
ModelAndView mav = new ModelAndView();
if(result.hasErrors()) {
logger.info("Validation errors while submitting form.");
mav.setViewName("user-creation");
mav.addObject("user", user);
mav.addObject("allProfiles", getProfiles());
return mav;
}
userService.addUser(user);
mav.addObject("allUsers", userService.getAllUserArticles());
mav.setViewName("user-info");
logger.info("Form submitted successfully.");
return mav;
}
private List<String> getProfiles() {
List<String> list = new ArrayList<>();
list.add("Developer");
list.add("Manager");
list.add("Director");
return list;
}
}
application.properties
logging.level.root= WARN
logging.level.org.springframework.web= ERROR
logging.level.com.concretepage= INFO
我们已经在上述属性文件中配置了我们的日志级别。
找到en
地区的消息属性。
messages_en.properties
app.title= Spring Boot + Thymeleaf
app.create-user= Create User
app.user-details= User Details
user.id= Id
user.name= Name
user.gender= Gender
user.married= Married
user.profile= Profile
user.gender.male= Male
user.gender.female= Female
user.form.submit= Submit
user.form.reset= Reset
user.add-more-users= Add More Users
error.user.id= Id must be between 3 to 10 characters.
error.user.name= User name must be between 5 to 20 characters.
error.user.gender= Select gender.
当我们访问该应用程序时,将打开以下页面。
用户-创建.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="#{app.title}"> Title </title>
<link rel="stylesheet" th:href="@{/css/styles.css}"/>
</head>
<body>
<h1 th:text="#{app.create-user}">Create</h1>
<form action="#" th:action="@{/app/create-user}" th:object="${user}" method="POST">
<table>
<tr><td th:text="#{user.id}"/></td>
<td>
<input type="text" th:field="*{userId}" />
<label th:if="${#fields.hasErrors('userId')}" th:text="#{error.user.id}" th:class="'error'">Id Error</label>
</td>
</tr>
<tr><td th:text="#{user.name}"></td>
<td>
<input type="text" th:field="*{userName}" />
<label th:if="${#fields.hasErrors('userName')}" th:text="#{error.user.name}" th:class="'error'">Name Error</label>
</td>
</tr>
<tr><td th:text="#{user.gender}"></td>
<td>
<input type="radio" th:field="*{gender}" value="Male"/><label th:text="#{user.gender.male}">M</label>
<input type="radio" th:field="*{gender}" value="Female"/><label th:text="#{user.gender.female}">F</label>
<label th:if="${#fields.hasErrors('gender')}" th:text="#{error.user.gender}" th:class="'error'">Gender Error</label>
</td>
</tr>
<tr><td th:text="#{user.married}+ '?'"></td>
<td>
<input type="checkbox" th:field="*{married}" />
</td>
</tr>
<tr><td th:text="#{user.profile}"></td>
<td>
<select th:field="*{profile}">
<option th:each="profile : ${allProfiles}" th:value="${profile}" th:text="${profile}">Profile</option>
</select>
</td>
</tr>
<tr><td colspan="2">
<input type="submit" th:value="#{user.form.submit}"/>
<input type="reset" th:value="#{user.form.reset}"/>
</td>
</tr>
</table>
</form>
</body>
</html>
在成功提交表单后,将打开以下页面。
用户信息.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
<title th:text="#{app.title}"> Title </title>
<link rel="stylesheet" th:href="@{/css/styles.css}"/>
</head>
<body>
<h1 th:text="#{app.user-details}">Details</h1>
<table>
<tr>
<th th:text="#{user.id}"/></th>
<th th:text="#{user.name}"></th>
<th th:text="#{user.gender}"></th>
<th th:text="#{user.married}+ '?'"></th>
<th th:text="#{user.profile}"></th>
</tr>
<tr th:each="user : ${allUsers}">
<td th:text="${user.userId}">Id</td>
<td th:text="${user.userName}">Title</td>
<td th:text="${user.gender}">Gender</td>
<td th:text="${user.married}">Married</td>
<td th:text="${user.profile}">Profile</td>
</tr>
</table>
<a href="#" th:href="@{/app/create-user}" th:text="#{user.add-more-users}">Add User</a>
</body>
</html>
styles.css
.error{
color: red;
font-size: 15px;
}
.user{
color: blue;
font-size: 15px;
}
table {
border-collapse: collapse;
}
table, th, td {
border: 1px solid black;
}
找到Spring boot主类来运行应用程序。
MyApplication.java
package com.concretepage;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
我们可以通过以下方式运行我们的应用程序。
mvn clean eclipse:eclipse
然后在eclipse中刷新该项目。通过点击运行为->Java应用程序来运行主类MyApplication
。Tomcat服务器将被启动。
mvn spring-boot:run
Tomcat服务器将被启动。
mvn clean package
我们将在target
文件夹中得到可执行JAR spring-boot-demo-0.0.1-SNAPSHOT.jar。运行这个JAR的方式是
java -jar target/spring-boot-demo-0.0.1-SNAPSHOT.jar
Tomcat服务器将被启动。
现在我们准备好测试该应用程序。访问下面给出的URL。
http://localhost:8080/app/create-user
我们将得到以下视图来创建一个用户。
成功提交表单后,我们将得到用户的报告页面。
祝你学习Spring Boot愉快!
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.concretepage.com/spring-boot/spring-boot-thymeleaf-maven-example
内容来源于网络,如有侵权,请联系作者删除!