随着互联网技术的发展,页面静态化的需求越来越明显,传统的jsp动态页面逐渐的被html静态页面+ajax异步请求所替代,模板技术解决了静态页面的数据更新问题。这篇博客主要是结合spring boot 来介绍一下 thymeleaf模板技术。
thymelaaf的特点:
a.html格式,
模板直接交给浏览器渲染。
b.实现真正意义上的前后端分离,
在标签上引用了thymeleaf表达式后,当页面被浏览器解析后,标签内原有的内容将被表达式的值替换,前端人员只需要将页面演示内容填写好,后台人员你需要要编写正确的表达式返回正确的值,页面就能达到想要的效果。
c.页面即原型,所见即所得
在Web开发过程中一个绕不开的话题就是前端工程师与后端工程师的协作,在传统Java Web开发过程中,前端工程师和后端工程师一样,也需要安装一套完整的开发环境,然后各类Java IDE中修改模板、静态资源文件,启动/重启/重新加载应用服务器,刷新页面查看最终效果。
但实际上前端工程师的职责更多应该关注于页面本身而非后端,使用JSP,Velocity等传统的Java模板引擎很难做到这一点,因为它们必须在应用服务器中渲染完成后才能在浏览器中看到结果,而Thymeleaf从根本上颠覆了这一过程,通过属性进行模板渲染不会引入任何新的浏览器不能识别的标签,例如JSP中的
,不会在Tag内部写表达式。整个页面直接作为HTML文件用浏览器打开,几乎就可以看到最终的效果,这大大解放了前端工程师的生产力,它们的最终交付物就是纯的HTML/CSS/JavaScript文件。
1.依赖
spring boot 余thymeleaf整合非常的方便,只需要在pom中添加一个依赖即可:
org.springframework.boot
spring-boot-starter-thymeleaf
spring boot 默认会将templates目录映射为模板目录,因此你只需要讲你的模板放在templates目录下即可。
2.配置
添加了上述依赖之后,spring boot实际上为我们初始化了很多基本配置,我们只需要简单的配置一下页面类型即可,这些配置都简单易懂:
#thymeleaf start
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.content-type=text/html
spring.thymeleaf.cache=false #关闭页面缓存,这样才能实时的看到页面更改
#thymeleaf end
然后你就可以开始编写你的页面模板了,但是需要注意,为了让thymeleaf识别一个模板,你必须使用下面的html头标签:
...
这样thymeleaf才能真缺德解析!
下面就可以开始编写模板了!
3.语法
thymeleaf表达式风格和jsp的EL表达式,Struts的OGNL表达式风格非常类似,所以如果你熟悉上面的表达式的话,thymeleaf的表达式对你来说也和简单,不同的是,thymeleaf的表达值写在html标签的开始标签内,而不像EL表达式那样,可以充斥在页面的任何位置!
3.1 引入普通文本,数字 th:text
尽管使用模板动态的为页面添加普通文本并没有什么意义,但是还是值得一提,铜鼓他,我们将引入thymeleaf中一个常用的标签th:text="文本内容";
这个标签的作用就是将文本内容填充到表达式作用的标签内:例如在模板中这样写
hello world!
显示到页面的效果为:
3.2引入html代码
通th:text的方式,我们只能想页面引入纯文本,即便是你提供的是带有html格式的代码,thymeleaf也会将他解析为普通的文本,不过,我们可以通过th:utext标签来为页面引入html,这样thymeleaf就会将文本内容解析为html代码并交给浏览器渲染,例如:
效果:
不过需要注意的是,<,>这两个标签符号由于会和已有的html中标签产生冲突,所以需要用html预定义符号<,>代替。
3.3 变量
在thymeleaf中,可以使用${变量名}来向页面中引入一个变量:
测试文本!
controller代码:
@RequestMapping("/hello")
public String hello(Model model) {
System.out.println("一个访问...");
model.addAttribute("name", "thymeleaf");
return "hello";
}
当我们访问action时,页面效果为:
你会发现,我们在标签中填写的内容不见了,这是应为thymeleaf在解析模板时,会将在pageContext中去这些变量,并直接替换掉页面标签中原有的内容!
而且,和我们在java中一样,我们可以使用“+”将字符串与变量拼接起来!
3.4 url
在thymeleaf中如果你需要引入一个url,你可以使用th:href = @{url} 或者 th:src=@{url}等等标签,看样子就很明白,基本上就是将html标签的属性名前面加上th:,例如:
如果假设:
网站的context路径为http:localhost:9020/start/,当前页面的地址为:http:localhost:9020/start/test/hello.action
你也可以使用相对路径:th:href=@{user/login.action}
例如:
转到登录页面
或者
转到登录页面
上面两种心事的路径被解析后的结果都为:http://localhost:9020/start
/test/
user/login.action
或者你也可使用基于context的绝对路径:th:href=@{/user/login.action},
这个时候解析的结果则为:http://localhost:9020/start/user/login.action
怎么样,看出区别来了吗?
当然,不仅仅是超链接,其他的html标签的属性你一样也可以使用th:属性名=${...}的形式为这些属性动态的设置值
3.5 Url参数拼接:
thymeleaf中支持一种简单的参数拼接到url上,即使用圆括号(参数名=参数值)的形式,其中参数名和参数值都可以使用变量,例如:
// 多个参数键值对用','隔开
用户信息
解析后的url为:
/start/user/login.action?id=111&name=bug4j
thymeleaf会自动加上相应的?与&,
3.6 消息表达式#{...}
消息表达式允许你再模板页面上读取消息源里面的静态内容,消息源可以是配置文件,数据库等,消息配置文件实际就是一个properties文件,文件内容为key=value形式的键值对。
如果你使用spring boot的默认配置,那么配置文件的名称为messages.properties,他必须放在resource根目录下,这样thymeleaf才能找到。
消息表达式常用于加载静态文本内容,之所以吧静态内容提取为消息,是为了能方便的集中管理页面上某些可能会变动的内容。
例子:
配置文件:
页面内容:
你好,这是一条消息
访问效果:
另外,thymeleaf还支持在文件名上指定语言的消息配置文件,例如,要想某个配置文件只对中文有效,可以将配置文件的名称命名为:messages_zh_CN.properties,那么,当你的操作系统的的语言为简体中文时,你访问页面是页面内的消息将从这个带有语言表示的消息源中读取。
3.7 对象选择表达式:
和变量表达式一样,对象选择表达式也可以从一个对象中获取某个特定的值使用,而且他的语法与变量表达式完全一致,不同的是,对象选择表达式必须从父标签中声明的对象中获取内容,而不是从任意对象中获取。
因此,要想使用对象选择表达式,你必须通过th:object在要使用的元素标签的父标签上获取到内容源对象:格式为:th:object ect="${...}".例如:
id
name
sex
页面效果为:
4.运算符
thymeleaf中支持java中的各类运算符如+,-,*,/,%等,也支持各类逻辑运算符,如>,<,>=,<=,==,!=等,甚至java中的三目运算符?都可以使用,不过需要注意的是,<,>这两个运算符由于会和html中标签产生冲突,所以需要用html预定义符号<,>代替。
例如:
3等于4吗?答案是:答案
50大于30吗?答案是:答案
页面结果为:
5.条件判断if/unless:
条件判断if/unlesse可以根据某个调价是否成立来控制标签内容是否显示,
if:当if条件成立时,内容显示,例如:
用户的id大为111,于1,所以能显示这些
而页面显示的结果为:
而unless则恰好和if相反,当条件满足是不显示:
当“用户名称为空”这个条件不成立就显示,
用户名为:用户名
页面解过为:
6.循环 th:each:
循环表达式和其他表达式语言很类似,同样是用“:”将单个变量与即可变量组合,然后就可以在标签范围内使用了。
7.分支条件判断表达式:th:switch
thymeleaf中还允许我们使用java风格的switch语句,你可在html父元素上使用th:switch=来指定要判断的变量,在子标签上用case=变量来声明当前标签内容对应的选项值,例如下面的例子:
当然,你可以用 * 表示没有选项匹配是的默认值,类似于java中的default.
8.Utilities工具集
8.1 基本内置对象:
基本内置对象类似于jsp的内置对象,基本上就是将域对象转换了个形式,基本内置对象一共有如下几个:
- #ctx:上下文对象。
- #vars: 上下文变量。
- #locale:上下文语言环境。
- #request:(只在Web上下文中)HttpServletRequest对象。
- #response:(只在Web上下文中)HttpServletResponse对象。
- #session:(只在Web上下文中)HttpSession对象。
- #servletContext:(只在Web上下文中)ServletContext对象。
例如我们可以这么用:
实际上,#locale等同于JDK中的java.util.Locale类,我们使用#locale可以直接调用这个类的public属性以及方法!而且,如果你的表达式是有错误,后台异常信息里面显示的是java.util.locale的异常。
8.2 表达式工具对象
除了这些基本的对象之外,Thymeleaf还会为我们提供一套实用对象,帮助我们在表达式中执行常见任务。
- #execInfo:关于正在处理的模板的信息。
- #messages:在变量表达式中获得外部化消息的方法,与使用#{...}语法获得的方式相同。
- #uris:用于转义URL / URI部分的方法
- #conversions:执行配置的转换服务的方法(如果有的话)。
- #dates:java.util.Date对象的方法:格式化,组件提取等
- #calendars:类似于#dates,但是对于java.util.Calendar物体。
- #numbers:格式化数字对象的方法。
- #strings:String对象的方法:contains,startsWith,prepending / appending等
- #objects:一般对象的方法。
- #bools:布尔评估的方法。
- #arrays:数组的方法。
- #lists:列表的方法。
- #sets:套的方法。
- #maps:map集合的方法。
- #aggregates:在数组或集合上创建聚合的方法。
- #ids:处理可能重复的id属性的方法(例如,作为迭代的结果)。
例如我们可以利用
#calendars对象对后台传来的日期对象格式化:
// controller代码
Date today = new Date();
model.addAttribute("today", today);
模板代码:
更多关于thymeleaf的用法请参见: thymeleaf官方文档