本篇学习SpringBoot如何整合视图层技术,其实这就是学习如何使用SpringBoot并结合视图层可以轻松搭建一个完整的Web应用,这里主要学习Thymeleaf
(读作[taɪm lif],百里香)和FreeMarker
。尽管在目前企业级的应用开发中,前后端分离是趋势,但是视图层技术还是占用一席之地。SpringBoot对视图层技术也提供了很好的支持,官方推荐使用的模板引擎是Thymeleaf,但是FreeMaker也支持,当然你可以像SSM中使用JSP等,但是非常不推荐使用。因此这里对于Thymeleaf
和FreeMarker
的介绍不会太深。
整合Thymeleaf
Thymeleaf
是新一代的Java模板引擎,类似于Velocity、FreeMaker等传统的Java模板引擎。但是Thymeleaf
与它们的不同之处在于Thymeleaf
支持HTML原型。如果你之前使用过JSP的话,你会发现不运行Java后端容器Tomcat,你是无法直接查看jsp网页的。但是Thymeleaf
支持HTML原型,既可以让前端人员在浏览器中直接打开查看样式,也可以让后端人员结合数据来查看显示效果。更重要的是SpringBoot提供了Thymeleaf
的自动化配置解决方案,因此在SpringBoot中使用Thymeleaf
是非常方便的,接下来就介绍如何整合Thymeleaf
。
创建工程和添加依赖
使用spring Initializr
构建工具构建一个SpringBoot的Web应用,名称为thymeleafspringboot,然后添加spring-boot-starter-web
和spring-boot-starter-thymeleaf
依赖:
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<!--添加Thymeleaf依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
|
配置 Thymeleaf
SpringBoot为Thymeleaf
提供了自动化配置类ThymeleafAutoConfiguration
,相关的配置属性在ThymeleafProperties
类中,ThymeleafProperties
的部分源码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| @ConfigurationProperties( prefix = "spring.thymeleaf" ) public class ThymeleafProperties { private static final Charset DEFAULT_ENCODING; public static final String DEFAULT_PREFIX = "classpath:/templates/"; public static final String DEFAULT_SUFFIX = ".html"; private boolean checkTemplate = true; private boolean checkTemplateLocation = true; private String prefix = "classpath:/templates/"; private String suffix = ".html"; private String mode = "HTML"; private Charset encoding; private boolean cache; private Integer templateResolverOrder; private String[] viewNames; private String[] excludedViewNames; private boolean enableSpringElCompiler; private boolean renderHiddenMarkersBeforeCheckboxes; private boolean enabled; private final ThymeleafProperties.Servlet servlet; private final ThymeleafProperties.Reactive reactive; ...... }
|
可以看到这个配置类使用了@ConfigurationProperties
注解说明它就是一个属性配置类,可以读取到aplication.properties
文件中的配置信息。还可以看到它默认的模板位置在classpath:/templates/
里面,默认的模板后缀为.html
。使用IDEA创建SpringBoot项目它会自动在resources目录下新建templates目录。
前面这个类可以读取到aplication.properties
文件中的配置信息,那么你就可以对默认的Thymeleaf配置参数进行自定义的修改,例如下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| # 是否开启缓存,开发时可设置为false,默认为true spring.thymeleaf.cache=true # 检查模板是否存在,默认为true spring.thymeleaf.check-template=true # 检查模板位置是否存在,默认为true spring.thymeleaf.check-template-location=true # 模板文件编码 spring.thymeleaf.encoding=UTF-8 # 模板文件位置 spring.thymeleaf.prefix=classpath:/templates/ # Content-Type配置 spring.thymeleaf.servlet.content-type=text/html # 模板文件后缀 spring.thymeleaf.suffix=.html
|
配置控制器
在com.envy.thymeleafspringboot
包下新建一个pojo包,接着在里面新建一个Book类,里面的代码为:
1 2 3 4 5 6 7 8 9
| package com.envy.thymeleafspringboot.pojo;
public class Book { private Integer id; private String name; private Integer price; //getter和setter方法,包含三个参数的构造方法 }
|
接下来继续在com.envy.thymeleafspringboot
包下新建一个controller包,接着在里面新建一个BookController类,请注意这里由于返回的是Web信息而不是字符串,因此需要返回一个ModelAndView对象,所以不能使用@RestController
注解,而是使用@Controller
注解。ModelAndView是模型数据和逻辑视图对象,它装载了模型的数据和逻辑视图,你可以通过modelAndView.addObject("key",ojbect);
方式来添加模型数据,然后使用modelAndView.setViewName("视图名称");
方式来设置逻辑视图。BookController类里面的代码为:
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
| package com.envy.thymeleafspringboot.controller;
import com.envy.thymeleafspringboot.pojo.Book; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays; import java.util.List;
@Controller public class BookController {
@GetMapping(value = "/books") public ModelAndView books(){ List<Book> books = Arrays.asList( new Book(1, "三国演义", 168), new Book(2, "红楼梦", 188), new Book(2, "西游记", 128), new Book(2, "水浒传", 108) ); //实例化模型数据和逻辑视图对象 ModelAndView modelAndView = new ModelAndView(); //添加模型数据 modelAndView.addObject("books",books); //设置逻辑视图 modelAndView.setViewName("books"); return modelAndView; } }
|
创建视图
在resources目录下的templates文件夹中新建books.html(请注意这里的books就是你在modelAndView.setViewName("books")
中设置的逻辑视图名称,这个需要保持一致),里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>图书列表</title> </head> <body> <h2>图书列表</h2> <table border="1px"> <tr> <td>图书编号</td> <td>图书名称</td> <td>图书价格</td> </tr> <tr th:each="book:${books}"> <td th:text="${book.id}"></td> <td th:text="${book.name}"></td> <td th:text="${book.price}"></td> </tr> </table> </body> </html>
|
请注意首先你需要在第2行导入Thymeleaf的名称空间,其次使用Thymeleaf中的th:each
来对集合对象进行遍历,并通过th:text
来展示数据。
运行项目
启动项目,在浏览器地址栏中输入http://localhost:8080/books
即可看到运行结果,如下图所示:
发现没有除了后面html中使用的是thymeleaf模板引擎,其他的其实就是SpringMVC的内容。请注意这里只是介绍SpringBoot如何整合Thymeleaf
,而不是Thymeleaf
的基础使用,关于Thymeleaf
的更多资料可以点击 这里,后续也会出一些关于Thymeleaf
的文章。
整合FreeMarker
FreeMarker
是一个非常古老的Java模板引擎。可以用在Web环境或者非Web环境中。与Thymeleaf
不同的是FreeMarker
需要经过解析才能够在浏览器中展示出来。FreeMarker
不仅可以用来配置HTML页面模板,也可以作为电子邮箱模板、配置文件模板以及源码模板等。正是由于它可以适应不同的应用场景,因此它虽然古老但是依旧还是有人愿意使用它。SpringBoot对FreeMarker
整合也提供了很好的支持,接下来就介绍如何整合FreeMarker
。
创建工程和添加依赖
使用spring Initializr
构建工具构建一个SpringBoot的Web应用,名称为freemarkerspringboot,然后添加spring-boot-starter-web
和spring-boot-starter-freemarker
依赖:
1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<!--添加FreeMarker依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
|
配置 FreeMarker
SpringBoot为FreeMarker
也提供了自动化配置类FreeMarkerAutoConfiguration
,相关的配置属性在FreeMarkerProperties
类中,FreeMarkerProperties
的部分源码如下:
1 2 3 4 5 6 7 8 9 10 11 12
| @ConfigurationProperties( prefix = "spring.freemarker" ) public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties { public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/"; public static final String DEFAULT_PREFIX = ""; public static final String DEFAULT_SUFFIX = ".ftlh"; private Map<String, String> settings = new HashMap(); private String[] templateLoaderPath = new String[]{"classpath:/templates/"}; private boolean preferFileSystemAccess = true; ...... }
|
可以看到这个配置类使用了@ConfigurationProperties
注解说明它就是一个属性配置类,可以读取到aplication.properties
文件中的配置信息。还可以看到它默认的模板位置在classpath:/templates/
里面,默认的模板后缀为.ftlh
。使用IDEA创建SpringBoot项目它会自动在resources目录下新建templates目录。
前面这个类可以读取到aplication.properties
文件中的配置信息,那么你就可以对默认的FreeMarker
配置参数进行自定义的修改,例如下面的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| # HttpServletRequest的属性是否可以覆盖Controller中的model的同名项 spring.freemarker.allow-request-override=false # HttpSession的属性是否可以覆盖Controller中的model的同名项 spring.freemarker.allow-session-override=false # 是否开启缓存,开发时可设置为false,默认为true spring.freemarker.cache=false # 检查模板位置是否存在,默认为true spring.freemarker.check-template-location=true # 模板文件编码 spring.freemarker.charset=UTF-8 # 模板文件位置 spring.freemarker.prefix=classpath:/templates/ # Content-Type配置 spring.freemarker.content-type=text/html # 模板文件后缀 spring.freemarker.suffix=.ftlh # 是否将HttpServletRequest中的属性添加到Model中 spring.freemarker.expose-request-attributes=false # 是否将HttpSession中的属性添加到Model中 spring.freemarker.expose-session-attributes=false
|
配置控制器
在com.envy.freemarkerspringboot
包下新建一个pojo包,接着在里面新建一个Book类,里面的代码为:
1 2 3 4 5 6 7 8 9
| package com.envy.freemarkerspringboot.pojo;
public class Book { private Integer id; private String name; private Integer price; //getter和setter方法,包含三个参数的构造方法 }
|
接下来继续在com.envy.freemarkerspringboot
包下新建一个controller包,接着在里面新建一个BookController类,请注意这里由于返回的是Web信息而不是字符串,因此需要返回一个ModelAndView对象,所以不能使用@RestController
注解,而是使用@Controller
注解。ModelAndView是模型数据和逻辑视图对象,它装载了模型的数据和逻辑视图,你可以通过modelAndView.addObject("key",ojbect);
方式来添加模型数据,然后使用modelAndView.setViewName("视图名称");
方式来设置逻辑视图。BookController类里面的代码为:
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
| package com.envy.freemarkerspringboot.controller;
import com.envy.freemarkerspringboot.pojo.Book; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.servlet.ModelAndView;
import java.util.Arrays; import java.util.List;
@Controller public class BookController {
@GetMapping(value = "/books") public ModelAndView books(){ List<Book> books = Arrays.asList( new Book(1, "三国演义", 168), new Book(2, "红楼梦", 188), new Book(2, "西游记", 128), new Book(2, "水浒传", 108) ); //实例化模型数据和逻辑视图对象 ModelAndView modelAndView = new ModelAndView(); //添加模型数据 modelAndView.addObject("books",books); //设置逻辑视图 modelAndView.setViewName("books"); return modelAndView; } }
|
创建视图
在resources目录下的templates文件夹中新建books.ftlh(请注意这里的books就是你在modelAndView.setViewName("books")
中设置的逻辑视图名称,这个需要保持一致),里面的代码为:
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
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>图书列表</title> </head> <body> <h2>图书列表</h2> <table border="1px"> <tr> <td>图书编号</td> <td>图书名称</td> <td>图书价格</td> </tr> <#if books ??&&(books?size>0)> <#list books as book> <tr> <td>${book.id}</td> <td>${book.name}</td> <td>${book.price}</td> </tr> </#list> </#if> </table> </body> </html>
|
请注意首先你需要判断model中的books不为空且books中有数据,然后才能进行遍历。后续通过遍历books集合,将集合中的数据通过表格展示出来。
运行项目
启动项目,在浏览器地址栏中输入http://localhost:8080/books
即可看到运行结果,如下图所示:
发现没有这个freemarker的用法与前面的thymeleaf非常相似,唯一不同的就是待渲染的模板的格式,前者为ftlh,而后者为html,还有就是对于数据的遍历输出方式不同。
请注意这里只是介绍SpringBoot如何整合FreeMarker
,而不是FreeMarker
的基础使用,关于FreeMarker
的更多资料可以点击 这里,后续也会出一些关于FreeMarker
的文章。
视图层整合小结
本篇学习了SpringBoot整合视图层技术,举了如何整合Thymeleaf
和FreeMarker
这两个例子。通过上面的学习你会发现整合Thymeleaf
和FreeMarker
的步骤几乎一致。如果开发人员使用的是目前最流行的前后端分离技术的话,那么在开发过程中不需要整合视图层技术,后端直接提供接口即可,目前大部分都是这样操作。