赞
踩
其官网:https://www.thymeleaf.org/
看一下官网的解释:
Thymeleaf是⾯向Web和独⽴环境的现代服务器端Java模板引擎,能够处理HTML,XML,JavaScript,CSS甚⾄纯⽂本。
Thymeleaf旨在提供⼀个优雅的、⾼度可维护的创建模板的⽅式。 为了实现这⼀⽬标,Thymeleaf建⽴在⾃然模板的概念上,将其逻辑注⼊到模板⽂件中,不会影响模板设计原型。 这改善了设计的沟通,弥合了设计和开发团队之间的差距。
Thymeleaf从设计之初就遵循Web标准——特别是HTML5标准 ,如果需要,Thymeleaf允许您创建完全符合HTML5验证标准的模板。
看说明,可以得出好像说了什么,又好像什么都没有说。因为我也不知道说什么,不过 SpringBoot推荐的模板引擎就是Thymeleaf。
不过现在不结合SpringBoot使用这个模板。直接同前面所学的servlet进行整合来使用,这样虽然麻烦点,但是至少学习这个模板,不会对其它的基础有要求。
这个可以下载jar包,或者使用maven进行依赖环境配置:
搞这个需要的两个jar 包,既然是javaweb项目,所以必然有servlet这个jar包,还有一个thymeleaf的jar包:
servlet-api-***.jar
thymeleaf*.*.**.RELEASE
其中* 是数字表示的是版本号,所以不再多说什么。
如果使用maven配置:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>3.0.12.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
然后在IDE中创建一个Javaweb项目。
如果不知道如何在IDE中创建web项目:
既然启动Thymeleaf模板,那就是有要解析这个模板的类,看一下官网解释:
除了解释器,还有对 模版引擎的配置,这些就看了,一般会通过配置一个父类的servlet对加载的thymeleaf模板页面进行处理。然后自己的逻辑的servlet继承这个父类即可。
所以创建一个父类的servlet:
package com.xzd.servlet; import org.thymeleaf.TemplateEngine; import org.thymeleaf.context.WebContext; import org.thymeleaf.templatemode.TemplateMode; import org.thymeleaf.templateresolver.ServletContextTemplateResolver; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class ViewBaseServlet extends HttpServlet { private TemplateEngine templateEngine; @Override public void init() throws ServletException { // 1.获取ServletContext对象 ServletContext servletContext = this.getServletContext(); // 2.创建Thymeleaf解析器对象 ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext); // 3.给解析器对象设置参数 // ①HTML是默认模式,明确设置是为了代码更容易理解 templateResolver.setTemplateMode(TemplateMode.HTML); // ②设置前缀 String viewPrefix = servletContext.getInitParameter("view-prefix"); templateResolver.setPrefix(viewPrefix); // ③设置后缀 String viewSuffix = servletContext.getInitParameter("view-suffix"); templateResolver.setSuffix(viewSuffix); // ④设置缓存过期时间(毫秒) templateResolver.setCacheTTLMs(60000L); // ⑤设置是否缓存 templateResolver.setCacheable(true); // ⑥设置服务器端编码方式 templateResolver.setCharacterEncoding("utf-8"); // 4.创建模板引擎对象 templateEngine = new TemplateEngine(); // 5.给模板引擎对象设置模板解析器 templateEngine.setTemplateResolver(templateResolver); } protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException { // 1.设置响应体内容类型和字符集 resp.setContentType("text/html;charset=UTF-8"); // 2.创建WebContext对象 WebContext webContext = new WebContext(req, resp, getServletContext()); // 3.处理模板数据 templateEngine.process(templateName, webContext, resp.getWriter()); } }
同事还需与在web.xml中配置一些参数来满足:
// ②设置前缀
String viewPrefix = servletContext.getInitParameter("view-prefix");
templateResolver.setPrefix(viewPrefix);
// ③设置后缀
String viewSuffix = servletContext.getInitParameter("view-suffix");
templateResolver.setSuffix(viewSuffix);
具体配置如下:
<!-- 在servletContext中配置上下文参数 -->
<context-param>
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
先看一下整体结构
首先创建逻辑servlet类,其基础父类的servlet
//通过注释而配置servlet的 url 这样可以更加直观看web.xml中为thymeleaf做了什么 @WebServlet("/testservelt") public class testservlet extends ViewBaseServlet{ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req,resp); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession httpSession= req.getSession(); List list=new ArrayList(); list.add("战神"); list.add("艾尔登法环"); list.add("卧龙苍天陨落"); list.add("霍格沃茨:遗产"); httpSession.setAttribute("list",list); // //此处的视图名称是 index // //那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去 // //逻辑视图名称 : testservlet 为了一致所以 html和servlet名字一样,当然也可以不一样 // //物理视图名称 : view-prefix + 逻辑视图名称 + view-suffix // //所以真实的视图名称是: /WEB-INF/html/ testservlet .html super.processTemplate("testservlet",req,resp); } }
看一下web.xml中的配置
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" > <web-app> <display-name>Archetype Created Web Application</display-name> <!-- 在servletContext中配置上下文参数 --> <context-param> <param-name>view-prefix</param-name> <param-value>/WEB-INF/html/</param-value> </context-param> <context-param> <param-name>view-suffix</param-name> <param-value>.html</param-value> </context-param> </web-app>
然后写一个页面,不要关心thymeleaf的语法问题,主要是为了演示:
<!DOCTYPE html> <!--在页面上外部导入thymeleaf--> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Title</title> <style> table { border-collapse: collapse; } table, td, th { border: 1px solid black; } #gameid { margin: 12px auto; collapse: 1px; } td { text-align: center; width: 160px; } </style> </head> <body> <table id="gameid"> <tr> <th class="w20">游戏名</th> <th>操作</th> </tr> <tr th:if="${#lists.isEmpty(session.list)}"> <td colspan="4">对不起,库存为空!</td> </tr> <tr th:unless="${#lists.isEmpty(session.list)}" th:each="gamename : ${session.list}"> <td><a th:text="${gamename}" href="#">默认没有如果不是通过服务器启动,就显示这个文本</a></td> <td><a th:text="购买" href="#">默认没有如果不是通过服务器启动,就显示这个文本</a></td> </tr> </table> </body> </html>
为了方便,在index.jsp中写一个转发:
<html>
<body>
<h2>Hello World!</h2>
<%--转发到自己配置的url上--%>
<jsp:forward page="/testservelt"></jsp:forward>
</body>
</html>
然后访问:http://localhost:8080/thymeleaf_web/
然后看一下结果:
只要有例子了,后面就直接聊语法了,因为按照上面配置环境肯定没问题。
Thymeleaf 模板引擎支持多种表达式:
th:text 是用来修改标签文本值,比如:
<p th:text="th表达式text的值">P标签体原始值</p>
其实例子中也可以看出其在演示时候输出的是th:text的值。不过需要注意其使用不同,显示的值也是不同的。
修改value属性值,比如:
<input type="text" th:value="1111111" value="2222222">
也是如果是服务器启动页面显示是1111111,如果是普通浏览器打开那就是2222222。
意思是解析URL地址,还是演示:
<p th:text="@{/aaa/bbb/ccc}"></p>
但是IDE会提示报错,不过不会影响运行结果;
看一下结果就明白了:
会自动在前面添加项目名字,因为我创建的项目名字就是thymeleaf_web。
这个语法的好处是:实际开发过程中,项目在不同环境部署时,Web应用的名字有可能发生变化。所以上下文路径不能写死。而通过@{}动态获取上下文路径后,不会出错误。
对于web项目中的域不了解的话可以看一下,前面的文章:传送阵
直接演示常用的请求域,会话域,以及应用域。
首先咋servelt中创建数据
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("request_data", "request_data");
HttpSession httpsession= req.getSession();
httpsession.setAttribute("session_data","session_data");
ServletContext servletContext=getServletContext();
servletContext.setAttribute("application_data","application");
super.processTemplate("testservlet",req,resp);
}
}
然后再页面如此操作:
<p th:text="${request_data}"> </p>
<p th:text="${session.session_data}"> </p>
<p th:text="${application.application_data}"> </p>
可以看出后台传递的数据,再thymeleaf中呈现文本显示的适合其值格式如下:
th:text="${}"
得到url中的参数,这个还是来一个例子:
http://localhost:8080/thymeleaf_web/?username=张三&favourite=篮球&favourite=rap
然后看例子:
<p th:text="${param.username}"> </p>
<p th:text="${param.favourite}"> </p>
<p th:text="${param.favourite[0]}"> </p>
<p th:text="${param.favourite[1]}"> </p>
看结果就明白了。
jsp中有内置对象,对于thymeleaf 也不例外,这个直接列举了。
Thymeleaf 中常用的内置基本对象如下:
来一个例子:
<p th:text="${#request.getContextPath()}"></p>
<p th:text="${#request.getAttribute('请求域中数据值')}"></p>
除了能使用内置的基本对象外,变量表达式还可以使用一些内置的工具对象。
来一个例子:
<p th:text="${#dates.createNow()}"></p>
使用th:fragment来给这个片段命名:
先创建一个test.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div th:fragment="fragment_name" id="fragment_id">
<span>抽取的啊公共页面片段</span>
</div>
</body>
</html>
具体路径是:
在 Thymeleaf 中,我们可以使用以下 3 个属性,将公共页面片段引入到当前页面中。
使用上 3 个属性引入页面片段,都可以通过以下 2 种方式实现。
通常情况下,~{} 可以省略,其行内写法为 [[~{...}]] 或 [(~{...})],其中 [[~{...}]] 会转义特殊字符,[(~{...})] 则不会转义特殊字符。
现在演示一下:
<p> 这个是调用的页面啊</p>
<!--th:insert 片段名引入-->
<div th:insert="/utils/test::fragment_name"></div>
<!--th:insert id 选择器引入-->
<div th:insert="/utils/test::#fragment_id"></div>
这个需要借助一下serlvet才行,所在servert中配置:
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("htmllabel", "<span>测试</span>");
super.processTemplate("testservlet",req,resp);
}
}
然后再html中如此写:
<p>有转义效果:[[${htmllabel}]]</p>
<p>无转义效果:[(${htmllabel})]</p>
先看结果:
可以看出如果传递的数据带有html标签要求可以在页面。
[[${ 内容 }]]: 显示完整的数据,哪怕是标签也会当作文本显示
[(${ 内容 })] 会让传递数据中的html标签其效果
既然是模板,那肯定也会又逻辑判断以及迭代的语句,所以下面简单的聊一下。
让标记了th:if、th:unless的标签根据条件决定是否显示。
其实这个两个例子前面例子演示了,还是直接黏贴过来:
<tr th:if="${#lists.isEmpty(session.list)}">
<td colspan="4">对不起,库存为空!</td>
</tr>
<tr th:unless="${#lists.isEmpty(session.list)}" th:each="gamename : ${session.list}">
简单理解可以将th:if和th:unless 理解为 java中的 if ------if not-----
其中的th: if还可以搭配not关键字使用,比如上面th:unless可以如下写:
<tr th:unless="${#lists.isEmpty(session.list)}"></tr>
替代为:
<tr th:if="${not #lists.isEmpty(session.list)}">></tr>
有if的必然有这个关键字。
th:switch 与 Java 的 switch case语句类似通常与 th:case 配合使用,根据不同的条件展示不同的内容
还是直接演示:
<div th:switch="${session.game.id}">
<p th:case=" 1">艾尔登法环</p>
<p th:case=" 2">战神</p>
</div>
th:each 遍历,支持 Iterable、Map、数组等。
这个其实在演示的例子中用了:
<tr th:unless="${#lists.isEmpty(session.list)}" th:each="gamename : ${session.list}">
<td><a th:text="${gamename}" href="#">默认没有如果不是通过服务器启动,就显示这个文本</a></td>
<td><a th:text="购买" href="#">默认没有如果不是通过服务器启动,就显示这个文本</a></td>
当然thymeleaf的语法还有很多,现在不过多阐述了,可以具体使用的时候可以聊,同时还有一点那就是如何整合springmpv,springboot等,这些再用的时候演示如何配置,这里就不再多说了。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。