查看原文
其他

Spring Boot 整合 Freemarker,50 多行配置是怎么省略掉的?

江南一点雨 江南一点雨 2020-10-08

Spring Boot2 系列教程接近完工,最近进入修修补补阶段。Freemarker 整合貌似还没和大家聊过,因此今天把这个补充上。

已经完工的 Spring Boot2 教程,大家可以参考这里:

  1. 干货|最新版 Spring Boot2.1.5 教程+案例合集

Freemarker 简介

这是一个相当老牌的开源的免费的模版引擎。通过 Freemarker 模版,我们可以将数据渲染成 HTML 网页、电子邮件、配置文件以及源代码等。Freemarker 不是面向最终用户的,而是一个 Java 类库,我们可以将之作为一个普通的组件嵌入到我们的产品中。

来看一张来自 Freemarker 官网的图片:

可以看到,Freemarker 可以将模版和数据渲染成 HTML 。

Freemarker 模版后缀为 .ftl(FreeMarker Template Language)。FTL 是一种简单的、专用的语言,它不是像 Java 那样成熟的编程语言。在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据。

好了,这是一个简单的介绍,接下来我们来看看 Freemarker 和 Spring Boot 的一个整合操作。

实践

在 SSM 中整合 Freemarker ,所有的配置文件加起来,前前后后大约在 50 行左右,Spring Boot 中要几行配置呢?0 行!

1.创建工程

首先创建一个 Spring Boot 工程,引入 Freemarker 依赖,如下图:

  1. <dependency>

  2. <groupId>org.springframework.boot</groupId>

  3. <artifactId>spring-boot-starter-freemarker</artifactId>

  4. </dependency>

  5. <dependency>

  6. <groupId>org.springframework.boot</groupId>

  7. <artifactId>spring-boot-starter-web</artifactId>

  8. </dependency>

工程创建完成后,在 org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration 类中,可以看到关于 Freemarker 的自动化配置:

  1. @Configuration

  2. @ConditionalOnClass({ freemarker.template.Configuration.class, FreeMarkerConfigurationFactory.class })

  3. @EnableConfigurationProperties(FreeMarkerProperties.class)

  4. @Import({ FreeMarkerServletWebConfiguration.class, FreeMarkerReactiveWebConfiguration.class,

  5. FreeMarkerNonWebConfiguration.class })

  6. public class FreeMarkerAutoConfiguration {

  7. }

从这里可以看出,当 classpath 下存在 freemarker.template.Configuration 以及 FreeMarkerConfigurationFactory 时,配置才会生效,也就是说当我们引入了 Freemarker 之后,配置就会生效。但是这里的自动化配置只做了模板位置检查,其他配置则是在导入的 FreeMarkerServletWebConfiguration 配置中完成的。那么我们再来看看 FreeMarkerServletWebConfiguration 类,部分源码如下:

  1. @Configuration

  2. @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)

  3. @ConditionalOnClass({ Servlet.class, FreeMarkerConfigurer.class })

  4. @AutoConfigureAfter(WebMvcAutoConfiguration.class)

  5. class FreeMarkerServletWebConfiguration extends AbstractFreeMarkerConfiguration {

  6. protected FreeMarkerServletWebConfiguration(FreeMarkerProperties properties) {

  7. super(properties);

  8. }

  9. @Bean

  10. @ConditionalOnMissingBean(FreeMarkerConfig.class)

  11. public FreeMarkerConfigurer freeMarkerConfigurer() {

  12. FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();

  13. applyProperties(configurer);

  14. return configurer;

  15. }

  16. @Bean

  17. @ConditionalOnMissingBean(name = "freeMarkerViewResolver")

  18. @ConditionalOnProperty(name = "spring.freemarker.enabled", matchIfMissing = true)

  19. public FreeMarkerViewResolver freeMarkerViewResolver() {

  20. FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();

  21. getProperties().applyToMvcViewResolver(resolver);

  22. return resolver;

  23. }

  24. }

我们来简单看下这段源码:

  1. @ConditionalOnWebApplication 表示当前配置在 web 环境下才会生效。

  2. ConditionalOnClass 表示当前配置在存在 Servlet 和 FreeMarkerConfigurer 时才会生效。

  3. @AutoConfigureAfter 表示当前自动化配置在 WebMvcAutoConfiguration 之后完成。

  4. 代码中,主要提供了 FreeMarkerConfigurer 和 FreeMarkerViewResolver。

  5. FreeMarkerConfigurer 是 Freemarker 的一些基本配置,例如 templateLoaderPath、defaultEncoding 等

  6. FreeMarkerViewResolver 则是视图解析器的基本配置,包含了viewClass、suffix、allowRequestOverride、allowSessionOverride 等属性。

