梦入琼楼寒有月,行过石树冻无烟

Spring boot and Thymeleaf Web

在上述文章之中我们主要撰写并列举了常用的Thymeleaf标签及表达式,通过上述文章我们将会在本章中列举一些真实的项目案例如表单的提交、国际化页面的撰写等。

表单

表单是在前端页面中不可缺失的一部分,通常应用在搜索、登入/注册、提交等页面之中,通过本书列举的Thymeleaf例子可更容易编写由Thymeleaf的动态页面:

login.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>login</title>
</head>
<body>
<h5>Thymeleaf is login</h5>
<hr />
<form action="#" th:action="@{/login}" th:object="${loginBean}" method="post">
<p>username: <input type="text" th:field="*{username}" th:placeholder="username" /></p>
<p>age: <input type="text" th:field="*{age}" th:placeholder="age" /></p>
<p><input type="submit" value="submit" /><input type="reset" value="reset" /></p>
</form>
</body>
</html>

result.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>result</title>
</head>
<body>
<h5>Thymeleaf submit an result</h5>
<hr/>
<p th:text="'username: ' + ${loginBean.username}" />
<p th:text="'age: ' + ${loginBean.age}" />
<a href="/toLogin" th:text="@{toLogin}"></a>
</body>
</html>

LoginController.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.example.demo;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.model.LoginBean;

@Controller
public class LoginController {
@RequestMapping("toLogin")
public String toLogin(Model model) {
model.addAttribute("loginBean",new LoginBean());
return "login";
}

@RequestMapping("login")
public String greetingSubmit(@ModelAttribute LoginBean loginBean) {
// LoginBean username&age
System.out.println("Test one data:" + loginBean.getUsername());
System.out.println("Test two data:" + loginBean.getAge());
return "result";
}
}

LoginBean.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.model;

public class LoginBean {
String username;
int age;

// username
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}

// age
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

国际化(i18n)

国际化是一个大型网站中必备的一个服务之一,主要用于服务于不同种族、宗教信仰、国家和地区的人们沟通的一个非常重要的工具,通过Thymeleaf来实现站点国际化服务无非是一件非常不错的事情,甚至比原生的更加顺利。
至于标题中的国际化 i18n的意思为 国际化英文单词 internationalization,18为中间的字符数,是“国际化”的简称,通常在资讯领域,国际化是指让产品、出版物、软件,无需做大的改变就可适应不同的地区和语言需要,而对程序来说则是```不需要修改内部代码的情况下,根据不同语言及其地区显示相应的页面。

i18n properties

本书我们通过IDEA作为主要的集成开发环境进行开发,首先建立一个spring boot web + thymeleaf 的maven项目即通过spring Initializr工具构建的web项目,在src/main/resources/static/中新建目录为i18n用于存储i18n语言文件。

之后右键resources/static/i18n/目录选择 New->Resource Bundle,出现Create Resource Bundle窗口下,此时可通过项目语言(Project Locales)移动到(>) 语言添加(Locales to Add)

在然后双击在IDEA中双击 src/main/resources/static/i18n/Resource Bundle 'home'出现.properties配置页面,点击“+”号建立其各语言变量名。

home.properties

1
# 为默认语言文件,可为空,但文件不可不存在。

home_en_US.properties

1
2
home.i8n=en_US
home.title=Hello,world!

home_zh_CN.properties

1
2
home.i8n=zh_CN
home.title=你好世界!

application.yml

在application.yml中,主要存放于和application.properties同级目录下,用于配置我们的i18n文件所在目录和项目的编码信息,通过设置application.yml可设置 i18n文件目录及文件名(相对目录,不要使用绝对目录)

1
2
3
4
spring:
messages:
basename: static/i18n/home
encoding: UTF-8

application.properties

1
2
spring.thymeleaf.cache=false
spring.messages.basename=static/i18n/home

拦截器

LocaleConfigucation.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.example.demo;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;

import java.util.Locale;

@Configuration
public class LocaleConfigucation {
@Bean
public LocaleResolver localeResolver() {
// 默认语言
SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
sessionLocaleResolver.setDefaultLocale(Locale.US);
// 断点测试拦截器是否执行
System.out.println("yes");
return sessionLocaleResolver;
}

@Bean
public WebMvcConfigurer localeInterceptor() {
return new WebMvcConfigurer() {
@Override
public void addInterceptors(InterceptorRegistry interceptorRegistry) {
LocaleChangeInterceptor localeInterceptor = new LocaleChangeInterceptor();
localeInterceptor.setParamName("lang");
interceptorRegistry.addInterceptor(localeInterceptor);
}
};
}
}

首页文件

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<h5>Java Thymeleaf i18n <span th:text="#{home.i8n}"></span> </h5><br>
<a href="?lang=zh_CN">中文</a>/<a href="/?lang=en_US">English</a>
<hr/>
<h5 th:text="#{home.title}"></h5>
</body>
</html>
⬅️ Go back