springboot中thymeleaf和freemarker分析
首先引入jar包,thymeleaf和freemarker的jar包可以同时引入,使用起来并不冲突。如果不配置application.yml则使用默认配置
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <!-- 方便测试,加上热部署 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency>
加入热部署的jar包后还需要在idea中配置2个地方。如果不行请百度,我也是百度的。
在打开的页面上快捷键ctrl + shift + a 搜索命令:registry –> 勾选compiler.automake.allow.when.app.running,原先是在下面,勾选完后跑到了最上面。
贴上代码,准备测试。
<!DOCTYPE html> <html xmlns:th="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>init.ftl</title> </head> <body> Thymeleaf : <p th:text="${hello}"></p> <br /> freemarker : ${hello} </body> </html>
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import java.util.HashMap; @Controller @RequestMapping("tiny") public class TinyController { @RequestMapping("/") public String init(HashMap<String, Object> map){ map.put("hello", "欢迎进入HTML页面"); return "init"; } @RequestMapping("/1") public String init1(HashMap<String, Object> map){ map.put("hello", "欢迎进入HTML页面"); return "init.ftl"; } @RequestMapping("/2") public String init2(HashMap<String, Object> map){ map.put("hello", "欢迎进入HTML页面"); return "init.ftl.ftl"; } @RequestMapping("/3") public String init3(HashMap<String, Object> map){ map.put("hello", "欢迎进入HTML页面"); return "init.html"; } @RequestMapping("/4") public String init4(HashMap<String, Object> map){ map.put("hello", "欢迎进入HTML页面"); return "init.html.html"; } @RequestMapping("/5") public String init5(HashMap<String, Object> map){ map.put("hello", "欢迎进入HTML页面"); return "init1"; } }
使用的是默认配置,application.yml内容为空
实验0
return "init";
访问http://localhost:8080/tiny/,返回的是init.ftl,加载的是freemarker模板。
分析:
1、文件名相同的情况下freemarker的优先级大于Thymeleaf。
2、视图解析器会在返回值后面新增后缀。freemarker为.ftl、Thymeleaf为.html
3、先以freemarker的方式查找init.ftl后缀,找到则渲染,找不到则会以Thymeleaf的方式查找init.html后缀,还找不到则报错。
实验1
return "init.ftl";
访问http://localhost:8080/tiny/1,返回的是init.ftl.ftl,加载的是freemarker模板。
分析:视图解析器以freemarker方式解析,无论返回值是否是有后缀,解析器都会在后面加上后缀去查找。
实验2
return "init.ftl.ftl";
访问http://localhost:8080/tiny/2 报错:Error resolving template [init.ftl.ftl], template might not exist or might not be accessible by any of the configured Template Resolvers
分析:由实验1的分析可知,实际查找的模板为init.ftl.ftl.ftl
实验3
return "init.html";
访问http://localhost:8080/tiny/3,返回的是init.html,加载的是Thymeleaf模板。
分析:视图解析器以freemarker方式解析,如果返回值为全路径,则解析器会直接按照全路径寻找文件,由于是.html文件所以是以Thymeleaf模板渲染的。
为了验证是否真的是按照全路径寻找,我把init.html文件删了再次访问确实访问不到。
实验4
return "init.html.html";
访问http://localhost:8080/tiny/4,返回的是init.html.html,加载的是Thymeleaf模板。
分析:真的是按照全路径查找模板,更加确定实验3的分析。
实验5
return "init1";
访问http://localhost:8080/tiny/5,返回的是init1.html,加载的是Thymeleaf模板。
分析:由于没有init1.ftl模板,所以是按照Thymeleaf的方式渲染。
这时候,如果在application.yml文件中设置一下freemarker的后缀名为.html会怎么样,我们来实验一下。
spring:
freemarker:
suffix: .html
实验6
访问http://localhost:8080/tiny/,返回的是init.html,加载的是freemarker模板。
分析:这个没有什么疑问,只是把默认的ftl后缀改为.html
实验7
访问http://localhost:8080/tiny/1、http://localhost:8080/tiny/2就不说了,肯定报错。
实验8
访问http://localhost:8080/tiny/3,返回的是init.html.html,加载的是freemarker模板。
分析:这就没跑了解析器以freemarker方式解析果然把返回值"init.html"后面加上了.html后缀。再次确定了实验2的分析。
实验9
访问http://localhost:8080/tiny/4,返回的是init.html.html,加载的是Thymeleaf模板。
分析:通过上面的实验已经很清楚了,实验1可知freemarker优先级比Thymeleaf高
实验2和实验8可知解析器以freemarker的方式解析,无论返回值是否是全路径都会加上后缀,
实验3和实验4可知解析器以Thymeleaf的方式解析,如果没有后缀则会添加后缀,如果是全路径则不会添加后缀。
所有出现下面结果的流程应是这样的:
先是以freemarker的方式寻找init.html.html.html模板,找不到这个模板后,会用Thymeleaf的方式以全路径init.html.html查找模板,如果找不到就会报错。
实验10
访问http://localhost:8080/tiny/5,返回的是init1.html,加载的是freemarker模板。
分析:init1+后缀.html,找的可不就是init1.html。如实验6
总结:
1、freemarker的优先级大于Thymeleaf,文件名相同的情况下会以freemarker的方式渲染模板。
2、freemarker默认后缀.ftl,Thymeleaf默认后缀.html,更多配置可通过application文件配置
3、视图解析器以freemarker的方式解析,无论Controller返回值中是否有后缀,都会在最后添加后缀。
4、视图解析器以Thymeleaf的方式解析,如果Controller返回值没有后缀,则会在最后添加后缀,有则不加。