另外还有一点,在这个类的构造方法中,注入了 FreeMarkerProperties:

  1. @ConfigurationProperties(prefix = "spring.freemarker")

  2. public class FreeMarkerProperties extends AbstractTemplateViewResolverProperties {

  3. public static final String DEFAULT_TEMPLATE_LOADER_PATH = "classpath:/templates/";

  4. public static final String DEFAULT_PREFIX = "";

  5. public static final String DEFAULT_SUFFIX = ".ftl";

  6. /**

  7. * Well-known FreeMarker keys which are passed to FreeMarker's Configuration.

  8. */

  9. private Map<String, String> settings = new HashMap<>();

  10. }

FreeMarkerProperties 中则配置了 Freemarker 的基本信息,例如模板位置在 classpath:/templates/ ,再例如模板后缀为 .ftl,那么这些配置我们以后都可以在 application.properties 中进行修改。

如果我们在 SSM 的 XML 文件中自己配置 Freemarker ,也不过就是配置这些东西。现在,这些配置由  FreeMarkerServletWebConfiguration  帮我们完成了。

2.创建类

首先我们来创建一个 User 类,如下:

  1. public class User {

  2. private Long id;

  3. private String username;

  4. private String address;

  5. //省略 getter/setter

  6. }

再来创建 UserController

  1. @Controller

  2. public class UserController {

  3. @GetMapping("/index")

  4. public String index(Model model) {

  5. List<User> users = new ArrayList<>();

  6. for (int i = 0; i < 10; i++) {

  7. User user = new User();

  8. user.setId((long) i);

  9. user.setUsername("javaboy>>>>" + i);

  10. user.setAddress("www.javaboy.org>>>>" + i);

  11. users.add(user);

  12. }

  13. model.addAttribute("users", users);

  14. return "index";

  15. }

  16. }

最后在 freemarker 中渲染数据:

  1. <!DOCTYPE html>

  2. <html lang="en">

  3. <head>

  4. <meta charset="UTF-8">

  5. <title>Title</title>

  6. </head>

  7. <body>

  8. <table border="1">

  9. <tr>

  10. <td>用户编号</td>

  11. <td>用户名称</td>

  12. <td>用户地址</td>

  13. </tr>

  14. <#list users as user>

  15. <tr>

  16. <td>${user.id}</td>

  17. <td>${user.username}</td>

  18. <td>${user.address}</td>

  19. </tr>

  20. </#list>

  21. </table>

  22. </body>

  23. </html>

运行效果如下:

其他配置

如果我们要修改模版文件位置等,可以在 application.properties 中进行配置:

  1. spring.freemarker.allow-request-override=false

  2. spring.freemarker.allow-session-override=false

  3. spring.freemarker.cache=false

  4. spring.freemarker.charset=UTF-8

  5. spring.freemarker.check-template-location=true

  6. spring.freemarker.content-type=text/html

  7. spring.freemarker.expose-request-attributes=false

  8. spring.freemarker.expose-session-attributes=false

  9. spring.freemarker.suffix=.ftl

  10. spring.freemarker.template-loader-path=classpath:/templates/

配置文件按照顺序依次解释如下:

  1. HttpServletRequest的属性是否可以覆盖controller中model的同名项

  2. HttpSession的属性是否可以覆盖controller中model的同名项

  3. 是否开启缓存

  4. 模板文件编码

  5. 是否检查模板位置

  6. Content-Type的值

  7. 是否将HttpServletRequest中的属性添加到Model中

  8. 是否将HttpSession中的属性添加到Model中

  9. 模板文件后缀

  10. 模板文件位置

好了,整合完成之后,Freemarker 的更多用法,就和在 SSM 中使用 Freemarker 一样了,这里我就不再赘述。

结语

本文和大家简单聊一聊 Spring Boot 整合 Freemarker,算是对 Spring Boot2 教程的一个补充(后面还会有一些补充),有问题欢迎留言讨论。本项目案例,我已经上传到 GitHub 上,欢迎大家 star:https://github.com/lenve/javaboy-code-samples

@ResponseBody 总是乱码?这个问题得好好捋一捋!

数据库分库分表,分片配置轻松入门!

前后端分离时代,Java 程序员的变与不变!

分布式数据库中间件 MyCat 搞起来!

What?Tomcat 竟然也算中间件?

北冥有 Data,其名为鲲,鲲之大,一个 MySQL 放不下!

MySQL 只能做小项目?松哥要说几句公道话!

松哥整理了 15 道 Spring Boot 高频面试题,看完当面霸!

极简 Spring Boot 整合 Thymeleaf 页面模板


你点的每个在看,我都认真当成了喜欢

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存